1
0
mirror of https://github.com/mattermost/focalboard.git synced 2025-11-06 09:19:31 +02:00

[GH-314] Persist and reapply users settings in mac app (#331)

* [GH-314] Persist and reapply users settings in mac app

Relates to: #314

* Inject settings blob at document start, push base64 conversion into TS, use proper quotes

* Remove whitespace

* Rename base64 to blob for consistency
This commit is contained in:
Johannes Marbach
2021-04-28 00:09:26 +02:00
committed by GitHub
parent 97b446f609
commit 3fb078d612
7 changed files with 132 additions and 14 deletions

View File

@@ -32,10 +32,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
@IBAction func openNewWindow(_ sender: Any?) {
let mainStoryBoard = NSStoryboard(name: "Main", bundle: nil)
let tabViewController = mainStoryBoard.instantiateController(withIdentifier: "ViewController") as? ViewController
let windowController = mainStoryBoard.instantiateController(withIdentifier: "WindowController") as! NSWindowController
windowController.showWindow(self)
windowController.contentViewController = tabViewController
}
private func showWhatsNewDialogIfNeeded() {

View File

@@ -7,7 +7,8 @@ import WebKit
class ViewController:
NSViewController,
WKUIDelegate,
WKNavigationDelegate {
WKNavigationDelegate,
WKScriptMessageHandler {
@IBOutlet var webView: WKWebView!
private var refreshWebViewOnLoad = true
@@ -19,14 +20,15 @@ class ViewController:
webView.navigationDelegate = self
webView.uiDelegate = self
webView.isHidden = true
webView.configuration.userContentController.add(self, name: "nativeApp")
clearWebViewCache()
// Load the home page if the server was started, otherwise wait until it has
let appDelegate = NSApplication.shared.delegate as! AppDelegate
if (appDelegate.isServerStarted) {
self.updateSessionToken()
self.loadHomepage()
updateSessionTokenAndUserSettings()
loadHomepage()
}
// Do any additional setup after loading the view.
@@ -38,6 +40,11 @@ class ViewController:
self.view.window?.makeFirstResponder(self.webView)
}
override func viewWillDisappear() {
super.viewWillDisappear()
persistUserSettings()
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
@@ -64,20 +71,55 @@ class ViewController:
@objc func onServerStarted() {
NSLog("onServerStarted")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.updateSessionToken()
self.updateSessionTokenAndUserSettings()
self.loadHomepage()
}
}
private func updateSessionToken() {
private func persistUserSettings() {
let semaphore = DispatchSemaphore(value: 0)
webView.evaluateJavaScript("Focalboard.exportUserSettingsBlob();") { result, error in
defer { semaphore.signal() }
guard let blob = result as? String else {
NSLog("Failed to export user settings: \(error?.localizedDescription ?? "?")")
return
}
UserDefaults.standard.set(blob, forKey: "localStorage")
NSLog("Persisted user settings: \(Data(base64Encoded: blob).flatMap { String(data: $0, encoding: .utf8) } ?? blob)")
}
// During shutdown the system grants us about 5 seconds to clean up and store user data
let timeout = DispatchTime.now() + .seconds(3)
var result: DispatchTimeoutResult?
// Busy wait because evaluateJavaScript can only be called from *and* signals on the main thread
while (result != .success && .now() < timeout) {
result = semaphore.wait(timeout: .now())
RunLoop.current.run(mode: .default, before: Date())
}
if result == .timedOut {
NSLog("Timed out trying to persist user settings")
}
}
private func updateSessionTokenAndUserSettings() {
let appDelegate = NSApplication.shared.delegate as! AppDelegate
let script = WKUserScript(
let sessionTokenScript = WKUserScript(
source: "localStorage.setItem('focalboardSessionId', '\(appDelegate.sessionToken)');",
injectionTime: .atDocumentStart,
forMainFrameOnly: true
)
let blob = UserDefaults.standard.string(forKey: "localStorage") ?? ""
let userSettingsScript = WKUserScript(
source: "const NativeApp = { settingsBlob: \"\(blob)\" };",
injectionTime: .atDocumentStart,
forMainFrameOnly: true
)
webView.configuration.userContentController.removeAllUserScripts()
webView.configuration.userContentController.addUserScript(script)
webView.configuration.userContentController.addUserScript(sessionTokenScript)
webView.configuration.userContentController.addUserScript(userSettingsScript)
}
private func loadHomepage() {
@@ -219,5 +261,13 @@ class ViewController:
@IBAction func navigateToHome(_ sender: NSObject) {
loadHomepage()
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard let body = message.body as? [String: String], let type = body["type"], let blob = body["settingsBlob"] else {
NSLog("Received unexpected script message \(message.body)")
return
}
NSLog("Received script message \(type): \(Data(base64Encoded: blob).flatMap { String(data: $0, encoding: .utf8) } ?? blob)")
}
}