89 lines
2.8 KiB
Swift
89 lines
2.8 KiB
Swift
import Foundation
|
|
import Capacitor
|
|
|
|
/// Hosts a native left-edge drawer (the "sidebar") that floats above the
|
|
/// Capacitor web view. The drawer's *content* is a second, transparent
|
|
/// WKWebView that renders the existing `Sidebar.js` from data pushed in via
|
|
/// `setData`. Taps inside that content web view are forwarded back to the main
|
|
/// app as an `action` event, mirroring how the NativeInput plugin works.
|
|
@objc(NativeSidebarPlugin)
|
|
public class NativeSidebarPlugin: CAPPlugin {
|
|
|
|
private var drawer: SidebarDrawer?
|
|
|
|
// MARK: Helpers
|
|
|
|
private func hostView() -> UIView? {
|
|
// Pin the drawer as a sibling of the web view inside the same parent so
|
|
// it can float above the web content (same pattern as NativeInput).
|
|
return webView?.superview ?? webView
|
|
}
|
|
|
|
private func ensureDrawer() -> SidebarDrawer? {
|
|
if let drawer = drawer { return drawer }
|
|
guard let host = hostView() else { return nil }
|
|
let drawer = SidebarDrawer(hostView: host, mainWebView: webView, parentVC: bridge?.viewController)
|
|
drawer.onAction = { [weak self] data in
|
|
self?.notifyListeners("action", data: data)
|
|
}
|
|
drawer.onStateChange = { [weak self] open in
|
|
self?.notifyListeners("stateChange", data: ["open": open])
|
|
}
|
|
drawer.attach()
|
|
self.drawer = drawer
|
|
return drawer
|
|
}
|
|
|
|
// MARK: Plugin methods
|
|
|
|
@objc func setData(_ call: CAPPluginCall) {
|
|
// Forward the whole options object (minus Capacitor's callbackId) to the
|
|
// content web view as the sidebar payload.
|
|
var payload = (call.options as? [String: Any]) ?? [:]
|
|
payload.removeValue(forKey: "callbackId")
|
|
DispatchQueue.main.async {
|
|
guard let drawer = self.ensureDrawer() else { call.reject("No host view"); return }
|
|
drawer.setData(payload)
|
|
call.resolve()
|
|
}
|
|
}
|
|
|
|
@objc func setTheme(_ call: CAPPluginCall) {
|
|
let theme = call.getString("theme") ?? ""
|
|
DispatchQueue.main.async {
|
|
self.drawer?.setTheme(theme)
|
|
call.resolve()
|
|
}
|
|
}
|
|
|
|
@objc func open(_ call: CAPPluginCall) {
|
|
DispatchQueue.main.async {
|
|
self.ensureDrawer()?.open()
|
|
call.resolve()
|
|
}
|
|
}
|
|
|
|
@objc func close(_ call: CAPPluginCall) {
|
|
DispatchQueue.main.async {
|
|
self.drawer?.close()
|
|
call.resolve()
|
|
}
|
|
}
|
|
|
|
@objc func setEnabled(_ call: CAPPluginCall) {
|
|
let enabled = call.getBool("enabled") ?? true
|
|
DispatchQueue.main.async {
|
|
self.drawer?.setEnabled(enabled)
|
|
call.resolve()
|
|
}
|
|
}
|
|
|
|
@objc func dismiss(_ call: CAPPluginCall) {
|
|
DispatchQueue.main.async {
|
|
self.drawer?.removeFromHost()
|
|
self.drawer = nil
|
|
call.resolve()
|
|
}
|
|
}
|
|
}
|