From ac5cfada4fb17ce4b11aaeb8d9af3260e49a9eb7 Mon Sep 17 00:00:00 2001 From: Phil Viso Date: Fri, 3 Jul 2020 07:15:51 -0500 Subject: [PATCH 1/6] Corrected spelling of palette --- Multiplatform/iOS/Settings/SettingsView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Multiplatform/iOS/Settings/SettingsView.swift b/Multiplatform/iOS/Settings/SettingsView.swift index b08cd249b..727aa93c7 100644 --- a/Multiplatform/iOS/Settings/SettingsView.swift +++ b/Multiplatform/iOS/Settings/SettingsView.swift @@ -158,7 +158,7 @@ struct SettingsView: View { destination: EmptyView(), label: { HStack { - Text("Color Pallete") + Text("Color Palette") Spacer() Text("Automatic") .foregroundColor(.secondary) From 2ed0d66e42fe671d45bc94dca378dc640c5859d4 Mon Sep 17 00:00:00 2001 From: Phil Viso Date: Sat, 4 Jul 2020 09:09:49 -0500 Subject: [PATCH 2/6] Implement iOS progress view #2162 --- Multiplatform/Shared/MainApp.swift | 3 + ...PreviewProvider+RefreshProgressModel.swift | 29 +++++ .../Shared/Sidebar/RefreshProgressModel.swift | 101 ++++++++++++++++++ .../Shared/Sidebar/RefreshProgressView.swift | 57 ++++++++++ .../Shared/Sidebar/SidebarToolbar.swift | 21 +++- NetNewsWire.xcodeproj/project.pbxproj | 18 ++++ 6 files changed, 224 insertions(+), 5 deletions(-) create mode 100644 Multiplatform/Shared/Previews/PreviewProvider+RefreshProgressModel.swift create mode 100644 Multiplatform/Shared/Sidebar/RefreshProgressModel.swift create mode 100644 Multiplatform/Shared/Sidebar/RefreshProgressView.swift diff --git a/Multiplatform/Shared/MainApp.swift b/Multiplatform/Shared/MainApp.swift index 1be5b3720..c38e40a84 100644 --- a/Multiplatform/Shared/MainApp.swift +++ b/Multiplatform/Shared/MainApp.swift @@ -19,6 +19,7 @@ struct MainApp: App { #endif @StateObject private var sceneModel = SceneModel() + @StateObject private var refreshProgresModel = RefreshProgressModel() @StateObject private var defaults = AppDefaults.shared @State private var showSheet = false @@ -28,6 +29,7 @@ struct MainApp: App { SceneNavigationView() .frame(minWidth: 600, idealWidth: 1000, maxWidth: .infinity, minHeight: 600, idealHeight: 700, maxHeight: .infinity) .environmentObject(sceneModel) + .environmentObject(refreshProgresModel) .environmentObject(defaults) .sheet(isPresented: $showSheet, onDismiss: { showSheet = false }) { AddWebFeedView() @@ -153,6 +155,7 @@ struct MainApp: App { WindowGroup { SceneNavigationView() .environmentObject(sceneModel) + .environmentObject(refreshProgresModel) .environmentObject(defaults) .modifier(PreferredColorSchemeModifier(preferredColorScheme: defaults.userInterfaceColorPalette)) } diff --git a/Multiplatform/Shared/Previews/PreviewProvider+RefreshProgressModel.swift b/Multiplatform/Shared/Previews/PreviewProvider+RefreshProgressModel.swift new file mode 100644 index 000000000..8538f7c8b --- /dev/null +++ b/Multiplatform/Shared/Previews/PreviewProvider+RefreshProgressModel.swift @@ -0,0 +1,29 @@ +// +// PreviewProvider+RefreshProgressModel.swift +// NetNewsWire +// +// Created by Phil Viso on 7/3/20. +// Copyright © 2020 Ranchero Software. All rights reserved. +// + +import Account +import Foundation +import RSWeb +import SwiftUI + +extension PreviewProvider { + + static func refreshProgressModel(lastRefreshDate: Date?, + tasksCompleted: Int, + totalTasks: Int) -> RefreshProgressModel { + return RefreshProgressModel { () -> Date? in + return lastRefreshDate + } combinedRefreshProgressProvider: { () -> CombinedRefreshProgress in + let progress = DownloadProgress(numberOfTasks: totalTasks) + progress.numberRemaining = totalTasks - tasksCompleted + + return CombinedRefreshProgress(downloadProgressArray: [progress]) + } + } + +} diff --git a/Multiplatform/Shared/Sidebar/RefreshProgressModel.swift b/Multiplatform/Shared/Sidebar/RefreshProgressModel.swift new file mode 100644 index 000000000..0c662d6c6 --- /dev/null +++ b/Multiplatform/Shared/Sidebar/RefreshProgressModel.swift @@ -0,0 +1,101 @@ +// +// RefreshProgressModel.swift +// NetNewsWire +// +// Created by Phil Viso on 7/2/20. +// Copyright © 2020 Ranchero Software. All rights reserved. +// + +import Account +import Combine +import Foundation +import SwiftUI + +class RefreshProgressModel: ObservableObject { + + enum State { + case refreshProgress(Float) + case lastRefreshDateText(String) + case none + } + + @Published var state = State.none + + private static var dateFormatter: RelativeDateTimeFormatter = { + let formatter = RelativeDateTimeFormatter() + formatter.dateTimeStyle = .named + + return formatter + }() + + private let lastRefreshDate: () -> Date? + private let combinedRefreshProgress: () -> CombinedRefreshProgress + + private static let lastRefreshDateTextUpdateInterval = 60 + private static let lastRefreshDateTextRelativeDateFormattingThreshold = 60.0 + + init(lastRefreshDateProvider: @escaping () -> Date?, + combinedRefreshProgressProvider: @escaping () -> CombinedRefreshProgress) { + self.lastRefreshDate = lastRefreshDateProvider + self.combinedRefreshProgress = combinedRefreshProgressProvider + + updateState() + + observeRefreshProgress() + scheduleLastRefreshDateTextUpdate() + } + + // MARK: Observing account changes + + private func observeRefreshProgress() { + NotificationCenter.default.addObserver(self, selector: #selector(updateState), name: .AccountRefreshProgressDidChange, object: nil) + } + + // MARK: Refreshing state + + @objc private func updateState() { + let progress = combinedRefreshProgress() + + if !progress.isComplete { + let fractionCompleted = Float(progress.numberCompleted) / Float(progress.numberOfTasks) + self.state = .refreshProgress(fractionCompleted) + } else if let lastRefreshDate = self.lastRefreshDate() { + let text = localizedLastRefreshText(lastRefreshDate: lastRefreshDate) + self.state = .lastRefreshDateText(text) + } else { + self.state = .none + } + } + + private func scheduleLastRefreshDateTextUpdate() { + DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(Self.lastRefreshDateTextUpdateInterval)) { + self.updateState() + self.scheduleLastRefreshDateTextUpdate() + } + } + + private func localizedLastRefreshText(lastRefreshDate: Date) -> String { + let now = Date() + + if now > lastRefreshDate.addingTimeInterval(Self.lastRefreshDateTextRelativeDateFormattingThreshold) { + let localizedDate = Self.dateFormatter.localizedString(for: lastRefreshDate, relativeTo: now) + let formatString = NSLocalizedString("Updated %@", comment: "Updated") as NSString + + return NSString.localizedStringWithFormat(formatString, localizedDate) as String + } else { + return NSLocalizedString("Updated Just Now", comment: "Updated Just Now") + } + } + +} + +extension RefreshProgressModel { + + convenience init() { + self.init( + lastRefreshDateProvider: { AccountManager.shared.lastArticleFetchEndTime }, + combinedRefreshProgressProvider: { AccountManager.shared.combinedRefreshProgress } + ) + } + +} diff --git a/Multiplatform/Shared/Sidebar/RefreshProgressView.swift b/Multiplatform/Shared/Sidebar/RefreshProgressView.swift new file mode 100644 index 000000000..4e776463e --- /dev/null +++ b/Multiplatform/Shared/Sidebar/RefreshProgressView.swift @@ -0,0 +1,57 @@ +// +// RefreshProgressView.swift +// NetNewsWire +// +// Created by Phil Viso on 7/2/20. +// Copyright © 2020 Ranchero Software. All rights reserved. +// + +import SwiftUI + +struct RefreshProgressView: View { + + @EnvironmentObject var refreshProgressModel: RefreshProgressModel + + @ViewBuilder var body: some View { + switch refreshProgressModel.state { + case .refreshProgress(let progress): + ProgressView(value: progress) + .frame(width: progressViewWidth()) + case .lastRefreshDateText(let text): + Text(text) + .lineLimit(1) + .font(.caption) + .foregroundColor(.secondary) + case .none: + EmptyView() + } + } + + // MARK - + + private func progressViewWidth() -> CGFloat { + #if os(iOS) + return 100.0 + #endif + + #if os(macOS) + return 40.0 + #endif + } + +} + +struct RefreshProgressView_Previews: PreviewProvider { + static var previews: some View { + Group { + RefreshProgressView() + .environmentObject(refreshProgressModel(lastRefreshDate: nil, tasksCompleted: 1, totalTasks: 2)) + .previewDisplayName("Refresh in progress") + + RefreshProgressView() + .environmentObject(refreshProgressModel(lastRefreshDate: Date(timeIntervalSinceNow: -120.0), tasksCompleted: 0, totalTasks: 0)) + .previewDisplayName("Last refreshed with date") + } + .previewLayout(.sizeThatFits) + } +} diff --git a/Multiplatform/Shared/Sidebar/SidebarToolbar.swift b/Multiplatform/Shared/Sidebar/SidebarToolbar.swift index 90d4a7e39..375d719d7 100644 --- a/Multiplatform/Shared/Sidebar/SidebarToolbar.swift +++ b/Multiplatform/Shared/Sidebar/SidebarToolbar.swift @@ -43,10 +43,8 @@ struct SidebarToolbar: View { }).help("Settings") Spacer() - - Text("Last updated") - .font(.caption) - .foregroundColor(.secondary) + + RefreshProgressView() Spacer() @@ -87,6 +85,19 @@ struct SidebarToolbar: View { struct SidebarToolbar_Previews: PreviewProvider { static var previews: some View { - SidebarToolbar() + Group { + SidebarToolbar() + .environmentObject(refreshProgressModel(lastRefreshDate: nil, tasksCompleted: 1, totalTasks: 2)) + .previewDisplayName("Refresh in progress") + + SidebarToolbar() + .environmentObject(refreshProgressModel(lastRefreshDate: Date(timeIntervalSinceNow: -120.0), tasksCompleted: 0, totalTasks: 0)) + .previewDisplayName("Last refreshed with date") + + SidebarToolbar() + .environmentObject(refreshProgressModel(lastRefreshDate: nil, tasksCompleted: 0, totalTasks: 0)) + .previewDisplayName("Refresh progress hidden") + } + .previewLayout(.sizeThatFits) } } diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index bdb2dc841..e952512cd 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -1023,6 +1023,12 @@ FF3ABF13232599810074C542 /* ArticleSorterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF09232599450074C542 /* ArticleSorterTests.swift */; }; FF3ABF1523259DDB0074C542 /* ArticleSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */; }; FF3ABF162325AF5D0074C542 /* ArticleSorter.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */; }; + FF64D0E724AF53EE0084080A /* RefreshProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF64D0C424AF53EE0084080A /* RefreshProgressModel.swift */; }; + FF64D0E824AF53EE0084080A /* RefreshProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF64D0C424AF53EE0084080A /* RefreshProgressModel.swift */; }; + FF64D0E924AF53EE0084080A /* RefreshProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF64D0E624AF53EE0084080A /* RefreshProgressView.swift */; }; + FF64D0EA24AF53EE0084080A /* RefreshProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF64D0E624AF53EE0084080A /* RefreshProgressView.swift */; }; + FFA2BBD624AF751100B3149D /* PreviewProvider+RefreshProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA2BBD524AF751100B3149D /* PreviewProvider+RefreshProgressModel.swift */; }; + FFA2BBD724AF751100B3149D /* PreviewProvider+RefreshProgressModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA2BBD524AF751100B3149D /* PreviewProvider+RefreshProgressModel.swift */; }; FFD43E412340F488009E5CA3 /* MarkAsReadAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFD43E372340F320009E5CA3 /* MarkAsReadAlertController.swift */; }; /* End PBXBuildFile section */ @@ -2211,6 +2217,9 @@ DD82AB09231003F6002269DF /* SharingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharingTests.swift; sourceTree = ""; }; FF3ABF09232599450074C542 /* ArticleSorterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorterTests.swift; sourceTree = ""; }; FF3ABF1423259DDB0074C542 /* ArticleSorter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleSorter.swift; sourceTree = ""; }; + FF64D0C424AF53EE0084080A /* RefreshProgressModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshProgressModel.swift; sourceTree = ""; }; + FF64D0E624AF53EE0084080A /* RefreshProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshProgressView.swift; sourceTree = ""; }; + FFA2BBD524AF751100B3149D /* PreviewProvider+RefreshProgressModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PreviewProvider+RefreshProgressModel.swift"; sourceTree = ""; }; FFD43E372340F320009E5CA3 /* MarkAsReadAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkAsReadAlertController.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -2573,6 +2582,7 @@ isa = PBXGroup; children = ( 514E6BFE24AD255D00AC6F6E /* PreviewArticles.swift */, + FFA2BBD524AF751100B3149D /* PreviewProvider+RefreshProgressModel.swift */, ); path = Previews; sourceTree = ""; @@ -2957,6 +2967,8 @@ isa = PBXGroup; children = ( 172952AF24AA287100D65E66 /* CompactSidebarContainerView.swift */, + FF64D0C424AF53EE0084080A /* RefreshProgressModel.swift */, + FF64D0E624AF53EE0084080A /* RefreshProgressView.swift */, 51E499FF24A91FC100B667CB /* RegularSidebarContainerView.swift */, 51392D1A24AC19A000BE0D35 /* SidebarExpandedContainers.swift */, 51408B7D24A9EC6F0073CF4E /* SidebarItem.swift */, @@ -4801,6 +4813,7 @@ 51392D1B24AC19A000BE0D35 /* SidebarExpandedContainers.swift in Sources */, 51E4992F24A8676400B667CB /* ArticleArray.swift in Sources */, 51E498F824A8085D00B667CB /* UnreadFeed.swift in Sources */, + FF64D0E724AF53EE0084080A /* RefreshProgressModel.swift in Sources */, 51E4996A24A8762D00B667CB /* ExtractedArticle.swift in Sources */, 51919FF124AB864A00541E64 /* TimelineModel.swift in Sources */, 51E498F124A8085D00B667CB /* StarredFeedDelegate.swift in Sources */, @@ -4841,6 +4854,7 @@ 51E49A0324A91FF600B667CB /* SceneNavigationView.swift in Sources */, 51E4990124A808BB00B667CB /* FaviconURLFinder.swift in Sources */, 51E4991D24A8092100B667CB /* NSAttributedString+NetNewsWire.swift in Sources */, + FF64D0E924AF53EE0084080A /* RefreshProgressView.swift in Sources */, 51E499FD24A9137600B667CB /* SidebarModel.swift in Sources */, 51A576BE24AE637400078888 /* ArticleView.swift in Sources */, 51E4995324A8734D00B667CB /* RedditFeedProvider-Extensions.swift in Sources */, @@ -4887,6 +4901,7 @@ 51E4993D24A870F800B667CB /* UserNotificationManager.swift in Sources */, 51E4991524A808FF00B667CB /* ArticleStringFormatter.swift in Sources */, 51919FEE24AB85E400541E64 /* TimelineContainerView.swift in Sources */, + FFA2BBD624AF751100B3149D /* PreviewProvider+RefreshProgressModel.swift in Sources */, 51E4995724A8734D00B667CB /* ExtensionPoint.swift in Sources */, 1776E88E24AC5F8A00E78166 /* AppDefaults.swift in Sources */, 51E4991124A808DE00B667CB /* SmallIconProvider.swift in Sources */, @@ -4943,6 +4958,7 @@ 51E498C924A8085D00B667CB /* PseudoFeed.swift in Sources */, 51E498FC24A808BA00B667CB /* FaviconURLFinder.swift in Sources */, 51E4991C24A8092000B667CB /* NSAttributedString+NetNewsWire.swift in Sources */, + FF64D0E824AF53EE0084080A /* RefreshProgressModel.swift in Sources */, 51E499D924A912C200B667CB /* SceneModel.swift in Sources */, 51919FB424AAB97900541E64 /* FeedIconImageLoader.swift in Sources */, 51E4994A24A8734C00B667CB /* ExtensionPointManager.swift in Sources */, @@ -4987,10 +5003,12 @@ 514E6C0024AD255D00AC6F6E /* PreviewArticles.swift in Sources */, 1729529524AA1CAA00D65E66 /* GeneralPreferencesView.swift in Sources */, 1729529424AA1CAA00D65E66 /* AdvancedPreferencesView.swift in Sources */, + FFA2BBD724AF751100B3149D /* PreviewProvider+RefreshProgressModel.swift in Sources */, 51E4992D24A8676300B667CB /* FetchRequestOperation.swift in Sources */, 51E4992424A8098400B667CB /* SmartFeedPasteboardWriter.swift in Sources */, 51E4991424A808FF00B667CB /* ArticleStringFormatter.swift in Sources */, 51A576BF24AE637400078888 /* ArticleView.swift in Sources */, + FF64D0EA24AF53EE0084080A /* RefreshProgressView.swift in Sources */, 51E4991024A808DE00B667CB /* SmallIconProvider.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; From 03f28a4d98964428ddf89c811de4b4a43b5afdff Mon Sep 17 00:00:00 2001 From: Phil Viso Date: Sat, 4 Jul 2020 09:10:06 -0500 Subject: [PATCH 3/6] Fixed crash as a result of mismatched asset name --- Multiplatform/Shared/AppAssets.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Multiplatform/Shared/AppAssets.swift b/Multiplatform/Shared/AppAssets.swift index 3ca181288..05e7e4699 100644 --- a/Multiplatform/Shared/AppAssets.swift +++ b/Multiplatform/Shared/AppAssets.swift @@ -69,7 +69,7 @@ struct AppAssets { }() static var faviconTemplateImage: RSImage = { - return RSImage(named: "FaviconTemplateImage")! + return RSImage(named: "faviconTemplateImage")! }() static var settingsImage: Image = { From 16e7b23425057cf68ce756f93aa291c6ddb04529 Mon Sep 17 00:00:00 2001 From: Phil Viso Date: Sat, 4 Jul 2020 09:20:51 -0500 Subject: [PATCH 4/6] Fixed merge conflict --- Multiplatform/Shared/Sidebar/SidebarToolbar.swift | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Multiplatform/Shared/Sidebar/SidebarToolbar.swift b/Multiplatform/Shared/Sidebar/SidebarToolbar.swift index 77d6a5799..bdee3a887 100644 --- a/Multiplatform/Shared/Sidebar/SidebarToolbar.swift +++ b/Multiplatform/Shared/Sidebar/SidebarToolbar.swift @@ -8,7 +8,6 @@ import SwiftUI - struct SidebarToolbar: ViewModifier { @EnvironmentObject private var appSettings: AppDefaults @@ -30,11 +29,7 @@ struct SidebarToolbar: ViewModifier { } ToolbarItem(placement: .automatic, content: { - Spacer() - Text("Last updated") - .font(.caption) - .foregroundColor(.secondary) - Spacer() + RefreshProgressView() }) ToolbarItem(placement: .automatic, content: { From 299f3d421efa833da93678cb16d2541654472f8d Mon Sep 17 00:00:00 2001 From: Phil Viso Date: Sat, 4 Jul 2020 09:34:56 -0500 Subject: [PATCH 5/6] Fixed refresh progress label truncating --- Multiplatform/Shared/Sidebar/SidebarToolbar.swift | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Multiplatform/Shared/Sidebar/SidebarToolbar.swift b/Multiplatform/Shared/Sidebar/SidebarToolbar.swift index bdee3a887..fd8ee3188 100644 --- a/Multiplatform/Shared/Sidebar/SidebarToolbar.swift +++ b/Multiplatform/Shared/Sidebar/SidebarToolbar.swift @@ -24,19 +24,25 @@ struct SidebarToolbar: ViewModifier { AppAssets.settingsImage .font(.title3) .foregroundColor(.accentColor) - Spacer() }).help("Settings") } - ToolbarItem(placement: .automatic, content: { + ToolbarItem { + Spacer() + } + + ToolbarItem(placement: .automatic) { RefreshProgressView() - }) + } + + ToolbarItem { + Spacer() + } ToolbarItem(placement: .automatic, content: { Button(action: { viewModel.showActionSheet = true }, label: { - Spacer() AppAssets.addMenuImage .font(.title3) .foregroundColor(.accentColor) From 9131056f2b6928d4135742b4c56f636762f769ef Mon Sep 17 00:00:00 2001 From: Phil Viso Date: Sat, 4 Jul 2020 10:20:50 -0500 Subject: [PATCH 6/6] Added refreshProgressState to SceneModel. Removed RefreshProgressModel from environment --- Multiplatform/Shared/MainApp.swift | 3 --- .../Shared/{Sidebar => }/RefreshProgressModel.swift | 0 Multiplatform/Shared/SceneModel.swift | 9 +++++++++ Multiplatform/Shared/Sidebar/RefreshProgressView.swift | 4 ++-- NetNewsWire.xcodeproj/project.pbxproj | 2 +- 5 files changed, 12 insertions(+), 6 deletions(-) rename Multiplatform/Shared/{Sidebar => }/RefreshProgressModel.swift (100%) diff --git a/Multiplatform/Shared/MainApp.swift b/Multiplatform/Shared/MainApp.swift index c38e40a84..1be5b3720 100644 --- a/Multiplatform/Shared/MainApp.swift +++ b/Multiplatform/Shared/MainApp.swift @@ -19,7 +19,6 @@ struct MainApp: App { #endif @StateObject private var sceneModel = SceneModel() - @StateObject private var refreshProgresModel = RefreshProgressModel() @StateObject private var defaults = AppDefaults.shared @State private var showSheet = false @@ -29,7 +28,6 @@ struct MainApp: App { SceneNavigationView() .frame(minWidth: 600, idealWidth: 1000, maxWidth: .infinity, minHeight: 600, idealHeight: 700, maxHeight: .infinity) .environmentObject(sceneModel) - .environmentObject(refreshProgresModel) .environmentObject(defaults) .sheet(isPresented: $showSheet, onDismiss: { showSheet = false }) { AddWebFeedView() @@ -155,7 +153,6 @@ struct MainApp: App { WindowGroup { SceneNavigationView() .environmentObject(sceneModel) - .environmentObject(refreshProgresModel) .environmentObject(defaults) .modifier(PreferredColorSchemeModifier(preferredColorScheme: defaults.userInterfaceColorPalette)) } diff --git a/Multiplatform/Shared/Sidebar/RefreshProgressModel.swift b/Multiplatform/Shared/RefreshProgressModel.swift similarity index 100% rename from Multiplatform/Shared/Sidebar/RefreshProgressModel.swift rename to Multiplatform/Shared/RefreshProgressModel.swift diff --git a/Multiplatform/Shared/SceneModel.swift b/Multiplatform/Shared/SceneModel.swift index e199ac11c..99071215f 100644 --- a/Multiplatform/Shared/SceneModel.swift +++ b/Multiplatform/Shared/SceneModel.swift @@ -11,10 +11,19 @@ import Account final class SceneModel: ObservableObject { + @Published var refreshProgressState = RefreshProgressModel.State.none + var sidebarModel: SidebarModel? var timelineModel: TimelineModel? var articleModel: ArticleModel? + private let refreshProgressModel: RefreshProgressModel + + init(refreshProgressModel: RefreshProgressModel = RefreshProgressModel()) { + self.refreshProgressModel = refreshProgressModel + self.refreshProgressModel.$state.assign(to: self.$refreshProgressState) + } + } // MARK: SidebarModelDelegate diff --git a/Multiplatform/Shared/Sidebar/RefreshProgressView.swift b/Multiplatform/Shared/Sidebar/RefreshProgressView.swift index 4e776463e..410713b94 100644 --- a/Multiplatform/Shared/Sidebar/RefreshProgressView.swift +++ b/Multiplatform/Shared/Sidebar/RefreshProgressView.swift @@ -10,10 +10,10 @@ import SwiftUI struct RefreshProgressView: View { - @EnvironmentObject var refreshProgressModel: RefreshProgressModel + @EnvironmentObject var sceneModel: SceneModel @ViewBuilder var body: some View { - switch refreshProgressModel.state { + switch sceneModel.refreshProgressState { case .refreshProgress(let progress): ProgressView(value: progress) .frame(width: progressViewWidth()) diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index 323884e32..0ab75b585 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -2791,6 +2791,7 @@ 1776E88D24AC5F8A00E78166 /* AppDefaults.swift */, 51E4995824A873F900B667CB /* ErrorHandler.swift */, 51C0513624A77DF700194D5E /* MainApp.swift */, + FF64D0C424AF53EE0084080A /* RefreshProgressModel.swift */, 51E499D724A912C200B667CB /* SceneModel.swift */, 51E49A0224A91FF600B667CB /* SceneNavigationView.swift */, 51C0513824A77DF800194D5E /* Assets.xcassets */, @@ -2978,7 +2979,6 @@ isa = PBXGroup; children = ( 172952AF24AA287100D65E66 /* CompactSidebarContainerView.swift */, - FF64D0C424AF53EE0084080A /* RefreshProgressModel.swift */, FF64D0E624AF53EE0084080A /* RefreshProgressView.swift */, 51E499FF24A91FC100B667CB /* RegularSidebarContainerView.swift */, 51392D1A24AC19A000BE0D35 /* SidebarExpandedContainers.swift */,