mirror of
https://github.com/logseq/logseq.git
synced 2026-04-24 14:14:55 +00:00
enhance: iOS dynamic type
This commit is contained in:
@@ -12,6 +12,38 @@ import UIKit
|
||||
@objc(Utils)
|
||||
public class Utils: CAPPlugin {
|
||||
private var currentInterfaceStyle: UIUserInterfaceStyle = .unspecified
|
||||
private var contentSizeObserver: NSObjectProtocol?
|
||||
|
||||
public override func load() {
|
||||
super.load()
|
||||
|
||||
contentSizeObserver = NotificationCenter.default.addObserver(
|
||||
forName: UIContentSizeCategory.didChangeNotification,
|
||||
object: nil,
|
||||
queue: .main
|
||||
) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.notifyListeners("contentSizeCategoryChanged", data: self.contentSizePayload())
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let observer = contentSizeObserver {
|
||||
NotificationCenter.default.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
|
||||
private func contentSizePayload() -> [String: Any] {
|
||||
let category = UIApplication.shared.preferredContentSizeCategory
|
||||
let base: CGFloat = 17.0
|
||||
let scaled = UIFontMetrics(forTextStyle: .body).scaledValue(for: base)
|
||||
let scale = scaled / base
|
||||
|
||||
return [
|
||||
"category": category.rawValue,
|
||||
"scale": scale
|
||||
]
|
||||
}
|
||||
|
||||
@objc func isZoomed(_ call: CAPPluginCall) {
|
||||
|
||||
@@ -22,6 +54,10 @@ public class Utils: CAPPlugin {
|
||||
call.resolve(["isZoomed": isZoomed])
|
||||
}
|
||||
|
||||
@objc func getContentSize(_ call: CAPPluginCall) {
|
||||
call.resolve(contentSizePayload())
|
||||
}
|
||||
|
||||
@objc func getDocumentRoot(_ call: CAPPluginCall) {
|
||||
let doc = FileManager.default.urls(
|
||||
for: .documentDirectory,
|
||||
|
||||
@@ -58,10 +58,13 @@
|
||||
@apply inline;
|
||||
|
||||
.icon-emoji-wrap {
|
||||
@apply relative top-[2px] pl-[1px];
|
||||
position: relative;
|
||||
top: 0.08em;
|
||||
padding-left: 1px;
|
||||
|
||||
&.as-emoji {
|
||||
@apply top-0 pr-[1px];
|
||||
top: 0.02em;
|
||||
padding-right: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +72,11 @@
|
||||
@apply inline-flex items-center pr-0.5;
|
||||
}
|
||||
|
||||
.icon-emoji-wrap em-emoji,
|
||||
.icon-cp-container .ui__icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.block-title-wrap.as-heading {
|
||||
@apply inline text-[length:inherit];
|
||||
}
|
||||
@@ -208,7 +216,8 @@
|
||||
|
||||
&.bullet-closed {
|
||||
.ls-icon-color-wrap em-emoji {
|
||||
@apply relative -top-[1px];
|
||||
position: relative;
|
||||
top: -0.08em;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -747,23 +756,32 @@
|
||||
}
|
||||
|
||||
.bullet-container {
|
||||
display: flex;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
display: inline-flex;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
min-width: 1em;
|
||||
flex-shrink: 0;
|
||||
align-self: center;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
|
||||
.bullet-heading {
|
||||
background-color: var(--ls-block-bullet-color, #8fbc8f);
|
||||
}
|
||||
|
||||
&.as-order-list {
|
||||
@apply w-[22px] whitespace-nowrap justify-center pl-[3px];
|
||||
width: 1.4em;
|
||||
min-width: 1.4em;
|
||||
@apply whitespace-nowrap justify-center pl-[3px];
|
||||
}
|
||||
|
||||
.bullet {
|
||||
@apply rounded-full w-[6px] h-[6px] text-[15px] opacity-80;
|
||||
@apply rounded-full opacity-80;
|
||||
width: 0.4em;
|
||||
height: 0.4em;
|
||||
|
||||
> * {
|
||||
@apply cursor-pointer;
|
||||
@@ -792,6 +810,9 @@
|
||||
}
|
||||
|
||||
.bullet-link-wrap {
|
||||
@apply inline-flex items-center;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
color: var(--ls-primary-text-color);
|
||||
|
||||
.ui__icon {
|
||||
|
||||
@@ -36,6 +36,31 @@
|
||||
(set! native-selection-action-bar (registerPlugin "NativeSelectionActionBarPlugin"))
|
||||
(set! ios-utils (registerPlugin "Utils")))
|
||||
|
||||
(defonce ios-content-size-listener nil)
|
||||
|
||||
(defn- set-ios-font-scale!
|
||||
[scale]
|
||||
(let [^js style (.-style js/document.documentElement)
|
||||
scale (or scale 1)]
|
||||
(.setProperty style "--ls-mobile-font-scale" (str scale))))
|
||||
|
||||
(defn sync-ios-content-size!
|
||||
"Fetch the current iOS Dynamic Type scale and sync it to CSS variables.
|
||||
Also attaches a listener to keep it in sync when the user changes the setting."
|
||||
[]
|
||||
(when (native-ios?)
|
||||
(let [apply-scale! (fn [payload]
|
||||
(let [payload (js->clj payload :keywordize-keys true)]
|
||||
(set-ios-font-scale! (:scale payload))))]
|
||||
(p/let [payload (p/chain (.getContentSize ^js ios-utils)
|
||||
#(js->clj % :keywordize-keys true))]
|
||||
(set-ios-font-scale! (:scale payload)))
|
||||
(when (nil? ios-content-size-listener)
|
||||
(set! ios-content-size-listener
|
||||
(.addListener ^js ios-utils "contentSizeCategoryChanged"
|
||||
(fn [^js payload]
|
||||
(apply-scale! payload))))))))
|
||||
|
||||
(defn hide-splash []
|
||||
(.hide SplashScreen))
|
||||
|
||||
|
||||
@@ -39,13 +39,14 @@
|
||||
`f` receives the tab id string.
|
||||
Returns the Capacitor listener handle; call `(.remove handle)` to unsubscribe."
|
||||
[f]
|
||||
(.addListener
|
||||
liquid-tabs
|
||||
"tabSelected"
|
||||
(fn [data]
|
||||
(when (and (util/capacitor?) liquid-tabs)
|
||||
(.addListener
|
||||
liquid-tabs
|
||||
"tabSelected"
|
||||
(fn [data]
|
||||
;; data is like { id: string }
|
||||
(when-let [id (.-id data)]
|
||||
(f id)))))
|
||||
(when-let [id (.-id data)]
|
||||
(f id))))))
|
||||
|
||||
(defn add-search-listener!
|
||||
"Listen to native search query changes from the SwiftUI search tab.
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
(rum/defc journals
|
||||
[]
|
||||
(ui-component/classic-app-container-wrap
|
||||
[:div.pt-3
|
||||
[:div.pt-6
|
||||
(journal/all-journals)]))
|
||||
|
||||
(rum/defc home-inner < rum/static
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
}
|
||||
|
||||
:root {
|
||||
--ls-page-title-size: 26px;
|
||||
--ls-mobile-font-scale: 1;
|
||||
--ls-page-title-size: calc(24px * var(--ls-mobile-font-scale, 1));
|
||||
--safe-area-inset-top: 40px;
|
||||
--safe-area-inset-bottom: 16px;
|
||||
--ls-mobile-font-size: 16px;
|
||||
}
|
||||
|
||||
html.is-native-ios {
|
||||
@@ -14,6 +16,29 @@ html.is-native-ios {
|
||||
--safe-area-inset-bottom: 24px;
|
||||
}
|
||||
|
||||
html.is-native-ios,
|
||||
html.is-ios {
|
||||
font-size: calc(var(--ls-mobile-font-size) * var(--ls-mobile-font-scale, 1));
|
||||
}
|
||||
|
||||
html.is-native-ios body,
|
||||
html.is-native-ios textarea,
|
||||
html.is-native-ios input,
|
||||
html.is-native-ios select,
|
||||
html.is-native-ios .block-content,
|
||||
html.is-ios body,
|
||||
html.is-ios textarea,
|
||||
html.is-ios input,
|
||||
html.is-ios select,
|
||||
html.is-ios .block-content {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
html.is-native-ios .block-content,
|
||||
html.is-ios .block-content {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
html.has-mobile-keyboard {
|
||||
body {
|
||||
@apply overflow-hidden
|
||||
@@ -331,3 +356,8 @@ div[data-radix-menu-content] {
|
||||
position:fixed;
|
||||
top:-9999px;
|
||||
}
|
||||
|
||||
.bullet {
|
||||
width: 0.45em;
|
||||
height: 0.45em;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
(defn- ios-init!
|
||||
"Initialize iOS-specified event listeners"
|
||||
[]
|
||||
(mobile-util/check-ios-zoomed-display))
|
||||
(mobile-util/check-ios-zoomed-display)
|
||||
(mobile-util/sync-ios-content-size!))
|
||||
|
||||
(defn- android-init!
|
||||
"Initialize Android-specified event listeners"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
["/page/:name"
|
||||
{:name :page
|
||||
:view (fn [route-match]
|
||||
[:div.ls-mobile-page.mt-6
|
||||
[:div.ls-mobile-page.pt-10
|
||||
(page/page-cp (assoc route-match :mobile-page? true))])}]
|
||||
["/import"
|
||||
{:name :import
|
||||
|
||||
Reference in New Issue
Block a user