From ab59aa3a800139e2fe80f7e802dfada2258ab0f6 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Thu, 25 Jun 2026 16:24:01 +0800
Subject: [PATCH] Add usage tips close reminder
---
src/Scripts/usage_tips_qa.sh | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 53 insertions(+), 6 deletions(-)
diff --git a/src/Scripts/usage_tips_qa.sh b/src/Scripts/usage_tips_qa.sh
index 25008cb..be9e0d4 100755
--- a/src/Scripts/usage_tips_qa.sh
+++ b/src/Scripts/usage_tips_qa.sh
@@ -8,6 +8,7 @@
PREFERENCES_VIEW_SWIFT="$ROOT_DIR/Apptag/PreferencesView.swift"
APP_DEFAULTS_SWIFT="$ROOT_DIR/Apptag/AppDefaults.swift"
APP_GRID_THEME_SWIFT="$ROOT_DIR/Apptag/AppGridTheme.swift"
+EDIT_MODE_VIEWS_SWIFT="$ROOT_DIR/Apptag/EditModeViews.swift"
LOCALIZATION_DIR="$ROOT_DIR/Apptag/Localization"
fail() {
@@ -21,9 +22,10 @@
[[ -f "$PREFERENCES_VIEW_SWIFT" ]] || fail "missing PreferencesView.swift"
[[ -f "$APP_DEFAULTS_SWIFT" ]] || fail "missing AppDefaults.swift"
[[ -f "$APP_GRID_THEME_SWIFT" ]] || fail "missing AppGridTheme.swift"
+[[ -f "$EDIT_MODE_VIEWS_SWIFT" ]] || fail "missing EditModeViews.swift"
[[ -d "$LOCALIZATION_DIR" ]] || fail "missing Localization directory"
-python3 - "$CONTENT_VIEW_SWIFT" "$APP_GRID_SWIFT" "$APPTAG_APP_SWIFT" "$PREFERENCES_VIEW_SWIFT" "$APP_DEFAULTS_SWIFT" "$APP_GRID_THEME_SWIFT" "$LOCALIZATION_DIR" <<'PY'
+python3 - "$CONTENT_VIEW_SWIFT" "$APP_GRID_SWIFT" "$APPTAG_APP_SWIFT" "$PREFERENCES_VIEW_SWIFT" "$APP_DEFAULTS_SWIFT" "$APP_GRID_THEME_SWIFT" "$EDIT_MODE_VIEWS_SWIFT" "$LOCALIZATION_DIR" <<'PY'
import json
import pathlib
import re
@@ -35,7 +37,8 @@
preferences = pathlib.Path(sys.argv[4]).read_text(encoding="utf-8")
defaults = pathlib.Path(sys.argv[5]).read_text(encoding="utf-8")
theme = pathlib.Path(sys.argv[6]).read_text(encoding="utf-8")
-localization_dir = pathlib.Path(sys.argv[7])
+edit_mode_views = pathlib.Path(sys.argv[7]).read_text(encoding="utf-8")
+localization_dir = pathlib.Path(sys.argv[8])
def fail(message: str) -> None:
@@ -54,6 +57,10 @@
"usageTips.previous",
"usageTips.next",
"usageTips.close",
+ "usageTips.closeReminder.title",
+ "usageTips.closeReminder.message",
+ "usageTips.closeReminder.doNotRemind",
+ "usageTips.closeReminder.previewCallout",
]
for index in range(1, 9):
required_keys.append(f"usageTips.tip{index}.title")
@@ -68,6 +75,11 @@
r'"hideUsageTips"\s*:\s*hideUsageTips',
defaults,
"AppDefaults.register must register hideUsageTips",
+)
+require(
+ r'"skipUsageTipsCloseReminder"\s*:\s*false',
+ defaults,
+ "AppDefaults.register must default the usage tips close reminder to visible",
)
for source_name, source in {
"ContentView.swift": content_view,
@@ -114,9 +126,29 @@
"ContentView must bind usage tip selection to AppGrid",
)
require(
- r"onHideUsageTips\s*:\s*\{\s*hideUsageTips\s*=\s*true\s*\}",
+ r"onHideUsageTips\s*:\s*requestHideUsageTips",
content_view,
- "closing the native usage tips banner must persist hideUsageTips",
+ "closing the native usage tips banner must route through the reminder flow",
+)
+require(
+ r'@AppStorage\("skipUsageTipsCloseReminder"\)\s+private\s+var\s+skipUsageTipsCloseReminder\s*=\s*false',
+ content_view,
+ "ContentView must persist the usage tips close reminder suppression flag",
+)
+require(
+ r"private\s+func\s+requestHideUsageTips\s*\(\)\s*\{(?P<body>.*?)skipUsageTipsCloseReminder(?P<body2>.*?)usageTipsCloseReminderVisible\s*=\s*true",
+ content_view,
+ "requestHideUsageTips must show the reminder unless the user suppressed it",
+)
+require(
+ r"private\s+func\s+confirmUsageTipsCloseReminder\s*\(\)\s*\{(?P<body>.*?)skipUsageTipsCloseReminder\s*=\s*true(?P<body2>.*?)hideUsageTips\s*=\s*true",
+ content_view,
+ "confirmUsageTipsCloseReminder must persist suppression only after opt-in and then hide tips",
+)
+require(
+ r"usageTipsCloseReminderVisible",
+ content_view,
+ "usage tips close reminder must participate in modal state and hit testing",
)
require(
r"let\s+onHideUsageTips\s*:\s*\(\)\s*->\s*Void",
@@ -124,15 +156,30 @@
"AppGridCollectionView must accept an onHideUsageTips callback",
)
require(
- r"closeButton\.action\s*=\s*\{\s*\[weak\s+self\]\s+in\s+self\?\.hideUsageTips\(\)\s*\}",
+ r"closeButton\.action\s*=\s*\{\s*\[weak\s+self\]\s+in\s+self\?\.requestHideUsageTips\(\)\s*\}",
app_grid,
- "close button must call the native hideUsageTips handler",
+ "close button must call the native requestHideUsageTips handler",
)
require(
r"coordinator\?\.onHideUsageTips\(\)",
app_grid,
"native hideUsageTips must call back to persisted SwiftUI state",
)
+require(
+ r"struct\s+UsageTipsCloseReminderBubble\s*:\s*View",
+ edit_mode_views,
+ "EditModeViews must provide the close reminder bubble",
+)
+require(
+ r"UsageTipsCloseReminderSettingsPreview\s*\(\s*callout\s*:\s*previewCallout\s*\)",
+ edit_mode_views,
+ "close reminder must pass the localized preview callout into the settings preview",
+)
+require(
+ r"struct\s+UsageTipsCloseReminderSettingsPreview\s*:\s*View(?P<body>.*?)settings\.hideUsageTips",
+ edit_mode_views,
+ "close reminder must include a localized Settings > General preview highlighting Hide usage tips",
+)
require(
r"private\s+let\s+titlePanelView\s*=\s*NSView\(\)",
--
Gitblit v1.9.3