diff --git a/Account/Sources/Account/WebFeed.swift b/Account/Sources/Account/WebFeed.swift index cd10c3478..f74ec904f 100644 --- a/Account/Sources/Account/WebFeed.swift +++ b/Account/Sources/Account/WebFeed.swift @@ -11,7 +11,7 @@ import RSCore import RSWeb import Articles -public final class WebFeed: Feed, Renamable, Hashable { +public final class WebFeed: Feed, Renamable, Hashable, ObservableObject { public var defaultReadFilterType: ReadFilterType { return .none diff --git a/iOS/Settings/Views/New Article Notifications/NewArticleNotificationsView.swift b/iOS/Settings/Views/New Article Notifications/NewArticleNotificationsView.swift index e29686752..cadf3b247 100644 --- a/iOS/Settings/Views/New Article Notifications/NewArticleNotificationsView.swift +++ b/iOS/Settings/Views/New Article Notifications/NewArticleNotificationsView.swift @@ -10,49 +10,76 @@ import SwiftUI import Account import RSCore -struct NewArticleNotificationsView: View { + +struct NewArticleNotificationsView: View, Logging { @State private var activeAccounts = AccountManager.shared.sortedActiveAccounts + var body: some View { - List { - ForEach(activeAccounts, id: \.accountID) { account in - Section(header: Text(account.nameForDisplay)) { - ForEach(sortedWebFeedsForAccount(account), id: \.webFeedID) { feed in - notificationToggle(feed) - } + List(activeAccounts, id: \.accountID) { account in + Section(header: Text(account.nameForDisplay)) { + ForEach(sortedWebFeedsForAccount(account), id: \.webFeedID) { feed in + WebFeedToggle(webfeed: feed) + .id(feed.webFeedID) } } .navigationTitle(Text("New Article Notifications")) .navigationBarTitleDisplayMode(.inline) - .onReceive(NotificationCenter.default.publisher(for: .WebFeedIconDidBecomeAvailable)) { _ in - activeAccounts = AccountManager.shared.sortedActiveAccounts - } - .onReceive(NotificationCenter.default.publisher(for: .FaviconDidBecomeAvailable)) { _ in - activeAccounts = AccountManager.shared.sortedActiveAccounts - } + } .tint(Color(uiColor: AppAssets.primaryAccentColor)) + .onReceive(NotificationCenter.default.publisher(for: .FaviconDidBecomeAvailable)) { notification in + guard let faviconURLString = notification.userInfo?["faviconURL"] as? String, + let faviconHost = URL(string: faviconURLString)?.host else { + return + } + activeAccounts.forEach { account in + for feed in Array(account.flattenedWebFeeds()) { + if let feedURLHost = URL(string: feed.url)?.host { + if faviconHost == feedURLHost { + feed.objectWillChange.send() + } + } + } + } + } + .onReceive(NotificationCenter.default.publisher(for: .WebFeedIconDidBecomeAvailable)) { notification in + guard let webFeed = notification.userInfo?[UserInfoKey.webFeed] as? WebFeed else { return } + webFeed.objectWillChange.send() + } } - private func sortedWebFeedsForAccount(_ account: Account) -> [WebFeed] { return Array(account.flattenedWebFeeds()).sorted(by: { $0.nameForDisplay.caseInsensitiveCompare($1.nameForDisplay) == .orderedAscending }) } - private func notificationToggle(_ webfeed: WebFeed) -> some View { - HStack { - Image(uiImage: IconImageCache.shared.imageFor(webfeed.feedID!)!.image) - .resizable() - .frame(width: 25, height: 25) - .cornerRadius(4) - Toggle(webfeed.nameForDisplay, isOn: Binding( - get: { webfeed.isNotifyAboutNewArticles ?? false }, - set: { webfeed.isNotifyAboutNewArticles = $0 })) - } - } + } +fileprivate struct WebFeedToggle: View { + + @ObservedObject var webfeed: WebFeed + + var body: some View { + //let _ = Self._printChanges() + Toggle(isOn: Binding( + get: { webfeed.isNotifyAboutNewArticles ?? false }, + set: { webfeed.isNotifyAboutNewArticles = $0 })) { + Label { + Text(webfeed.nameForDisplay) + } icon: { + Image(uiImage: IconImageCache.shared.imageFor(webfeed.feedID!)!.image) + .resizable() + .frame(width: 25, height: 25) + .cornerRadius(4) + } + } + } + +} + + struct NewArticleNotificationsView_Previews: PreviewProvider { static var previews: some View { NewArticleNotificationsView()