Selaa lähdekoodia

Add titlebar Add to Status Bar and Add to Desktop buttons

Place them left and right of the widget icon; wire to Premium, launcher
host matching, status bar ID persistence, and desktop .webloc save panel.
Refresh status bar button state on navigation and status bar ID changes.

Made-with: Cursor
huzaifahayat12 3 kuukautta sitten
vanhempi
sitoutus
db827bc417
1 muutettua tiedostoa jossa 127 lisäystä ja 0 poistoa
  1. 127 0
      google_apps/InAppBrowserWindow.swift

+ 127 - 0
google_apps/InAppBrowserWindow.swift

@@ -142,7 +142,9 @@ final class InAppBrowserWindowController: NSWindowController, NSWindowDelegate {
     private var reloadButton: TitlebarIconButton!
     private var pinButton: TitlebarIconButton!
     private var homeButton: TitlebarIconButton!
+    private var addToStatusBarButton: TitlebarIconButton!
     private var widgetButton: TitlebarIconButton!
+    private var addToDesktopButton: TitlebarIconButton!
     private var handButton: TitlebarIconButton!
     private var downloadButton: TitlebarIconButton!
     private var moreButton: TitlebarIconButton!
@@ -156,10 +158,18 @@ final class InAppBrowserWindowController: NSWindowController, NSWindowDelegate {
     private var isPinnedOnTop = false
     private var isGestureModeEnabled = true
 
+    private var statusBarShortcutObserver: NSObjectProtocol?
+
     private func setToggledStyle(_ button: TitlebarIconButton, isOn: Bool) {
         button.setToggleActive(isOn)
     }
 
+    deinit {
+        if let statusBarShortcutObserver {
+            NotificationCenter.default.removeObserver(statusBarShortcutObserver)
+        }
+    }
+
     init(initialURL: URL, windowTitle: String?) {
         self.initialURL = initialURL
 
@@ -240,6 +250,14 @@ final class InAppBrowserWindowController: NSWindowController, NSWindowDelegate {
             action: #selector(togglePinOnTop)
         )
 
+        // Add to menu bar (matches launcher tile behavior; requires Premium + known app host).
+        addToStatusBarButton = makeIconButton(
+            symbolName: "arrow.up.square",
+            accessibility: "Add to Status Bar",
+            action: #selector(addCurrentPageToStatusBar),
+            fallbackSymbolName: "square.and.arrow.up"
+        )
+
         // Home
         homeButton = makeIconButton(
             symbolName: "house",
@@ -258,6 +276,14 @@ final class InAppBrowserWindowController: NSWindowController, NSWindowDelegate {
         // Bundled PNG: 1x = layout-fluid-3, 2x = layout-fluid-4 @ 48px — slightly larger than 12pt symbols so the full glyph reads clearly.
         widgetButton.image = makeTitlebarSizedTemplateImage(named: "widget_custom_icon", pointSize: 14, layoutMarginFraction: 0)
 
+        // Add desktop shortcut (.webloc); matches launcher tile behavior (Premium).
+        addToDesktopButton = makeIconButton(
+            symbolName: "arrow.up.right.square",
+            accessibility: "Add to Desktop",
+            action: #selector(addCurrentPageToDesktop),
+            fallbackSymbolName: "square.and.arrow.up"
+        )
+
         // Center site identity (logo + app/site name).
         siteIconView = NSImageView()
         siteIconView.translatesAutoresizingMaskIntoConstraints = false
@@ -335,11 +361,21 @@ final class InAppBrowserWindowController: NSWindowController, NSWindowDelegate {
         reloadButton.target = self
         pinButton.target = self
         homeButton.target = self
+        addToStatusBarButton.target = self
         widgetButton.target = self
+        addToDesktopButton.target = self
         handButton.target = self
         downloadButton.target = self
         moreButton.target = self
 
+        statusBarShortcutObserver = NotificationCenter.default.addObserver(
+            forName: .statusBarShortcutIDsChanged,
+            object: nil,
+            queue: .main
+        ) { [weak self] _ in
+            self?.updateAddToStatusBarButtonAppearance()
+        }
+
         webView.uiDelegate = self
         webView.navigationDelegate = self
         webView.allowsBackForwardNavigationGestures = true
@@ -370,7 +406,9 @@ final class InAppBrowserWindowController: NSWindowController, NSWindowDelegate {
 
         let rightStack = NSStackView(views: [
             pinButton,
+            addToStatusBarButton,
             widgetButton,
+            addToDesktopButton,
             handButton,
             downloadButton,
             moreButton,
@@ -481,6 +519,94 @@ final class InAppBrowserWindowController: NSWindowController, NSWindowDelegate {
         )
     }
 
+    @objc private func addCurrentPageToStatusBar() {
+        guard PremiumStore.shared.isPremiumUnlocked else {
+            showAlert(
+                title: "Premium required",
+                message: "Update to Premium to add shortcuts to the menu bar."
+            )
+            return
+        }
+        guard let app = resolvedLauncherAppForCurrentPage() else {
+            showAlert(
+                title: "Can’t add to menu bar",
+                message: "This site isn’t in your launcher list. Open it from the home screen first, then use this button."
+            )
+            return
+        }
+        var ids = LauncherApp.statusBarShortcutIDSet()
+        guard ids.insert(app.id).inserted else {
+            showAlert(title: "Already added", message: "“\(app.name)” is already in the menu bar.")
+            return
+        }
+        LauncherApp.persistStatusBarShortcutIDs(ids)
+        showAlert(
+            title: "Added to Status Bar",
+            message: "“\(app.name)” now has its own icon in the menu bar. Click it to open, or right‑click to remove."
+        )
+    }
+
+    @objc private func addCurrentPageToDesktop() {
+        guard PremiumStore.shared.isPremiumUnlocked else {
+            showAlert(
+                title: "Premium required",
+                message: "Update to Premium to save desktop shortcuts."
+            )
+            return
+        }
+        let url = currentPageURL()
+        guard let scheme = url.scheme?.lowercased(), scheme == "http" || scheme == "https" else {
+            showAlert(title: "Unavailable", message: "Desktop shortcuts need a web address (http or https).")
+            return
+        }
+        let name = displayNameForDesktopShortcut()
+        DesktopWeblocShortcutPresenter.beginSavePanel(forAppNamed: name, webURL: url)
+    }
+
+    private func currentPageURL() -> URL {
+        webView.url ?? initialURL
+    }
+
+    private func normalizedHost(_ host: String) -> String {
+        let h = host.lowercased()
+        return h.hasPrefix("www.") ? String(h.dropFirst(4)) : h
+    }
+
+    private func resolvedLauncherAppForCurrentPage() -> LauncherApp? {
+        let url = currentPageURL()
+        guard let host = url.host else { return nil }
+        let nh = normalizedHost(host)
+        let apps = LauncherApp.allLaunchableAppsFromUserDefaults()
+        return apps.first { app in
+            guard let appURL = app.webURL, let appHost = appURL.host else { return false }
+            return normalizedHost(appHost) == nh
+        }
+    }
+
+    private func displayNameForDesktopShortcut() -> String {
+        if let app = resolvedLauncherAppForCurrentPage() {
+            return app.name
+        }
+        let t = siteNameLabel.stringValue.trimmingCharacters(in: .whitespacesAndNewlines)
+        if !t.isEmpty, !isLikelyURLString(t) {
+            return t
+        }
+        if let host = currentPageURL().host {
+            return host
+        }
+        return "Shortcut"
+    }
+
+    private func updateAddToStatusBarButtonAppearance() {
+        if resolvedLauncherAppForCurrentPage() == nil {
+            addToStatusBarButton.isEnabled = false
+            addToStatusBarButton.toolTip = "Add to Status Bar — open this site from the launcher first"
+        } else {
+            addToStatusBarButton.isEnabled = true
+            addToStatusBarButton.toolTip = "Add to Status Bar"
+        }
+    }
+
     @objc private func togglePinOnTop() {
         isPinnedOnTop.toggle()
         window?.level = isPinnedOnTop ? .floating : .normal
@@ -615,6 +741,7 @@ final class InAppBrowserWindowController: NSWindowController, NSWindowDelegate {
 
         // Sync center site name.
         updateSiteNameFromWebView()
+        updateAddToStatusBarButtonAppearance()
     }
 
     private func showAlert(title: String, message: String) {