From 9f22053fa9ba32a7a939b2b6482b4e5d0a61450b Mon Sep 17 00:00:00 2001 From: Davide Date: Thu, 31 Oct 2024 11:14:39 +0100 Subject: [PATCH] Fix lifecycle of environment objects (#790) #779 was happening because environment objects were set on contentView, which is not the _outmost_ root view. This clarifies why the Theme object was not being found in ThemeLockScreenModifier. Also, do not hardcode LogoView as lock view. --- Passepartout/App/PassepartoutApp.swift | 1 - Passepartout/App/Platforms/App+iOS.swift | 3 ++- Passepartout/App/Platforms/App+macOS.swift | 2 ++ Passepartout/App/Platforms/App+tvOS.swift | 5 ++++- .../Sources/AppUI/Theme/Theme+UI.swift | 20 ++++++++++--------- .../Library/Sources/AppUI/Theme/Theme.swift | 4 ++-- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/Passepartout/App/PassepartoutApp.swift b/Passepartout/App/PassepartoutApp.swift index c7801b5b..0f97d564 100644 --- a/Passepartout/App/PassepartoutApp.swift +++ b/Passepartout/App/PassepartoutApp.swift @@ -86,6 +86,5 @@ extension PassepartoutApp { break } } - .withEnvironment(from: context, theme: theme) } } diff --git a/Passepartout/App/Platforms/App+iOS.swift b/Passepartout/App/Platforms/App+iOS.swift index 12ff2149..397768a1 100644 --- a/Passepartout/App/Platforms/App+iOS.swift +++ b/Passepartout/App/Platforms/App+iOS.swift @@ -42,7 +42,8 @@ extension PassepartoutApp { .onOpenURL { url in ImporterPipe.shared.send([url]) } - .themeLockScreen(theme) + .themeLockScreen() + .withEnvironment(from: context, theme: theme) } } } diff --git a/Passepartout/App/Platforms/App+macOS.swift b/Passepartout/App/Platforms/App+macOS.swift index fcd267f0..164b32d7 100644 --- a/Passepartout/App/Platforms/App+macOS.swift +++ b/Passepartout/App/Platforms/App+macOS.swift @@ -73,10 +73,12 @@ extension PassepartoutApp { var body: some Scene { Window(appName, id: appName, content: contentView) .defaultSize(width: 600, height: 400) + .withEnvironment(from: context, theme: theme) Settings { SettingsView(profileManager: context.profileManager) .frame(minWidth: 300, minHeight: 200) + .withEnvironment(from: context, theme: theme) } MenuBarExtra { AppMenu() diff --git a/Passepartout/App/Platforms/App+tvOS.swift b/Passepartout/App/Platforms/App+tvOS.swift index f3eccb92..5997d643 100644 --- a/Passepartout/App/Platforms/App+tvOS.swift +++ b/Passepartout/App/Platforms/App+tvOS.swift @@ -37,7 +37,10 @@ extension AppDelegate: UIApplicationDelegate { extension PassepartoutApp { var body: some Scene { - WindowGroup(content: contentView) + WindowGroup { + contentView() + .withEnvironment(from: context, theme: theme) + } } } diff --git a/Passepartout/Library/Sources/AppUI/Theme/Theme+UI.swift b/Passepartout/Library/Sources/AppUI/Theme/Theme+UI.swift index 6d8f4421..7b892394 100644 --- a/Passepartout/Library/Sources/AppUI/Theme/Theme+UI.swift +++ b/Passepartout/Library/Sources/AppUI/Theme/Theme+UI.swift @@ -68,7 +68,7 @@ struct ThemeBooleanModalModifier: ViewModifier where Modal: View { modal() .frame(minWidth: modalSize?.width, minHeight: modalSize?.height) .interactiveDismissDisabled(!isInteractive) - .themeLockScreen(theme) + .themeLockScreen() } } @@ -97,7 +97,7 @@ struct ThemeItemModalModifier: ViewModifier where Modal: View, T: Iden modal($0) .frame(minWidth: modalSize?.width, minHeight: modalSize?.height) .interactiveDismissDisabled(!isInteractive) - .themeLockScreen(theme) + .themeLockScreen() } } @@ -129,13 +129,13 @@ struct ThemeBooleanPopoverModifier: ViewModifier, SizeClassProviding wh .popover(isPresented: $isPresented) { popover .frame(minWidth: theme.popoverSize?.width, minHeight: theme.popoverSize?.height) - .themeLockScreen(theme) + .themeLockScreen() } } else { content .sheet(isPresented: $isPresented) { popover - .themeLockScreen(theme) + .themeLockScreen() } } } @@ -319,13 +319,16 @@ struct ThemeHoverListRowModifier: ViewModifier { } } -struct ThemeLockScreenModifier: ViewModifier { +struct ThemeLockScreenModifier: ViewModifier where LockedContent: View { @AppStorage(AppPreference.locksInBackground.key) private var locksInBackground = false - @ObservedObject - var theme: Theme + @EnvironmentObject + private var theme: Theme + + @ViewBuilder + let lockedContent: () -> LockedContent func body(content: Content) -> some View { LockableView( @@ -333,10 +336,9 @@ struct ThemeLockScreenModifier: ViewModifier { content: { content }, - lockedContent: LogoView.init, + lockedContent: lockedContent, unlockBlock: Self.unlockScreenBlock ) - .environmentObject(theme) } private static func unlockScreenBlock() async -> Bool { diff --git a/Passepartout/Library/Sources/AppUI/Theme/Theme.swift b/Passepartout/Library/Sources/AppUI/Theme/Theme.swift index 4323849c..b084a961 100644 --- a/Passepartout/Library/Sources/AppUI/Theme/Theme.swift +++ b/Passepartout/Library/Sources/AppUI/Theme/Theme.swift @@ -209,8 +209,8 @@ extension View { modifier(ThemeHoverListRowModifier()) } - public func themeLockScreen(_ theme: Theme) -> some View { - modifier(ThemeLockScreenModifier(theme: theme)) + public func themeLockScreen() -> some View { + modifier(ThemeLockScreenModifier(lockedContent: LogoView.init)) } public func themeTip(_ text: String, edge: Edge) -> some View {