| | |
| | | require(preferences, "private var settingsFixedProHeader: some View", "Settings pages must share one fixed-position Pro guidance header") |
| | | require(preferences, "private var settingsProHeaderText: String", "fixed Pro guidance header must switch copy by selected tab") |
| | | require(preferences, "private var settingsProHeaderFeature: ProFeature", "fixed Pro guidance header must route unlock prompts by selected tab") |
| | | require(preferences, "private var shouldShowSettingsFixedProHeader: Bool", "Language/About tabs must be able to hide the fixed Pro header") |
| | | require(preferences, "selectedTab != .language && selectedTab != .about", "fixed Pro header must be hidden on Language and About tabs") |
| | | require(preferences, "private var shouldCenterUnlockedIdentityHeader: Bool", "Language/Pro/About tabs need the centered unlocked Pro identity header") |
| | | center_identity_body = function_body(preferences, "private var shouldCenterUnlockedIdentityHeader: Bool") |
| | | require(center_identity_body, "guard proEntitlement.isUnlocked else { return false }", "centered Pro identity header must only apply after Pro unlock") |
| | | require(center_identity_body, "case .language, .pro, .about:", "centered Pro identity header must apply to Language, Pro, and About tabs") |
| | | require(center_identity_body, "case .general, .theme, .hotkeys, .tags, .data:", "centered Pro identity header must not affect the feature-specific settings tabs") |
| | | settings_header_text_body = function_body(preferences, "private var settingsProHeaderText: String") |
| | | require(settings_header_text_body, "case .language, .about:", "Language/About tabs must have an explicit fixed-header text branch") |
| | | require(settings_header_text_body, 'return ""', "Language/About tabs must not show the general Pro guidance sentence") |
| | | if "case .general, .language, .about:" in settings_header_text_body: |
| | | fail("Language/About tabs must not reuse the General tab Pro guidance sentence") |
| | | require(preferences, "private func proHeaderStatusLabel(compact: Bool = false) -> some View", "fixed Pro guidance header must render the free status as plain text") |
| | | require(preferences, 'Text(tr("settings.proStatus.freeUser"))', "Free status must render as the full current-user sentence instead of a Free pill") |
| | | require(preferences, "private var shouldShowSettingsFixedProHeader: Bool", "all settings tabs must use the fixed Pro header gate") |
| | | require(function_body(preferences, "private var shouldShowSettingsFixedProHeader: Bool"), "true", "fixed Pro header must be shown on Language and About tabs too") |
| | | if "selectedTab != .language && selectedTab != .about" in preferences: |
| | | fail("fixed Pro header must no longer be hidden on Language and About tabs") |
| | | require(preferences, "if shouldShowSettingsFixedProHeader", "Settings body must conditionally render the fixed Pro header") |
| | | fixed_header_body = function_body(preferences, "private var settingsFixedProHeader: some View") |
| | | require(fixed_header_body, "if shouldCenterUnlockedIdentityHeader", "fixed Pro header must use the centered unlocked identity branch") |
| | | require(fixed_header_body, 'text: tr("pro.status.unlocked")', "centered Pro identity header must start with the Pro unlocked pill") |
| | | require(fixed_header_body, "style: .unlocked", "centered Pro identity pill must use the unlocked style") |
| | | require(fixed_header_body, 'Text(tr("settings.proStatus.proUser"))', "centered Pro identity header must render the current Pro user sentence") |
| | | if fixed_header_body.find("if shouldCenterUnlockedIdentityHeader") > fixed_header_body.find('Text(tr("settings.proStatus.proUser"))'): |
| | | fail("centered Pro identity sentence must be inside the centered branch") |
| | | if fixed_header_body.count("Spacer(minLength: 0)") < 2: |
| | | fail("centered Pro identity header must be horizontally centered with leading and trailing spacers") |
| | | require(fixed_header_body, "if !proEntitlement.isUnlocked", "fixed Pro header must branch on unlocked state") |
| | | require(fixed_header_body, 'Button(tr("pro.card.restore"))', "fixed Pro header must keep restore purchase for free users") |
| | | if fixed_header_body.find("if !proEntitlement.isUnlocked") > fixed_header_body.find('Button(tr("pro.card.restore"))'): |
| | |
| | | require(preferences, 'selectedTab == .pro', "fixed Pro header must render the Pro tab user status state") |
| | | require(preferences, "proTabComparisonTable(width: dataPanelWidth)", "Pro tab must render the Free-vs-Pro comparison table") |
| | | require(preferences, "private struct ProTabComparisonFeature", "Pro tab comparison row model is missing") |
| | | comparison_body = function_body(preferences, "private func proTabComparisonTable(width: CGFloat)") |
| | | if comparison_body.count(".frame(width: 118, alignment: .leading)") < 4: |
| | | fail("Pro comparison Free/Pro columns and status chips must be left-aligned") |
| | | if ".frame(width: 118, alignment: .center)" in comparison_body: |
| | | fail("Pro comparison status columns must not be centered") |
| | | if 'Text(tr("settings.proCompare.title"))' in preferences: |
| | | fail("Pro tab comparison table must not render the removed title") |
| | | require(preferences, 'Text(tr("settings.proCompare.free"))', "Pro tab comparison table free column is missing") |