Adds InspectorModel

`InspectorModel` covers previous management of notifications, reader view, and name changes.
This commit is contained in:
Stuart Breckenridge 2020-07-18 21:21:59 +08:00
parent dece406f56
commit 0e2b8fd514
No known key found for this signature in database
GPG Key ID: 79BD673276AE83CE
3 changed files with 144 additions and 26 deletions

View File

@ -0,0 +1,103 @@
//
// InspectorModel.swift
// NetNewsWire
//
// Created by Stuart Breckenridge on 18/7/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import Foundation
import UserNotifications
import RSCore
import Account
#if os(macOS)
import AppKit
#else
import UIKit
#endif
class InspectorModel: ObservableObject {
@Published var notificationSettings: UNNotificationSettings?
@Published var editedName: String = ""
@Published var shouldUpdate: Bool = false
@Published var notifyAboutNewArticles: Bool = false {
didSet {
updateNotificationSettings()
}
}
@Published var alwaysShowReaderView: Bool = false
private let centre = UNUserNotificationCenter.current()
private var selectedWebFeed: WebFeed?
private var selectedFolder: Folder?
private var selectedAccount: Account?
init() {
getNotificationSettings()
}
func getNotificationSettings() {
centre.getNotificationSettings { (settings) in
DispatchQueue.main.async {
self.notificationSettings = settings
if settings.authorizationStatus == .authorized {
#if os(macOS)
NSApplication.shared.registerForRemoteNotifications()
#else
UIApplication.shared.registerForRemoteNotifications()
#endif
}
}
}
}
func configure(with feed: WebFeed) {
selectedWebFeed = feed
notifyAboutNewArticles = selectedWebFeed?.isNotifyAboutNewArticles ?? false
alwaysShowReaderView = selectedWebFeed?.isArticleExtractorAlwaysOn ?? false
editedName = feed.nameForDisplay
}
func configure(with folder: Folder) {
selectedFolder = folder
editedName = folder.nameForDisplay
}
func configure(with account: Account) {
selectedAccount = account
editedName = account.nameForDisplay
}
func updateNotificationSettings() {
guard let feed = selectedWebFeed,
let settings = notificationSettings
else { return }
if settings.authorizationStatus == .denied {
notifyAboutNewArticles = false
} else if settings.authorizationStatus == .authorized {
feed.isNotifyAboutNewArticles = notifyAboutNewArticles
} else {
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .sound, .alert]) { [weak self] (granted, error) in
self?.updateNotificationSettings()
if granted {
DispatchQueue.main.async {
self?.selectedWebFeed!.isNotifyAboutNewArticles = self?.notifyAboutNewArticles
#if os(macOS)
NSApplication.shared.registerForRemoteNotifications()
#else
UIApplication.shared.registerForRemoteNotifications()
#endif
}
} else {
DispatchQueue.main.async {
self?.notifyAboutNewArticles = false
}
}
}
}
}
}

View File

@ -14,8 +14,7 @@ struct InspectorView: View {
@Environment(\.presentationMode) var presentationMode @Environment(\.presentationMode) var presentationMode
@StateObject private var feedIconImageLoader = FeedIconImageLoader() @StateObject private var feedIconImageLoader = FeedIconImageLoader()
@State private var editedName: String = "" @StateObject private var inspectorModel = InspectorModel()
@State private var shouldUpdate: Bool = false
var sidebarItem: SidebarItem var sidebarItem: SidebarItem
@ViewBuilder @ViewBuilder
@ -23,13 +22,13 @@ struct InspectorView: View {
switch sidebarItem.representedType { switch sidebarItem.representedType {
case .webFeed: case .webFeed:
WebFeedInspectorView WebFeedInspectorView
.modifier(InspectorPlatformModifier(shouldUpdate: $shouldUpdate)) .modifier(InspectorPlatformModifier(shouldUpdate: $inspectorModel.shouldUpdate))
case .folder: case .folder:
FolderInspectorView FolderInspectorView
.modifier(InspectorPlatformModifier(shouldUpdate: $shouldUpdate)) .modifier(InspectorPlatformModifier(shouldUpdate: $inspectorModel.shouldUpdate))
case .account: case .account:
AccountInspectorView AccountInspectorView
.modifier(InspectorPlatformModifier(shouldUpdate: $shouldUpdate)) .modifier(InspectorPlatformModifier(shouldUpdate: $inspectorModel.shouldUpdate))
default: default:
EmptyView() EmptyView()
} }
@ -44,7 +43,7 @@ struct InspectorView: View {
IconImageView(iconImage: image) IconImageView(iconImage: image)
.frame(width: 30, height: 30) .frame(width: 30, height: 30)
} }
TextField("", text: $editedName) TextField("", text: $inspectorModel.editedName)
} }
} }
@ -52,6 +51,15 @@ struct InspectorView: View {
Divider() Divider()
#endif #endif
Section(content: {
Toggle("Notify About New Articles", isOn: $inspectorModel.notifyAboutNewArticles)
Toggle("Always Show Reader View", isOn: $inspectorModel.alwaysShowReaderView)
})
#if os(macOS)
Divider()
#endif
Section(header: Text("Home Page URL").bold()) { Section(header: Text("Home Page URL").bold()) {
Text((sidebarItem.feed as? WebFeed)?.homePageURL ?? "") Text((sidebarItem.feed as? WebFeed)?.homePageURL ?? "")
} }
@ -71,18 +79,18 @@ struct InspectorView: View {
presentationMode.wrappedValue.dismiss() presentationMode.wrappedValue.dismiss()
}) })
Button("Done", action: { Button("Done", action: {
shouldUpdate = true inspectorModel.shouldUpdate = true
}) }).keyboardShortcut(.defaultAction)
}.padding(.top) }.padding(.top)
#endif #endif
} }
.onAppear { .onAppear {
editedName = sidebarItem.nameForDisplay inspectorModel.configure(with: sidebarItem.feed as! WebFeed)
feedIconImageLoader.loadImage(for: sidebarItem.feed!) feedIconImageLoader.loadImage(for: sidebarItem.feed!)
}.onChange(of: shouldUpdate) { value in }.onChange(of: inspectorModel.shouldUpdate) { value in
if value == true { if value == true {
if editedName.trimmingWhitespace.count > 0 { if inspectorModel.editedName.trimmingWhitespace.count > 0 {
(sidebarItem.feed as? WebFeed)?.editedName = editedName (sidebarItem.feed as? WebFeed)?.editedName = inspectorModel.editedName
} else { } else {
(sidebarItem.feed as? WebFeed)?.editedName = nil (sidebarItem.feed as? WebFeed)?.editedName = nil
} }
@ -102,7 +110,7 @@ struct InspectorView: View {
IconImageView(iconImage: image) IconImageView(iconImage: image)
.frame(width: 30, height: 30) .frame(width: 30, height: 30)
} }
TextField("", text: $editedName) TextField("", text: $inspectorModel.editedName)
} }
} }
@ -113,20 +121,20 @@ struct InspectorView: View {
presentationMode.wrappedValue.dismiss() presentationMode.wrappedValue.dismiss()
}) })
Button("Done", action: { Button("Done", action: {
shouldUpdate = true inspectorModel.shouldUpdate = true
}) }).keyboardShortcut(.defaultAction)
}.padding(.top) }.padding(.top)
#endif #endif
} }
.onAppear { .onAppear {
editedName = sidebarItem.nameForDisplay inspectorModel.configure(with: sidebarItem.represented as! Folder)
feedIconImageLoader.loadImage(for: sidebarItem.feed!) feedIconImageLoader.loadImage(for: sidebarItem.feed!)
} }
.onChange(of: shouldUpdate) { value in .onChange(of: inspectorModel.shouldUpdate) { value in
if value == true { if value == true {
if editedName.trimmingWhitespace.count > 0 { if inspectorModel.editedName.trimmingWhitespace.count > 0 {
(sidebarItem.feed as? Folder)?.name = editedName (sidebarItem.feed as? Folder)?.name = inspectorModel.editedName
} else { } else {
(sidebarItem.feed as? Folder)?.name = nil (sidebarItem.feed as? Folder)?.name = nil
} }
@ -146,7 +154,7 @@ struct InspectorView: View {
.aspectRatio(contentMode: .fit) .aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30) .frame(width: 30, height: 30)
} }
TextField("", text: $editedName) TextField("", text: $inspectorModel.editedName)
} }
} }
@ -157,17 +165,18 @@ struct InspectorView: View {
presentationMode.wrappedValue.dismiss() presentationMode.wrappedValue.dismiss()
}) })
Button("Done", action: { Button("Done", action: {
shouldUpdate = true inspectorModel.shouldUpdate = true
}) }).keyboardShortcut(.defaultAction)
}.padding(.top) }.padding(.top)
#endif #endif
} }
.onAppear { .onAppear {
editedName = sidebarItem.nameForDisplay inspectorModel.configure(with: sidebarItem.represented as! Account)
}.onChange(of: shouldUpdate) { value in }
.onChange(of: inspectorModel.shouldUpdate) { value in
if value == true { if value == true {
if editedName.trimmingWhitespace.count > 0 { if inspectorModel.editedName.trimmingWhitespace.count > 0 {
(sidebarItem.represented as? Account)?.name = editedName (sidebarItem.represented as? Account)?.name = inspectorModel.editedName
} else { } else {
(sidebarItem.represented as? Account)?.name = nil (sidebarItem.represented as? Account)?.name = nil
} }

View File

@ -36,6 +36,8 @@
17930ED524AF10EE00A9BA52 /* AddWebFeedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */; }; 17930ED524AF10EE00A9BA52 /* AddWebFeedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */; };
1799E6A924C2F93F00511E91 /* InspectorPlatformModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1799E6A824C2F93F00511E91 /* InspectorPlatformModifier.swift */; }; 1799E6A924C2F93F00511E91 /* InspectorPlatformModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1799E6A824C2F93F00511E91 /* InspectorPlatformModifier.swift */; };
1799E6AA24C2F93F00511E91 /* InspectorPlatformModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1799E6A824C2F93F00511E91 /* InspectorPlatformModifier.swift */; }; 1799E6AA24C2F93F00511E91 /* InspectorPlatformModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1799E6A824C2F93F00511E91 /* InspectorPlatformModifier.swift */; };
1799E6CD24C320D600511E91 /* InspectorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1799E6CC24C320D600511E91 /* InspectorModel.swift */; };
1799E6CE24C320D600511E91 /* InspectorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1799E6CC24C320D600511E91 /* InspectorModel.swift */; };
179DB1DFBCF9177104B12E0F /* AccountsNewsBlurWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */; }; 179DB1DFBCF9177104B12E0F /* AccountsNewsBlurWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */; };
179DB3CE822BFCC2D774D9F4 /* AccountsNewsBlurWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */; }; 179DB3CE822BFCC2D774D9F4 /* AccountsNewsBlurWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */; };
17D232A824AFF10A0005F075 /* AddWebFeedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */; }; 17D232A824AFF10A0005F075 /* AddWebFeedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */; };
@ -1830,6 +1832,7 @@
17897AC924C281A40014BA03 /* InspectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorView.swift; sourceTree = "<group>"; }; 17897AC924C281A40014BA03 /* InspectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorView.swift; sourceTree = "<group>"; };
17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedView.swift; sourceTree = "<group>"; }; 17930ED324AF10EE00A9BA52 /* AddWebFeedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedView.swift; sourceTree = "<group>"; };
1799E6A824C2F93F00511E91 /* InspectorPlatformModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorPlatformModifier.swift; sourceTree = "<group>"; }; 1799E6A824C2F93F00511E91 /* InspectorPlatformModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorPlatformModifier.swift; sourceTree = "<group>"; };
1799E6CC24C320D600511E91 /* InspectorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InspectorModel.swift; sourceTree = "<group>"; };
179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsNewsBlurWindowController.swift; sourceTree = "<group>"; }; 179DBBA2B22A659F81EED6F9 /* AccountsNewsBlurWindowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountsNewsBlurWindowController.swift; sourceTree = "<group>"; };
17B223DB24AC24D2001E4592 /* TimelineLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineLayoutView.swift; sourceTree = "<group>"; }; 17B223DB24AC24D2001E4592 /* TimelineLayoutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineLayoutView.swift; sourceTree = "<group>"; };
17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedModel.swift; sourceTree = "<group>"; }; 17D232A724AFF10A0005F075 /* AddWebFeedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddWebFeedModel.swift; sourceTree = "<group>"; };
@ -2647,6 +2650,7 @@
children = ( children = (
17897AC924C281A40014BA03 /* InspectorView.swift */, 17897AC924C281A40014BA03 /* InspectorView.swift */,
1799E6A824C2F93F00511E91 /* InspectorPlatformModifier.swift */, 1799E6A824C2F93F00511E91 /* InspectorPlatformModifier.swift */,
1799E6CC24C320D600511E91 /* InspectorModel.swift */,
); );
path = Inspector; path = Inspector;
sourceTree = "<group>"; sourceTree = "<group>";
@ -5246,6 +5250,7 @@
51E4990224A808BB00B667CB /* ColorHash.swift in Sources */, 51E4990224A808BB00B667CB /* ColorHash.swift in Sources */,
51919FAC24AA8CCA00541E64 /* UnreadCountView.swift in Sources */, 51919FAC24AA8CCA00541E64 /* UnreadCountView.swift in Sources */,
5177476224B3BC4700EB0F74 /* SettingsAboutView.swift in Sources */, 5177476224B3BC4700EB0F74 /* SettingsAboutView.swift in Sources */,
1799E6CD24C320D600511E91 /* InspectorModel.swift in Sources */,
51E4991924A8090A00B667CB /* CacheCleaner.swift in Sources */, 51E4991924A8090A00B667CB /* CacheCleaner.swift in Sources */,
51E498F724A8085D00B667CB /* SearchTimelineFeedDelegate.swift in Sources */, 51E498F724A8085D00B667CB /* SearchTimelineFeedDelegate.swift in Sources */,
175942AA24AD533200585066 /* RefreshInterval.swift in Sources */, 175942AA24AD533200585066 /* RefreshInterval.swift in Sources */,
@ -5392,6 +5397,7 @@
51392D1C24AC19A000BE0D35 /* SidebarExpandedContainers.swift in Sources */, 51392D1C24AC19A000BE0D35 /* SidebarExpandedContainers.swift in Sources */,
51C0515F24A77DF800194D5E /* MainApp.swift in Sources */, 51C0515F24A77DF800194D5E /* MainApp.swift in Sources */,
51B54A4324B5499B0014348B /* WebViewProvider.swift in Sources */, 51B54A4324B5499B0014348B /* WebViewProvider.swift in Sources */,
1799E6CE24C320D600511E91 /* InspectorModel.swift in Sources */,
514E6C0024AD255D00AC6F6E /* PreviewArticles.swift in Sources */, 514E6C0024AD255D00AC6F6E /* PreviewArticles.swift in Sources */,
1729529524AA1CAA00D65E66 /* GeneralPreferencesView.swift in Sources */, 1729529524AA1CAA00D65E66 /* GeneralPreferencesView.swift in Sources */,
1769E32724BC5B6C000E1E8E /* AddAccountModel.swift in Sources */, 1769E32724BC5B6C000E1E8E /* AddAccountModel.swift in Sources */,