From ca65f84137f67e7bd5e5e8b68c0156097e079806 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 21 Jul 2024 12:02:14 -0700 Subject: [PATCH] Lift pinned timelines modifiers up to CustomizeTimelinesList .sheet on a Section with a header does not work, and produces warnings about trying to present on a VC that already has a presentation. It seems like the .sheet modifier is being applied to both the Section content and header? Fixes #514 --- .../CustomizeTimelinesView.swift | 24 +++++- .../PinnedTimelinesView.swift | 86 ++++++++++--------- 2 files changed, 66 insertions(+), 44 deletions(-) diff --git a/Tusker/Screens/Customize Timelines/CustomizeTimelinesView.swift b/Tusker/Screens/Customize Timelines/CustomizeTimelinesView.swift index 84b96b465c..e7c32a6423 100644 --- a/Tusker/Screens/Customize Timelines/CustomizeTimelinesView.swift +++ b/Tusker/Screens/Customize Timelines/CustomizeTimelinesView.swift @@ -13,7 +13,7 @@ struct CustomizeTimelinesView: View { let mastodonController: MastodonController var body: some View { - CustomizeTimelinesList() + CustomizeTimelinesList(pinnedTimelines: mastodonController.accountPreferences.pinnedTimelines) .environmentObject(mastodonController) .environment(\.managedObjectContext, mastodonController.persistentContainer.viewContext) } @@ -26,7 +26,15 @@ struct CustomizeTimelinesList: View { @FetchRequest(sortDescriptors: []) private var filters: FetchedResults @Environment(\.dismiss) private var dismiss @State private var deletionError: (any Error)? + // store this separately from AccountPreferences in the view, b/c the @LazilyDecoding wrapper breaks animations + @State private var pinnedTimelines: [PinnedTimeline] + @State private var isShowingAddHashtagSheet = false + @State private var isShowingAddInstanceSheet = false + init(pinnedTimelines: [PinnedTimeline]) { + self.pinnedTimelines = pinnedTimelines + } + var body: some View { if #available(iOS 16.0, *) { NavigationStack { @@ -50,8 +58,12 @@ struct CustomizeTimelinesList: View { private var navigationBody: some View { List { - PinnedTimelinesView(accountPreferences: mastodonController.accountPreferences) - .appGroupedListRowBackground() + PinnedTimelinesView( + pinnedTimelines: $pinnedTimelines, + isShowingAddHashtagSheet: $isShowingAddHashtagSheet, + isShowingAddInstanceSheet: $isShowingAddInstanceSheet + ) + .appGroupedListRowBackground() Section { Toggle(isOn: $preferences.hideReblogsInTimelines) { @@ -99,6 +111,12 @@ struct CustomizeTimelinesList: View { } } } + .modifier(PinnedTimelinesModifier( + accountPreferences: mastodonController.accountPreferences, + pinnedTimelines: $pinnedTimelines, + isShowingAddHashtagSheet: $isShowingAddHashtagSheet, + isShowingAddInstanceSheet: $isShowingAddInstanceSheet + )) .alertWithData("Error Deleting Filter", data: $deletionError, actions: { _ in Button("OK") { self.deletionError = nil diff --git a/Tusker/Screens/Customize Timelines/PinnedTimelinesView.swift b/Tusker/Screens/Customize Timelines/PinnedTimelinesView.swift index 8bcff3cced..c355f285ba 100644 --- a/Tusker/Screens/Customize Timelines/PinnedTimelinesView.swift +++ b/Tusker/Screens/Customize Timelines/PinnedTimelinesView.swift @@ -11,17 +11,10 @@ import Pachyderm struct PinnedTimelinesView: View { @EnvironmentObject private var mastodonController: MastodonController - @ObservedObject private var accountPreferences: AccountPreferences - @State private var isShowingAddHashtagSheet = false - @State private var isShowingAddInstanceSheet = false - // store this separately from AccountPreferences in the view, b/c the @LazilyDecoding wrapper breaks animations - @State private var pinnedTimelines: [PinnedTimeline] - - init(accountPreferences: AccountPreferences) { - self.accountPreferences = accountPreferences - self.pinnedTimelines = accountPreferences.pinnedTimelines - } + @Binding var pinnedTimelines: [PinnedTimeline] + @Binding var isShowingAddHashtagSheet: Bool + @Binding var isShowingAddInstanceSheet: Bool var body: some View { Section { @@ -110,42 +103,53 @@ struct PinnedTimelinesView: View { } header: { Text("Pinned Timelines") } - .sheet(isPresented: $isShowingAddHashtagSheet, content: { - #if os(visionOS) - AddHashtagPinnedTimelineView(pinnedTimelines: $pinnedTimelines) - .edgesIgnoringSafeArea(.bottom) - #else - if #available(iOS 16.0, *) { + } +} + +struct PinnedTimelinesModifier: ViewModifier { + let accountPreferences: AccountPreferences + @Binding var pinnedTimelines: [PinnedTimeline] + @Binding var isShowingAddHashtagSheet: Bool + @Binding var isShowingAddInstanceSheet: Bool + + func body(content: Content) -> some View { + content + .sheet(isPresented: $isShowingAddHashtagSheet, content: { + #if os(visionOS) AddHashtagPinnedTimelineView(pinnedTimelines: $pinnedTimelines) .edgesIgnoringSafeArea(.bottom) - } else { - AddHashtagPinnedTimelineRepresentable(pinnedTimelines: $pinnedTimelines) + #else + if #available(iOS 16.0, *) { + AddHashtagPinnedTimelineView(pinnedTimelines: $pinnedTimelines) + .edgesIgnoringSafeArea(.bottom) + } else { + AddHashtagPinnedTimelineRepresentable(pinnedTimelines: $pinnedTimelines) + .edgesIgnoringSafeArea(.bottom) + } + #endif + }) + .sheet(isPresented: $isShowingAddInstanceSheet, content: { + AddInstancePinnedTimelineView(pinnedTimelines: $pinnedTimelines) .edgesIgnoringSafeArea(.bottom) + }) + .onReceive(accountPreferences.publisher(for: \.pinnedTimelinesData)) { _ in + if pinnedTimelines != accountPreferences.pinnedTimelines { + pinnedTimelines = accountPreferences.pinnedTimelines + } + } + #if os(visionOS) + .onChange(of: pinnedTimelines) { + if accountPreferences.pinnedTimelines != pinnedTimelines { + accountPreferences.pinnedTimelines = pinnedTimelines + } + } + #else + .onChange(of: pinnedTimelines) { newValue in + if accountPreferences.pinnedTimelines != newValue { + accountPreferences.pinnedTimelines = newValue + } } #endif - }) - .sheet(isPresented: $isShowingAddInstanceSheet, content: { - AddInstancePinnedTimelineView(pinnedTimelines: $pinnedTimelines) - .edgesIgnoringSafeArea(.bottom) - }) - .onReceive(accountPreferences.publisher(for: \.pinnedTimelinesData)) { _ in - if pinnedTimelines != accountPreferences.pinnedTimelines { - pinnedTimelines = accountPreferences.pinnedTimelines - } - } - #if os(visionOS) - .onChange(of: pinnedTimelines) { - if accountPreferences.pinnedTimelines != pinnedTimelines { - accountPreferences.pinnedTimelines = pinnedTimelines - } - } - #else - .onChange(of: pinnedTimelines) { newValue in - if accountPreferences.pinnedTimelines != newValue { - accountPreferences.pinnedTimelines = newValue - } - } - #endif } }