Merge pull request #6 from pawelorzech/codex/added_new_browsers

Include broader browser discovery in picker
This commit is contained in:
Paweł Orzech 2026-02-04 14:12:00 +01:00 committed by GitHub
commit 7b7fe98666
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 69 additions and 9 deletions

View file

@ -7,26 +7,77 @@ enum PreferredBrowser: String, CaseIterable, Identifiable {
case firefox = "Firefox" case firefox = "Firefox"
case edge = "Microsoft Edge" case edge = "Microsoft Edge"
case brave = "Brave" case brave = "Brave"
case arc = "Arc"
case vivaldi = "Vivaldi"
case zen = "Zen"
case opera = "Opera"
case duckduckgo = "DuckDuckGo"
case orion = "Orion"
case tor = "Tor Browser"
case chromium = "Chromium"
case librewolf = "LibreWolf"
case waterfox = "Waterfox"
case atlas = "ChatGPT Atlas"
var id: String { rawValue } var id: String { rawValue }
var bundleIdentifier: String? { var bundleIdentifiers: [String]? {
switch self { switch self {
case .system: case .system:
return nil return nil
case .safari: case .safari:
return "com.apple.Safari" return ["com.apple.Safari"]
case .chrome: case .chrome:
return "com.google.Chrome" return ["com.google.Chrome"]
case .firefox: case .firefox:
return "org.mozilla.firefox" return ["org.mozilla.firefox"]
case .edge: case .edge:
return "com.microsoft.edgemac" return ["com.microsoft.edgemac"]
case .brave: case .brave:
return "com.brave.Browser" return ["com.brave.Browser"]
case .arc:
return ["company.thebrowser.Browser"]
case .vivaldi:
return ["com.vivaldi.Vivaldi"]
case .zen:
return ["app.zen-browser.zen"]
case .opera:
return ["com.operasoftware.Opera"]
case .duckduckgo:
return ["com.duckduckgo.macos.browser"]
case .orion:
return ["com.kagi.kagimacOS", "com.kagi.kagimacOS.RC"]
case .tor:
return ["com.torproject.tor"]
case .chromium:
return ["org.chromium.Chromium"]
case .librewolf:
return ["io.gitlab.librewolf-community"]
case .waterfox:
return ["net.waterfox.waterfox"]
case .atlas:
return ["com.openai.atlas"]
} }
} }
var installedApplicationURL: URL? {
guard let bundleIdentifiers else { return nil }
for bundleIdentifier in bundleIdentifiers {
if let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleIdentifier) {
return appURL
}
}
return nil
}
var isInstalled: Bool {
self == .system || installedApplicationURL != nil
}
static func availableBrowsers() -> [PreferredBrowser] {
PreferredBrowser.allCases.filter { $0.isInstalled }
}
init(storedValue: String?) { init(storedValue: String?) {
guard let storedValue, guard let storedValue,
let value = PreferredBrowser(rawValue: storedValue) else { let value = PreferredBrowser(rawValue: storedValue) else {
@ -50,8 +101,7 @@ final class BrowserManager {
} }
let preference = PreferredBrowser(storedValue: UserDefaults.standard.string(forKey: "preferredBrowser")) let preference = PreferredBrowser(storedValue: UserDefaults.standard.string(forKey: "preferredBrowser"))
guard let bundleIdentifier = preference.bundleIdentifier, guard let appURL = preference.installedApplicationURL else {
let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleIdentifier) else {
NSWorkspace.shared.open(url) NSWorkspace.shared.open(url)
return return
} }

View file

@ -7,6 +7,7 @@ struct SettingsView: View {
@AppStorage("preferredBrowser") private var preferredBrowser: String = PreferredBrowser.system.rawValue @AppStorage("preferredBrowser") private var preferredBrowser: String = PreferredBrowser.system.rawValue
@State private var inputKey: String = "" @State private var inputKey: String = ""
@State private var showCredits: Bool = false @State private var showCredits: Bool = false
@State private var availableBrowsers: [PreferredBrowser] = PreferredBrowser.availableBrowsers()
// Developer ID for tip feature (bombel) // Developer ID for tip feature (bombel)
private let developerID = 2362436 private let developerID = 2362436
@ -114,7 +115,7 @@ struct SettingsView: View {
.frame(width: 20) .frame(width: 20)
Picker("Preferred Browser", selection: $preferredBrowser) { Picker("Preferred Browser", selection: $preferredBrowser) {
ForEach(PreferredBrowser.allCases) { browser in ForEach(availableBrowsers) { browser in
Text(browser.rawValue).tag(browser.rawValue) Text(browser.rawValue).tag(browser.rawValue)
} }
} }
@ -230,6 +231,15 @@ struct SettingsView: View {
.frame(width: 320) .frame(width: 320)
.onAppear { .onAppear {
inputKey = appState.apiKey inputKey = appState.apiKey
refreshAvailableBrowsers()
}
}
private func refreshAvailableBrowsers() {
let browsers = PreferredBrowser.availableBrowsers()
availableBrowsers = browsers
if !browsers.contains(where: { $0.rawValue == preferredBrowser }) {
preferredBrowser = PreferredBrowser.system.rawValue
} }
} }