Default RSS feeds now displayed

This commit is contained in:
Stuart Breckenridge 2020-07-12 18:53:37 +08:00
parent 31b93c5d13
commit c2c138218d
No known key found for this signature in database
GPG Key ID: 79BD673276AE83CE
6 changed files with 139 additions and 41 deletions

View File

@ -8,28 +8,122 @@
import Foundation import Foundation
class MacPreferencesModel { enum PreferencePane: Int, CaseIterable {
case general = 0
case accounts = 1
case advanced = 2
enum PreferencePane: Int, CaseIterable { var description: String {
case general = 0 switch self {
case accounts = 1 case .general:
case advanced = 2 return "General"
case .accounts:
var description: String { return "Accounts"
switch self { case .advanced:
case .general: return "Advanced"
return "General"
case .accounts:
return "Accounts"
case .advanced:
return "Advanced"
}
} }
} }
var currentPreferencePane: PreferencePane = PreferencePane.general }
// General Preferences
class MacPreferencesModel: ObservableObject {
@Published var currentPreferencePane: PreferencePane = PreferencePane.general
@Published var rssReaders = Array(RSSReaderInfo.fetchRSSReaders(nil))
@Published var rssReaderSelection: Set<RSSReader> = RSSReaderInfo.fetchRSSReaders(nil)
} }
// MARK:- RSS Readers
private extension MacPreferencesModel {
func prepareRSSReaders() {
// Top item should always be: NetNewsWire (this app)
// Additional items should be sorted alphabetically.
// Any older versions of NetNewsWire should be listed as: NetNewsWire (old version)
}
func registerAppWithBundleID(_ bundleID: String) {
NSWorkspace.shared.setDefaultAppBundleID(forURLScheme: "feed", to: bundleID)
NSWorkspace.shared.setDefaultAppBundleID(forURLScheme: "feeds", to: bundleID)
objectWillChange.send()
}
}
// MARK: - RSSReaderInfo
struct RSSReaderInfo {
let defaultRSSReaderBundleID: String?
let rssReaders: Set<RSSReader>
static let feedURLScheme = "feed:"
init() {
let defaultRSSReaderBundleID = NSWorkspace.shared.defaultAppBundleID(forURLScheme: RSSReaderInfo.feedURLScheme)
self.defaultRSSReaderBundleID = defaultRSSReaderBundleID
self.rssReaders = RSSReaderInfo.fetchRSSReaders(defaultRSSReaderBundleID)
}
static func fetchRSSReaders(_ defaultRSSReaderBundleID: String?) -> Set<RSSReader> {
let rssReaderBundleIDs = NSWorkspace.shared.bundleIDsForApps(forURLScheme: feedURLScheme)
var rssReaders = Set<RSSReader>()
if let defaultRSSReaderBundleID = defaultRSSReaderBundleID, let defaultReader = RSSReader(bundleID: defaultRSSReaderBundleID) {
rssReaders.insert(defaultReader)
}
rssReaderBundleIDs.forEach { (bundleID) in
if let reader = RSSReader(bundleID: bundleID) {
rssReaders.insert(reader)
}
}
return rssReaders
}
}
// MARK: - RSSReader
struct RSSReader: Hashable {
let bundleID: String
let name: String
let nameMinusAppSuffix: String
let path: String
init?(bundleID: String) {
guard let path = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleID) else {
return nil
}
self.path = path.path
self.bundleID = bundleID
let name = (self.path as NSString).lastPathComponent
self.name = name
if name.hasSuffix(".app") {
self.nameMinusAppSuffix = name.stripping(suffix: ".app")
}
else {
self.nameMinusAppSuffix = name
}
}
// MARK: - Hashable
func hash(into hasher: inout Hasher) {
hasher.combine(bundleID)
}
// MARK: - Equatable
static func ==(lhs: RSSReader, rhs: RSSReader) -> Bool {
return lhs.bundleID == rhs.bundleID
}
}

View File

@ -17,7 +17,7 @@ struct MacPreferencesView: View {
VStack { VStack {
switch viewModel.currentPreferencePane { switch viewModel.currentPreferencePane {
case .general: case .general:
GeneralPreferencesView() GeneralPreferencesView(preferences: viewModel)
.environmentObject(defaults) .environmentObject(defaults)
case .accounts: case .accounts:
AccountsPreferencesView() AccountsPreferencesView()

View File

@ -12,37 +12,34 @@ struct AdvancedPreferencesView: View {
@EnvironmentObject private var preferences: AppDefaults @EnvironmentObject private var preferences: AppDefaults
var body: some View { var body: some View {
VStack {
Form { Form {
Toggle("Check for app updates automatically", isOn: $preferences.checkForUpdatesAutomatically) Toggle("Check for app updates automatically", isOn: $preferences.checkForUpdatesAutomatically)
Toggle("Download Test Builds", isOn: $preferences.downloadTestBuilds) Toggle("Download Test Builds", isOn: $preferences.downloadTestBuilds)
HStack {
Spacer() Text("If youre not sure, don't enable test builds. Test builds may have bugs, which may include crashing bugs and data loss.")
Text("If youre not sure, don't enable test builds. Test builds may have bugs, which may include crashing bugs and data loss.").foregroundColor(.secondary) .foregroundColor(.secondary)
Spacer() .lineLimit(3)
} .padding(.bottom, 8)
HStack { HStack {
Spacer() Spacer()
Button("Check for Updates", action: {}) Button("Check for Updates", action: {})
Spacer() Spacer()
}.padding(.vertical, 12) }.padding(.bottom, 8)
Toggle("Send Crash Logs Automatically", isOn: $preferences.sendCrashLogs) Toggle("Send Crash Logs Automatically", isOn: $preferences.sendCrashLogs)
Spacer()
HStack { HStack {
Spacer() Spacer()
Button("Privacy Policy", action: {}) Button("Privacy Policy", action: {
NSWorkspace.shared.open(URL(string: "https://ranchero.com/netnewswire/privacypolicy")!)
})
Spacer() Spacer()
}.padding(.top, 12) }.padding(.top, 12)
}.frame(width: 400, alignment: .center)
}
Spacer()
}.frame(width: 300, alignment: .center)
} }
} }

View File

@ -10,11 +10,11 @@ import SwiftUI
struct GeneralPreferencesView: View { struct GeneralPreferencesView: View {
@EnvironmentObject private var defaults: AppDefaults @EnvironmentObject private var defaults: AppDefaults
@ObservedObject var preferences: MacPreferencesModel
var body: some View { var body: some View {
VStack {
Form { Form {
Picker("Refresh Feeds", Picker("Refresh feeds",
selection: $defaults.interval, selection: $defaults.interval,
content: { content: {
ForEach(RefreshInterval.allCases, content: { interval in ForEach(RefreshInterval.allCases, content: { interval in
@ -23,12 +23,19 @@ struct GeneralPreferencesView: View {
}) })
.frame(width: 300, alignment: .center) .frame(width: 300, alignment: .center)
Picker("Default RSS reader", selection: $preferences.rssReaderSelection, content: {
ForEach(0..<preferences.rssReaders.count, content: { i in
Text(preferences.rssReaders[i].nameMinusAppSuffix)
})
})
Toggle("Open webpages in background in browser", isOn: $defaults.openInBrowserInBackground) Toggle("Open webpages in background in browser", isOn: $defaults.openInBrowserInBackground)
Toggle("Hide Unread Count in Dock", isOn: $defaults.hideDockUnreadCount) Toggle("Hide Unread Count in Dock", isOn: $defaults.hideDockUnreadCount)
} }
Spacer() .frame(width: 400, alignment: .center)
}.frame(width: 300, alignment: .center) .lineLimit(2)
} }
} }

View File

@ -2507,19 +2507,19 @@
children = ( children = (
1717535524BADF33004498C6 /* MacPreferencesModel.swift */, 1717535524BADF33004498C6 /* MacPreferencesModel.swift */,
1729529624AA1CD000D65E66 /* MacPreferencesView.swift */, 1729529624AA1CD000D65E66 /* MacPreferencesView.swift */,
1729529924AA1CE100D65E66 /* Preferences Subviews */, 1729529924AA1CE100D65E66 /* Preference Panes */,
); );
path = Preferences; path = Preferences;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
1729529924AA1CE100D65E66 /* Preferences Subviews */ = { 1729529924AA1CE100D65E66 /* Preference Panes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
1729529224AA1CAA00D65E66 /* GeneralPreferencesView.swift */, 1729529224AA1CAA00D65E66 /* GeneralPreferencesView.swift */,
1729529024AA1CAA00D65E66 /* AccountsPreferencesView.swift */, 1729529024AA1CAA00D65E66 /* AccountsPreferencesView.swift */,
1729529124AA1CAA00D65E66 /* AdvancedPreferencesView.swift */, 1729529124AA1CAA00D65E66 /* AdvancedPreferencesView.swift */,
); );
path = "Preferences Subviews"; path = "Preference Panes";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
17930ED224AF10CD00A9BA52 /* Add */ = { 17930ED224AF10CD00A9BA52 /* Add */ = {