Default RSS feeds now displayed
This commit is contained in:
parent
31b93c5d13
commit
c2c138218d
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 you’re not sure, don't enable test builds. Test builds may have bugs, which may include crashing bugs and data loss.")
|
||||||
Text("If you’re 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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -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 */ = {
|
||||||
|
|
Loading…
Reference in New Issue