mirror of
https://github.com/logseq/logseq.git
synced 2026-05-24 12:44:22 +00:00
126 lines
3.4 KiB
Swift
126 lines
3.4 KiB
Swift
//
|
|
// Utils.swift
|
|
// Logseq
|
|
//
|
|
// Created by leizhe on 2022/5/23.
|
|
//
|
|
|
|
import Foundation
|
|
import Capacitor
|
|
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) {
|
|
|
|
var isZoomed: Bool {
|
|
UIScreen.main.scale < UIScreen.main.nativeScale
|
|
}
|
|
|
|
call.resolve(["isZoomed": isZoomed])
|
|
}
|
|
|
|
@objc func getContentSize(_ call: CAPPluginCall) {
|
|
call.resolve(contentSizePayload())
|
|
}
|
|
|
|
@objc func getDocumentRoot(_ call: CAPPluginCall) {
|
|
let doc = FileManager.default.urls(
|
|
for: .documentDirectory,
|
|
in: .userDomainMask).first
|
|
|
|
if doc != nil {
|
|
call.resolve(["documentRoot": doc!.path])
|
|
} else {
|
|
call.resolve(["documentRoot": ""])
|
|
}
|
|
}
|
|
|
|
@objc func setInterfaceStyle(_ call: CAPPluginCall) {
|
|
let mode = call.getString("mode")?.lowercased() ?? "system"
|
|
let followSystem = call.getBool("system") ?? (mode == "system")
|
|
UserDefaults.standard.set(mode, forKey: "logseqTheme")
|
|
UserDefaults.standard.synchronize()
|
|
|
|
let style: UIUserInterfaceStyle
|
|
if followSystem {
|
|
style = .unspecified
|
|
} else {
|
|
style = (mode == "dark") ? .dark : .light
|
|
}
|
|
|
|
DispatchQueue.main.async {
|
|
self.applyInterfaceStyle(style)
|
|
call.resolve()
|
|
}
|
|
}
|
|
|
|
private func applyInterfaceStyle(_ style: UIUserInterfaceStyle) {
|
|
guard style != currentInterfaceStyle else { return }
|
|
currentInterfaceStyle = style
|
|
|
|
let app = UIApplication.shared
|
|
|
|
let applyToWindow: (UIWindow) -> Void = { window in
|
|
window.overrideUserInterfaceStyle = style
|
|
window.rootViewController?.overrideUserInterfaceStyle = style
|
|
}
|
|
|
|
// Propagate to all active windows (handles multi-scene).
|
|
let targetScenes = app.connectedScenes
|
|
.compactMap { $0 as? UIWindowScene }
|
|
.filter { $0.activationState == .foregroundActive || $0.activationState == .foregroundInactive }
|
|
|
|
let windows = targetScenes.flatMap { $0.windows }
|
|
if windows.isEmpty {
|
|
app.windows.forEach(applyToWindow)
|
|
} else {
|
|
windows.forEach(applyToWindow)
|
|
}
|
|
|
|
// Bridge VC + WKWebView
|
|
bridge?.viewController?.overrideUserInterfaceStyle = style
|
|
bridge?.webView?.overrideUserInterfaceStyle = style
|
|
|
|
// UINavigationController root (if available)
|
|
if let nav = (app.delegate as? AppDelegate)?.navController {
|
|
nav.overrideUserInterfaceStyle = style
|
|
nav.viewControllers.forEach { $0.overrideUserInterfaceStyle = style }
|
|
}
|
|
}
|
|
}
|