Ariver
2026-06-25 ab59aa3a800139e2fe80f7e802dfada2258ab0f6
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\(\)",