From d8f5caa2f7339e7444f97598260db935f74b1418 Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 4 Dec 2024 17:38:13 +0100 Subject: [PATCH] Improve "Purchased" view (#979) - Show eligible features first - Render ineligible features as secondary --- .../UILibrary/Views/About/PurchasedView.swift | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/Library/Sources/UILibrary/Views/About/PurchasedView.swift b/Library/Sources/UILibrary/Views/About/PurchasedView.swift index 1974146a..47511340 100644 --- a/Library/Sources/UILibrary/Views/About/PurchasedView.swift +++ b/Library/Sources/UILibrary/Views/About/PurchasedView.swift @@ -73,7 +73,14 @@ private extension PurchasedView { } var allFeatures: [AppFeature] { - AppFeature.allCases.sorted() + AppFeature.allCases.sorted { + let lRank = $0.rank(with: iapManager) + let rRank = $1.rank(with: iapManager) + if lRank != rRank { + return lRank < rRank + } + return $0 < $1 + } } } @@ -124,18 +131,41 @@ private extension PurchasedView { var featuresSection: some View { Group { ForEach(allFeatures, id: \.self) { feature in - HStack { - Text(feature.localizedDescription) - Spacer() - ThemeImage(iapManager.isEligible(for: feature) ? .marked : .close) - } - .scrollableOnTV() + FeatureView(text: feature.localizedDescription, isEligible: iapManager.isEligible(for: feature)) + .scrollableOnTV() } } .themeSection(header: Strings.Views.Purchased.Sections.Features.header) } } +private struct FeatureView: View { + let text: String + + let isEligible: Bool + + var body: some View { + HStack { + Text(text) + Spacer() + ThemeImage(isEligible ? .marked : .close) + } + .foregroundStyle(isEligible ? .primary : .secondary) + } +} + +// MARK: - + +private extension AppFeature { + + @MainActor + func rank(with iapManager: IAPManager) -> Int { + iapManager.isEligible(for: self) ? 0 : 1 + } +} + +// MARK: - Previews + #Preview { PurchasedView() .withMockEnvironment()