From 3760058bf5d230232384bb8213bc3296c4acb33c Mon Sep 17 00:00:00 2001 From: Bugen Zhao Date: Tue, 4 Nov 2025 21:50:35 +0800 Subject: [PATCH] use default value when not unlocked Signed-off-by: Bugen Zhao --- app/Shared/Storage/PreferencesStorage.swift | 101 +++++++++++++++++--- app/Shared/Views/PreferencesView.swift | 47 ++++++--- 2 files changed, 121 insertions(+), 27 deletions(-) diff --git a/app/Shared/Storage/PreferencesStorage.swift b/app/Shared/Storage/PreferencesStorage.swift index 4472c841..5721084a 100644 --- a/app/Shared/Storage/PreferencesStorage.swift +++ b/app/Shared/Storage/PreferencesStorage.swift @@ -11,22 +11,26 @@ import SwiftUI import SwiftUIX class PreferencesStorage: ObservableObject { + private var unlocked: Bool { + PaywallModel.shared.isUnlocked + } + @Published var showing = false static let shared = PreferencesStorage() - @AppStorage("showSignatureNew") var showSignature = false - @AppStorage("showAvatar") var showAvatar = true + @AppStorage("showSignatureNew") var showSignatureInner = false + @AppStorage("showAvatar") var showAvatarInner = true @AppStorage("usePaginatedDetails") var usePaginatedDetails = false @AppStorage("useInAppSafari") var useInAppSafari = true @AppStorage("defaultTopicListOrder") var defaultTopicListOrder = TopicListRequest.Order.lastPost @AppStorage("topicListHideBlocked") var topicListHideBlocked = false @AppStorage("topicListShowRefreshButton") var topicListShowRefreshButton = true - @AppStorage("themeColorNew") var themeColor = ThemeColor.mnga + @AppStorage("themeColorNew") var themeColorInner = ThemeColor.mnga @AppStorage("colorScheme") var colorScheme = ColorSchemeMode.auto - @AppStorage("useInsetGroupedModern") var useInsetGroupedModern = true + @AppStorage("useInsetGroupedModern") var useInsetGroupedModernInner = true @AppStorage("hideMNGAMeta") var hideMNGAMeta = false - @AppStorage("showPlusInTitle") var showPlusInTitle = false + @AppStorage("showPlusInTitle") var showPlusInTitleInner = false @AppStorage("requestOption") var requestOptionWrapper = WrappedMessage(inner: RequestOption()) { didSet { syncRequestOptionWithLogic() } @@ -37,19 +41,90 @@ class PreferencesStorage: ObservableObject { set { requestOptionWrapper.inner = newValue } } - @AppStorage("postRowSwipeActionLeading") var postRowSwipeActionLeading = false - @AppStorage("postRowSwipeVoteFirst") var postRowSwipeVoteFirst = false - @AppStorage("postRowShowUserDetails") var postRowShowUserDetails = true - @AppStorage("postRowShowUserRegDate") var postRowShowUserRegDate = false - @AppStorage("postRowDateTimeStrategy") var postRowDateTimeStrategy = DateTimeTextView.Strategy.automatic - @AppStorage("postRowShowAuthorIndicator") var postRowShowAuthorIndicator = true + @AppStorage("postRowSwipeActionLeading") var postRowSwipeActionLeadingInner = false + @AppStorage("postRowSwipeVoteFirst") var postRowSwipeVoteFirstInner = false + @AppStorage("postRowShowUserDetails") var postRowShowUserDetailsInner = true + @AppStorage("postRowShowUserRegDate") var postRowShowUserRegDateInner = false + @AppStorage("postRowDateTimeStrategy") var postRowDateTimeStrategyInner = DateTimeTextView.Strategy.automatic + @AppStorage("postRowShowAuthorIndicator") var postRowShowAuthorIndicatorInner = true @AppStorage("postRowLargerFont") var postRowLargerFont = false - @AppStorage("postRowDimImagesInDarkMode") var postRowDimImagesInDarkMode = false + @AppStorage("postRowDimImagesInDarkMode") var postRowDimImagesInDarkModeInner = false @AppStorage("postRowImageScale") var postRowImageScale = ContentImageScale.fullSize - @AppStorage("resumeTopicFrom") var resumeTopicFrom = TopicResumeFrom.none + @AppStorage("resumeTopicFrom") var resumeTopicFromInner = TopicResumeFrom.none @AppStorage("autoOpenInBrowserWhenBannedNew") var autoOpenInBrowserWhenBanned = false + // MARK: - Paywalled Preferences + + private func paywalledValue(_ value: Value, default defaultValue: Value) -> Value { + unlocked ? value : defaultValue + } + + var postRowSwipeActionLeading: Bool { + get { paywalledValue(postRowSwipeActionLeadingInner, default: false) } + set { postRowSwipeActionLeadingInner = newValue } + } + + var postRowSwipeVoteFirst: Bool { + get { paywalledValue(postRowSwipeVoteFirstInner, default: false) } + set { postRowSwipeVoteFirstInner = newValue } + } + + var postRowDateTimeStrategy: DateTimeTextView.Strategy { + get { paywalledValue(postRowDateTimeStrategyInner, default: .automatic) } + set { postRowDateTimeStrategyInner = newValue } + } + + var showSignature: Bool { + get { paywalledValue(showSignatureInner, default: false) } + set { showSignatureInner = newValue } + } + + var showAvatar: Bool { + get { paywalledValue(showAvatarInner, default: true) } + set { showAvatarInner = newValue } + } + + var postRowShowAuthorIndicator: Bool { + get { paywalledValue(postRowShowAuthorIndicatorInner, default: true) } + set { postRowShowAuthorIndicatorInner = newValue } + } + + var postRowShowUserDetails: Bool { + get { paywalledValue(postRowShowUserDetailsInner, default: true) } + set { postRowShowUserDetailsInner = newValue } + } + + var postRowShowUserRegDate: Bool { + get { paywalledValue(postRowShowUserRegDateInner, default: false) } + set { postRowShowUserRegDateInner = newValue } + } + + var postRowDimImagesInDarkMode: Bool { + get { paywalledValue(postRowDimImagesInDarkModeInner, default: false) } + set { postRowDimImagesInDarkModeInner = newValue } + } + + var themeColor: ThemeColor { + get { paywalledValue(themeColorInner, default: .mnga) } + set { themeColorInner = newValue } + } + + var useInsetGroupedModern: Bool { + get { paywalledValue(useInsetGroupedModernInner, default: true) } + set { useInsetGroupedModernInner = newValue } + } + + var resumeTopicFrom: TopicResumeFrom { + get { paywalledValue(resumeTopicFromInner, default: .none) } + set { resumeTopicFromInner = newValue } + } + + var showPlusInTitle: Bool { + get { paywalledValue(showPlusInTitleInner, default: false) } + set { showPlusInTitleInner = newValue } + } + // MARK: - Debug @AppStorage("debugResetTips") var debugResetTips = false diff --git a/app/Shared/Views/PreferencesView.swift b/app/Shared/Views/PreferencesView.swift index f238c099..a0f0389b 100644 --- a/app/Shared/Views/PreferencesView.swift +++ b/app/Shared/Views/PreferencesView.swift @@ -24,39 +24,58 @@ private struct PostRowAppearanceView: View { .tint(nil) // remove accent color for swipe actions Section { - Picker(selection: $pref.postRowSwipeActionLeading, label: Label("Swipe Trigger Edge", systemImage: "rectangle.portrait.arrowtriangle.2.outward")) { + Picker( + selection: $pref.postRowSwipeActionLeadingInner, + label: Label("Swipe Trigger Edge", systemImage: "rectangle.portrait.arrowtriangle.2.outward") + ) { Text("Leading").tag(true) Text("Trailing").tag(false) } - Picker(selection: $pref.postRowSwipeVoteFirst, label: Label("Primary Swipe Action", systemImage: "smallcircle.filled.circle")) { + Picker( + selection: $pref.postRowSwipeVoteFirstInner, + label: Label("Primary Swipe Action", systemImage: "smallcircle.filled.circle") + ) { Text("Vote Up").tag(true) Text("Quote").tag(false) } }.disableWithPlusCheck(.customAppearance) Section { - Picker(selection: $pref.postRowDateTimeStrategy.animation(), label: Label("Date Display", systemImage: "calendar")) { + Picker( + selection: $pref.postRowDateTimeStrategyInner.animation(), + label: Label("Date Display", systemImage: "calendar") + ) { ForEach(DateTimeTextView.Strategy.allCases, id: \.self) { s in Text(s.description).tag(s) } } - Toggle(isOn: $pref.showSignature.animation()) { + Toggle( + isOn: $pref.showSignatureInner.animation() + ) { Label("Show Signature", systemImage: "signature") } - Toggle(isOn: $pref.showAvatar.animation()) { + Toggle( + isOn: $pref.showAvatarInner.animation() + ) { Label("Show Avatar", systemImage: "person.crop.circle") } - Toggle(isOn: $pref.postRowShowAuthorIndicator.animation()) { + Toggle( + isOn: $pref.postRowShowAuthorIndicatorInner.animation() + ) { Label("Show Author Indicator", systemImage: "person.fill") } - Toggle(isOn: $pref.postRowShowUserDetails.animation()) { + Toggle( + isOn: $pref.postRowShowUserDetailsInner.animation() + ) { Label("Show User Details", systemImage: "info.circle") } - if pref.postRowShowUserDetails { - Toggle(isOn: $pref.postRowShowUserRegDate.animation()) { + if pref.postRowShowUserDetailsInner { + Toggle( + isOn: $pref.postRowShowUserRegDateInner.animation() + ) { Label("Show User Register Date", systemImage: "calendar") } } @@ -74,7 +93,7 @@ private struct PostRowAppearanceView: View { Text(s.description).tag(s) } } - Toggle(isOn: $pref.postRowDimImagesInDarkMode) { + Toggle(isOn: $pref.postRowDimImagesInDarkModeInner) { Label("Dim Images in Dark Mode", systemImage: "moon.fill") } .disableWithPlusCheck(.customAppearance) @@ -127,7 +146,7 @@ struct PreferencesInnerView: View { NavigationLink(destination: PlusView()) { Label("Plus Unlocked", systemImage: "hands.and.sparkles") } - Toggle(isOn: $pref.showPlusInTitle) { + Toggle(isOn: $pref.showPlusInTitleInner) { Label("Show Plus in Title", systemImage: "sparkle") } } else { @@ -170,7 +189,7 @@ struct PreferencesInnerView: View { } } - Picker(selection: $pref.themeColor, label: Label("Theme Color", systemImage: "circle")) { + Picker(selection: $pref.themeColorInner, label: Label("Theme Color", systemImage: "circle")) { ForEach(ThemeColor.allCases, id: \.self) { color in Label(color.description, systemImage: "circle.fill") .tint(color.color) @@ -178,7 +197,7 @@ struct PreferencesInnerView: View { } }.disableWithPlusCheck(.customAppearance) - Picker(selection: $pref.useInsetGroupedModern, label: Label("List Style", systemImage: "list.bullet.rectangle.portrait")) { + Picker(selection: $pref.useInsetGroupedModernInner, label: Label("List Style", systemImage: "list.bullet.rectangle.portrait")) { Text("Compact").tag(false) Text("Modern").tag(true) }.disableWithPlusCheck(.customAppearance) @@ -196,7 +215,7 @@ struct PreferencesInnerView: View { Label("Topic Details Style", systemImage: "list.bullet.below.rectangle") } - Picker(selection: $pref.resumeTopicFrom) { + Picker(selection: $pref.resumeTopicFromInner) { Text("Disabled").tag(TopicResumeFrom.none) Text("Last Read Floor").tag(TopicResumeFrom.last) Text("Highest Read Floor").tag(TopicResumeFrom.highest)