Adds InspectorModel
`InspectorModel` covers previous management of notifications, reader view, and name changes.
This commit is contained in:
parent
dece406f56
commit
0e2b8fd514
103
Multiplatform/Shared/Inspector/InspectorModel.swift
Normal file
103
Multiplatform/Shared/Inspector/InspectorModel.swift
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 */,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user