diff --git a/Sources/Firelink/Settings/IntegrationSettingsPane.swift b/Sources/Firelink/Settings/IntegrationSettingsPane.swift index 8e45957..d14cc8d 100644 --- a/Sources/Firelink/Settings/IntegrationSettingsPane.swift +++ b/Sources/Firelink/Settings/IntegrationSettingsPane.swift @@ -3,8 +3,6 @@ import SwiftUI struct IntegrationSettingsPane: View { @EnvironmentObject private var controller: DownloadController - @State private var copiedExtensionURL: URL? - @State private var installMessage = "" var body: some View { Form { @@ -27,37 +25,25 @@ struct IntegrationSettingsPane: View { } Section("Installation") { - HStack(spacing: 10) { - Button { - copyExtensionToDownloads() - } label: { - Label("Copy to Downloads", systemImage: "folder.badge.plus") - } + VStack(alignment: .leading, spacing: 16) { + Text("Firelink Companion is officially available on the Mozilla Add-on store. Install it to easily intercept downloads and send media directly to Firelink.") + .foregroundStyle(.secondary) Button { - showCopiedExtensionInFinder() + if let url = URL(string: "https://addons.mozilla.org/en-US/firefox/addon/firelink-companion/") { + NSWorkspace.shared.open(url) + } } label: { - Label("Show Copied Folder", systemImage: "folder.fill") - } - .disabled(copiedExtensionURL == nil) - - Button { - openFirefoxDebugging() - } label: { - Label("Open Firefox Debugging", systemImage: "link") + Label("Install on Firefox", systemImage: "arrow.down.app") + .font(.headline) + .padding(.horizontal, 12) + .padding(.vertical, 4) } + .buttonStyle(.borderedProminent) + .tint(Color(nsColor: NSColor(red: 1.0, green: 0.44, blue: 0.22, alpha: 1.0))) // Firefox Orange + .controlSize(.large) } - .buttonStyle(.borderedProminent) - - if !installMessage.isEmpty { - Text(installMessage) - .font(.caption) - .foregroundStyle(.secondary) - } - - Text("Firelink Companion has been submitted to Mozilla and is awaiting review. Until it is approved, load the extension manually:\n1. Click 'Copy to Downloads'.\n2. Click 'Open Firefox Debugging'.\n3. Click 'This Firefox' on the left sidebar.\n4. Click 'Load Temporary Add-on' and select manifest.json inside Downloads/Firelink Firefox Extension.\n\nKeep the copied folder while Firefox is running. Temporary add-ons are removed when Firefox restarts, so you can delete the folder after restart or after installing the approved add-on.") - .font(.caption) - .foregroundStyle(.secondary) + .padding(.vertical, 8) } Section("Diagnostics") { @@ -70,16 +56,6 @@ struct IntegrationSettingsPane: View { .foregroundStyle(.orange) } } - - LabeledContent("Copied folder") { - if FileManager.default.fileExists(atPath: downloadsExtensionURL.appendingPathComponent("manifest.json").path) { - Label("Ready", systemImage: "checkmark.seal.fill") - .foregroundStyle(.green) - } else { - Label("Not copied", systemImage: "folder.badge.questionmark") - .foregroundStyle(.secondary) - } - } } Section("Permissions & Privacy") { @@ -89,99 +65,5 @@ struct IntegrationSettingsPane: View { } } .formStyle(.grouped) - .onAppear { - if FileManager.default.fileExists(atPath: downloadsExtensionURL.path) { - copiedExtensionURL = downloadsExtensionURL - } - } - } - - private var downloadsExtensionURL: URL { - let downloads = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first - ?? URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("Downloads") - return downloads.appendingPathComponent("Firelink Firefox Extension", isDirectory: true) - } - - private func copyExtensionToDownloads() { - guard let sourceURL = bundledFirefoxExtensionURL() else { - installMessage = "The bundled Firefox extension folder was not found." - return - } - - let destinationURL = downloadsExtensionURL - do { - if FileManager.default.fileExists(atPath: destinationURL.path) { - try FileManager.default.removeItem(at: destinationURL) - } - - try copyFirefoxExtension(from: sourceURL, to: destinationURL) - copiedExtensionURL = destinationURL - installMessage = "Copied to \(destinationURL.path). Select manifest.json from this folder in Firefox." - showCopiedExtensionInFinder() - } catch { - installMessage = "Could not copy the extension to Downloads: \(error.localizedDescription)" - } - } - - private func bundledFirefoxExtensionURL() -> URL? { - if let bundled = Bundle.main.url(forResource: "FirefoxExtension", withExtension: nil) { - return bundled - } - - let sourceFile = URL(fileURLWithPath: #filePath) - let projectRoot = sourceFile - .deletingLastPathComponent() - .deletingLastPathComponent() - .deletingLastPathComponent() - let sourceTreeExtension = projectRoot.appendingPathComponent("Extensions/Firefox", isDirectory: true) - return FileManager.default.fileExists(atPath: sourceTreeExtension.appendingPathComponent("manifest.json").path) - ? sourceTreeExtension - : nil - } - - private func copyFirefoxExtension(from sourceURL: URL, to destinationURL: URL) throws { - let fileManager = FileManager.default - try fileManager.createDirectory(at: destinationURL, withIntermediateDirectories: true) - - for component in ["background.js", "content.js", "manifest.json", "icons", "popup"] { - try fileManager.copyItem( - at: sourceURL.appendingPathComponent(component), - to: destinationURL.appendingPathComponent(component) - ) - } - } - - private func showCopiedExtensionInFinder() { - let folderURL = copiedExtensionURL ?? downloadsExtensionURL - let manifestURL = folderURL.appendingPathComponent("manifest.json") - if FileManager.default.fileExists(atPath: manifestURL.path) { - NSWorkspace.shared.activateFileViewerSelecting([manifestURL]) - } else if FileManager.default.fileExists(atPath: folderURL.path) { - NSWorkspace.shared.activateFileViewerSelecting([folderURL]) - } - } - - private func openFirefoxDebugging() { - let bundleIDs = [ - "org.mozilla.firefoxdeveloperedition", - "org.mozilla.firefox", - "org.mozilla.nightly" - ] - - let workspace = NSWorkspace.shared - for id in bundleIDs { - if let appURL = workspace.urlForApplication(withBundleIdentifier: id) { - let process = Process() - process.executableURL = URL(fileURLWithPath: "/usr/bin/open") - process.arguments = ["-a", appURL.path, "about:debugging"] - try? process.run() - return - } - } - - // Fallback - if let fallbackURL = URL(string: "about:debugging") { - workspace.open(fallbackURL) - } } }