From d76f5d61a7463dee1600d6b40eb85cabfa75a914 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Tue, 07 Jul 2026 12:55:37 +0800
Subject: [PATCH] release: prepare 8.3.6 settings header update

---
 C1.source/Apptag/Info.plist                                                  |    4 +-
 C1.source/Apptag/ProEntitlement.swift                                        |    5 --
 C1.source/CHANGELOG.md                                                       |    6 +++
 C1.source/Docs/Requirements/2026-07-07-settings-pro-header-border-removal.md |   28 ++++++++++++++
 C1.source/Scripts/pro_feature_gate_qa.sh                                     |    4 ++
 C1.source/Apptag/ContentView.swift                                           |    8 ++++
 C1.source/Apptag/PreferencesView.swift                                       |    8 ----
 CODEGRAPH.md                                                                 |    6 +-
 8 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/C1.source/Apptag/ContentView.swift b/C1.source/Apptag/ContentView.swift
index e3a6fe9..b1ca582 100644
--- a/C1.source/Apptag/ContentView.swift
+++ b/C1.source/Apptag/ContentView.swift
@@ -583,6 +583,10 @@
     }
 
     var body: some View {
+        contentWithStateObservers
+    }
+
+    private var contentWithNotificationObservers: some View {
         contentStack
             .onAppear(perform: handleContentAppear)
             .onReceive(NotificationCenter.default.publisher(for: .tagLauncherOverlayDidShow), perform: handleOverlayDidShow)
@@ -593,6 +597,10 @@
             .onReceive(NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification), perform: handleApplicationDidBecomeActive)
             .onReceive(NotificationCenter.default.publisher(for: .tagLauncherDataDidChange), perform: handleDataDidChange)
             .onReceive(NotificationCenter.default.publisher(for: .appLanguageDidChange), perform: handleAppLanguageDidChange)
+    }
+
+    private var contentWithStateObservers: some View {
+        contentWithNotificationObservers
             .onChange(of: editPhase) { _, newPhase in
                 let active = newPhase != .none
                 dismissAppBubble()
diff --git a/C1.source/Apptag/Info.plist b/C1.source/Apptag/Info.plist
index 941795c..94c96f5 100644
--- a/C1.source/Apptag/Info.plist
+++ b/C1.source/Apptag/Info.plist
@@ -19,7 +19,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>8.3.5</string>
+	<string>8.3.6</string>
 	<key>CFBundleURLTypes</key>
 	<array>
 		<dict>
@@ -32,7 +32,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>20260702.1046</string>
+	<string>20260707.1242</string>
 	<key>LSApplicationCategoryType</key>
 	<string>public.app-category.utilities</string>
 	<key>LSMinimumSystemVersion</key>
diff --git a/C1.source/Apptag/PreferencesView.swift b/C1.source/Apptag/PreferencesView.swift
index 32a95e1..b1052cd 100644
--- a/C1.source/Apptag/PreferencesView.swift
+++ b/C1.source/Apptag/PreferencesView.swift
@@ -1022,14 +1022,6 @@
             .padding(.vertical, 10)
             .frame(width: dataPanelWidth, alignment: .leading)
             .frame(minHeight: 44)
-            .background(
-                RoundedRectangle(cornerRadius: 10, style: .continuous)
-                    .fill(Color(nsColor: .controlBackgroundColor))
-            )
-            .overlay(
-                RoundedRectangle(cornerRadius: 10, style: .continuous)
-                    .stroke(Color.secondary.opacity(0.16), lineWidth: 1)
-            )
         }
         .frame(maxWidth: .infinity, alignment: .center)
         .padding(.top, 12)
diff --git a/C1.source/Apptag/ProEntitlement.swift b/C1.source/Apptag/ProEntitlement.swift
index 4d5fc2b..dd94ee6 100644
--- a/C1.source/Apptag/ProEntitlement.swift
+++ b/C1.source/Apptag/ProEntitlement.swift
@@ -680,11 +680,6 @@
             let verification = try await AppTransaction.shared
             switch verification {
             case .verified(let transaction):
-                if #available(macOS 13.0, *) {
-                    if transaction.revocationDate != nil {
-                        return nil
-                    }
-                }
                 return transaction
             case .unverified:
                 return nil
diff --git a/C1.source/CHANGELOG.md b/C1.source/CHANGELOG.md
index 016a633..0897058 100644
--- a/C1.source/CHANGELOG.md
+++ b/C1.source/CHANGELOG.md
@@ -2,6 +2,12 @@
 
 ## [Unreleased]
 
+## [8.3.6] — 2026-07-07
+
+- 设置页顶部固定 Pro 状态 / 引导行移除外层圆角矩形背景和描边,保留原位置、身份文案、购买和恢复购买入口
+- 扩展 Pro 门禁 QA,防止该固定 Pro 行回退为带外框样式
+- 版本号更新为 `8.3.6`,Build 更新为 `20260707.1242`
+
 ## [8.3.5] — 2026-07-02
 
 - 标签列表自身顺序不再作为 Pro 权益:免费用户拖动标签后也会持久保存容器显示顺序
diff --git a/C1.source/Docs/Requirements/2026-07-07-settings-pro-header-border-removal.md b/C1.source/Docs/Requirements/2026-07-07-settings-pro-header-border-removal.md
new file mode 100644
index 0000000..1a4430b
--- /dev/null
+++ b/C1.source/Docs/Requirements/2026-07-07-settings-pro-header-border-removal.md
@@ -0,0 +1,28 @@
+# Settings Pro Header Border Removal
+
+Date: 2026-07-07
+Target version: 8.3.6
+
+## Requirement
+
+Across all Settings tabs, the fixed Pro status / guidance row below the tab bar must no longer render an outer rounded rectangle frame.
+
+## Keep
+
+- Keep `settingsFixedProHeader` visible on Language, General, Theme, Hotkeys, Tags, Data, Pro, and About tabs.
+- Keep the row width, vertical position, status text, Pro pill, purchase button, and restore purchase button behavior.
+- Keep the centered unlocked identity layout for Language, Pro, and About after Pro unlock.
+
+## Remove
+
+- Remove only the outer rounded rectangle background and stroke from `settingsFixedProHeader`.
+- Do not remove inner Pro pills, tab content cards, Pro comparison rows, data action cards, or modal prompt styling.
+
+## Evidence
+
+User screenshot: `/var/folders/s4/_92q_d2d7sxczn21bpxjhbv00000gp/T/codex-clipboard-b111590b-42cc-42e5-80f0-be58e0f68eb4.png`
+
+## Validation
+
+- Static QA must fail if `settingsFixedProHeader` reintroduces the old `controlBackgroundColor` rounded background or secondary stroke.
+- Visual smoke must confirm the header content remains in the same position without the outer frame.
diff --git a/C1.source/Scripts/pro_feature_gate_qa.sh b/C1.source/Scripts/pro_feature_gate_qa.sh
index a41712c..c885d74 100755
--- a/C1.source/Scripts/pro_feature_gate_qa.sh
+++ b/C1.source/Scripts/pro_feature_gate_qa.sh
@@ -176,6 +176,10 @@
     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")
+if "Color(nsColor: .controlBackgroundColor)" in fixed_header_body:
+    fail("fixed Pro header must not render the removed outer rounded background")
+if ".stroke(Color.secondary.opacity(0.16), lineWidth: 1)" in fixed_header_body:
+    fail("fixed Pro header must not render the removed outer rounded border")
 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")
diff --git a/CODEGRAPH.md b/CODEGRAPH.md
index 94ecb62..162e5de 100644
--- a/CODEGRAPH.md
+++ b/CODEGRAPH.md
@@ -1,6 +1,6 @@
 # TagLauncher CODEGRAPH
 
-最后更新:2026-07-02
+最后更新:2026-07-07
 
 用途:本文件是 TagLauncher 的长期工程地图。修改用户可见行为、状态模型、构建/发布入口、核心源码或 QA 入口前,应先读本文件,再读指向的真实源码。若本文件与源码不一致,以源码为准,并在同一任务内更新本文件。
 
@@ -37,7 +37,7 @@
 - `C1.source/Apptag/PreferencesView.swift`
   - `PreferencesView`:设置窗口、语言、通用、主题、快捷键、标签、数据、Pro、关于等设置页。
   - 顶部设置页签必须保持 8 个标签总宽不超过旧 7 标签宽度;图标统一使用线型 SF Symbols,`Pro` 页签位于数据之后、关于之前,使用线型皇冠。
-  - 设置页签下方按页签渲染统一固定位置的 `settingsFixedProHeader`:语言 / 通用 / 主题 / 快捷键 / 标签 / 数据 / Pro / 关于 8 个页签都显示该行且位置不漂移。免费态左侧状态用“当前免费版用户”完整句而不是“免费版”胶囊;通用 / 主题 / 快捷键 / 标签 / 数据页显示当前 tab 对应购买引导和解锁/恢复按钮,语言和关于页只显示状态与操作按钮,不显示购买说明文字;已解锁 Pro 时,语言 / Pro / 关于页统一居中显示 `Pro 已解锁` 胶囊加 `settings.proStatus.proUser` 文案,不显示恢复购买按钮,且 `settings.proStatus.proUser` 本地化文字不再内置皇冠图标。
+  - 设置页签下方按页签渲染统一固定位置的 `settingsFixedProHeader`:语言 / 通用 / 主题 / 快捷键 / 标签 / 数据 / Pro / 关于 8 个页签都显示该行且位置不漂移。免费态左侧状态用“当前免费版用户”完整句而不是“免费版”胶囊;通用 / 主题 / 快捷键 / 标签 / 数据页显示当前 tab 对应购买引导和解锁/恢复按钮,语言和关于页只显示状态与操作按钮,不显示购买说明文字;已解锁 Pro 时,语言 / Pro / 关于页统一居中显示 `Pro 已解锁` 胶囊加 `settings.proStatus.proUser` 文案,不显示恢复购买按钮,且 `settings.proStatus.proUser` 本地化文字不再内置皇冠图标。8.3.6 起该固定行不渲染包住整行的外层圆角矩形背景或描边。
   - Pro 专属主题、彩色容器 / 彩色网格、自定义快捷键、自定义标签颜色和数据导入导出入口即使已解锁,也应保留皇冠 Pro 标识。
   - Language tab 去掉重复标题说明,语言矩阵在主内容区域上下左右居中;About tab 应用信息块也在主内容区域居中。
   - Theme tab 只写视觉偏好 `appGridThemeID` 和炫彩主题调色值,炫彩滑轨只能影响 AppGrid 背景,不得改变标签、排序、备注或分类数据。
@@ -205,7 +205,7 @@
 - `C1.source/Scripts/pro_localization_qa.sh`
   - Pro 文案 29 语种静态门禁;检查 `pro.*`、设置页 Pro 状态/对比表、自定义标签颜色、Quick Search 快捷键页和气泡提示设置键完整、占位符完整、无生成污染和非英文语言无英文兜底复制。
 - `C1.source/Scripts/pro_feature_gate_qa.sh`
-  - Pro 功能源码门禁;检查 StoreKit 权益、老用户自动 Pro、主题门禁、导入导出硬拦截、3 条备注额度、自定义标签颜色、自定义快捷键、容器内 App 排序预览、Pro UI 提示、设置页线型图标、轻量 Pro 权益行、Pro 页签、免费列“不支持”状态和 About 页不回归 Pro 汇总卡。
+  - Pro 功能源码门禁;检查 StoreKit 权益、老用户自动 Pro、主题门禁、导入导出硬拦截、3 条备注额度、自定义标签颜色、自定义快捷键、容器内 App 排序预览、Pro UI 提示、设置页线型图标、轻量 Pro 权益行、固定 Pro 行不回归外层圆角矩形框、Pro 页签、免费列“不支持”状态和 About 页不回归 Pro 汇总卡。
 - `C1.source/Scripts/pro_theme_preview_countdown_qa.sh`
   - Pro 主题 / 彩色显示模式预览倒计时门禁;检查状态行倒计时、当前预览卡片 `MM:SS`、到期清理、29 语种 `%time%` 占位符和禁止写死体验时长。
 - `C1.source/Scripts/pro_display_mode_preview_qa.sh`

--
Gitblit v1.9.3