diff --git a/MacTorn/MacTorn/Utilities/BrowserManager.swift b/MacTorn/MacTorn/Utilities/BrowserManager.swift new file mode 100644 index 0000000..30c5105 --- /dev/null +++ b/MacTorn/MacTorn/Utilities/BrowserManager.swift @@ -0,0 +1,62 @@ +import AppKit + +enum PreferredBrowser: String, CaseIterable, Identifiable { + case system = "System Default" + case safari = "Safari" + case chrome = "Google Chrome" + case firefox = "Firefox" + case edge = "Microsoft Edge" + case brave = "Brave" + + var id: String { rawValue } + + var bundleIdentifier: String? { + switch self { + case .system: + return nil + case .safari: + return "com.apple.Safari" + case .chrome: + return "com.google.Chrome" + case .firefox: + return "org.mozilla.firefox" + case .edge: + return "com.microsoft.edgemac" + case .brave: + return "com.brave.Browser" + } + } + + init(storedValue: String?) { + guard let storedValue, + let value = PreferredBrowser(rawValue: storedValue) else { + self = .system + return + } + self = value + } +} + +final class BrowserManager { + static let shared = BrowserManager() + + private init() {} + + func open(_ url: URL) { + guard let scheme = url.scheme, + ["http", "https"].contains(scheme) else { + NSWorkspace.shared.open(url) + return + } + + let preference = PreferredBrowser(storedValue: UserDefaults.standard.string(forKey: "preferredBrowser")) + guard let bundleIdentifier = preference.bundleIdentifier, + let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleIdentifier) else { + NSWorkspace.shared.open(url) + return + } + + let configuration = NSWorkspace.OpenConfiguration() + NSWorkspace.shared.open([url], withApplicationAt: appURL, configuration: configuration, completionHandler: nil) + } +} diff --git a/MacTorn/MacTorn/Utilities/NotificationManager.swift b/MacTorn/MacTorn/Utilities/NotificationManager.swift index 816cf00..7ce7cbf 100644 --- a/MacTorn/MacTorn/Utilities/NotificationManager.swift +++ b/MacTorn/MacTorn/Utilities/NotificationManager.swift @@ -127,7 +127,7 @@ class NotificationManager: NSObject, UNUserNotificationCenterDelegate { ) { let categoryIdentifier = response.notification.request.content.categoryIdentifier if let type = NotificationType(rawValue: categoryIdentifier) { - NSWorkspace.shared.open(type.url) + BrowserManager.shared.open(type.url) } completionHandler() } diff --git a/MacTorn/MacTorn/Utilities/ShortcutsManager.swift b/MacTorn/MacTorn/Utilities/ShortcutsManager.swift index 4d02bdb..0a37baf 100644 --- a/MacTorn/MacTorn/Utilities/ShortcutsManager.swift +++ b/MacTorn/MacTorn/Utilities/ShortcutsManager.swift @@ -41,6 +41,6 @@ class ShortcutsManager: ObservableObject { func openURL(_ urlString: String) { guard let url = URL(string: urlString) else { return } - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } diff --git a/MacTorn/MacTorn/ViewModels/AppState.swift b/MacTorn/MacTorn/ViewModels/AppState.swift index 9a26980..169cb67 100644 --- a/MacTorn/MacTorn/ViewModels/AppState.swift +++ b/MacTorn/MacTorn/ViewModels/AppState.swift @@ -770,7 +770,7 @@ class AppState: ObservableObject { showFeedbackPrompt = false saveFeedbackState() if let url = URL(string: "https://www.torn.com/forums.php#/p=threads&f=67&t=16532308") { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } @@ -779,7 +779,7 @@ class AppState: ObservableObject { showFeedbackPrompt = false saveFeedbackState() if let url = URL(string: "mailto:pawel@orzech.lol?subject=MacTorn%20Feedback") { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } diff --git a/MacTorn/MacTorn/Views/AttacksView.swift b/MacTorn/MacTorn/Views/AttacksView.swift index 46ef233..9542516 100644 --- a/MacTorn/MacTorn/Views/AttacksView.swift +++ b/MacTorn/MacTorn/Views/AttacksView.swift @@ -58,7 +58,7 @@ struct AttacksView: View { Button { if let opponentId = attack.opponentId(forUserId: userId), let url = URL(string: "https://www.torn.com/profiles.php?XID=\(opponentId)") { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } label: { HStack(spacing: 6) { @@ -128,7 +128,7 @@ struct AttacksView: View { private func openURL(_ urlString: String) { if let url = URL(string: urlString) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } } diff --git a/MacTorn/MacTorn/Views/CreditsView.swift b/MacTorn/MacTorn/Views/CreditsView.swift index 8f0e6c6..e7365b2 100644 --- a/MacTorn/MacTorn/Views/CreditsView.swift +++ b/MacTorn/MacTorn/Views/CreditsView.swift @@ -238,21 +238,21 @@ struct CreditsView: View { private func openTornProfile(_ tornID: Int) { let urlString = "https://www.torn.com/profiles.php?XID=\(tornID)" if let url = URL(string: urlString) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } private func openFaction(_ factionID: Int) { let urlString = "https://www.torn.com/factions.php?step=profile&ID=\(factionID)" if let url = URL(string: urlString) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } private func openCompany(_ ownerID: Int) { let urlString = "https://www.torn.com/joblist.php#/p=corpinfo&userID=\(ownerID)" if let url = URL(string: urlString) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } } diff --git a/MacTorn/MacTorn/Views/FactionView.swift b/MacTorn/MacTorn/Views/FactionView.swift index 900ab8a..bbacbd2 100644 --- a/MacTorn/MacTorn/Views/FactionView.swift +++ b/MacTorn/MacTorn/Views/FactionView.swift @@ -132,7 +132,7 @@ struct FactionView: View { private func openURL(_ urlString: String) { if let url = URL(string: urlString) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } } diff --git a/MacTorn/MacTorn/Views/MoneyView.swift b/MacTorn/MacTorn/Views/MoneyView.swift index cc85d37..5933a7d 100644 --- a/MacTorn/MacTorn/Views/MoneyView.swift +++ b/MacTorn/MacTorn/Views/MoneyView.swift @@ -106,7 +106,7 @@ struct MoneyView: View { private func openURL(_ urlString: String) { if let url = URL(string: urlString) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } } diff --git a/MacTorn/MacTorn/Views/PropertiesView.swift b/MacTorn/MacTorn/Views/PropertiesView.swift index e5004b4..2353f26 100644 --- a/MacTorn/MacTorn/Views/PropertiesView.swift +++ b/MacTorn/MacTorn/Views/PropertiesView.swift @@ -52,7 +52,7 @@ struct PropertiesView: View { private func openURL(_ urlString: String) { if let url = URL(string: urlString) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } } diff --git a/MacTorn/MacTorn/Views/SettingsView.swift b/MacTorn/MacTorn/Views/SettingsView.swift index f0ca1e7..32d87b3 100644 --- a/MacTorn/MacTorn/Views/SettingsView.swift +++ b/MacTorn/MacTorn/Views/SettingsView.swift @@ -4,6 +4,7 @@ struct SettingsView: View { @EnvironmentObject var appState: AppState @AppStorage("appearanceMode") private var appearanceMode: String = AppearanceMode.system.rawValue @AppStorage("reduceTransparency") private var reduceTransparency: Bool = false + @AppStorage("preferredBrowser") private var preferredBrowser: String = PreferredBrowser.system.rawValue @State private var inputKey: String = "" @State private var showCredits: Bool = false @@ -106,6 +107,20 @@ struct SettingsView: View { .labelsHidden() } + // Preferred Browser + HStack { + Image(systemName: "globe") + .foregroundColor(.secondary) + .frame(width: 20) + + Picker("Preferred Browser", selection: $preferredBrowser) { + ForEach(PreferredBrowser.allCases) { browser in + Text(browser.rawValue).tag(browser.rawValue) + } + } + .pickerStyle(.menu) + } + // Reduce Transparency (Accessibility) HStack { Image(systemName: "eye") @@ -164,7 +179,7 @@ struct SettingsView: View { Button("Download Update") { if let url = URL(string: update.htmlUrl) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } .buttonStyle(.borderedProminent) @@ -268,7 +283,7 @@ struct SettingsView: View { private func openTornProfile() { let url = "https://www.torn.com/profiles.php?XID=\(developerID)" if let url = URL(string: url) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } } diff --git a/MacTorn/MacTorn/Views/StatusView.swift b/MacTorn/MacTorn/Views/StatusView.swift index a94bd11..7f1f99f 100644 --- a/MacTorn/MacTorn/Views/StatusView.swift +++ b/MacTorn/MacTorn/Views/StatusView.swift @@ -99,7 +99,7 @@ struct StatusView: View { private var messagesBadge: some View { Button { if let url = URL(string: "https://www.torn.com/messages.php") { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } label: { HStack { diff --git a/MacTorn/MacTorn/Views/TravelView.swift b/MacTorn/MacTorn/Views/TravelView.swift index 0169c07..ca7040f 100644 --- a/MacTorn/MacTorn/Views/TravelView.swift +++ b/MacTorn/MacTorn/Views/TravelView.swift @@ -149,7 +149,7 @@ struct TravelView: View { Button { if let url = URL(string: "https://www.torn.com/travelagency.php") { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } label: { HStack { @@ -204,7 +204,7 @@ struct TravelView: View { // Show only return button when abroad Button { if let url = URL(string: "https://www.torn.com/travelagency.php") { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } label: { HStack { @@ -234,7 +234,7 @@ struct TravelView: View { private func destinationButton(_ destination: TornDestination) -> some View { Button { - NSWorkspace.shared.open(destination.travelAgencyURL) + BrowserManager.shared.open(destination.travelAgencyURL) } label: { VStack(spacing: 4) { HStack(spacing: 4) { @@ -304,7 +304,7 @@ struct TravelView: View { HStack(spacing: 8) { Button { if let url = URL(string: "https://www.torn.com/travelagency.php") { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } label: { HStack { @@ -321,7 +321,7 @@ struct TravelView: View { Button { if let url = URL(string: "https://www.torn.com/page.php?sid=ItemMarket") { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } label: { HStack { diff --git a/MacTorn/MacTorn/Views/WatchlistView.swift b/MacTorn/MacTorn/Views/WatchlistView.swift index f1fb764..a8e083e 100644 --- a/MacTorn/MacTorn/Views/WatchlistView.swift +++ b/MacTorn/MacTorn/Views/WatchlistView.swift @@ -126,7 +126,7 @@ struct WatchlistView: View { private func openURL(_ urlString: String) { if let url = URL(string: urlString) { - NSWorkspace.shared.open(url) + BrowserManager.shared.open(url) } } }