From ed4ebcfa763f66ecd69cae57df2c949a7a9a8a45 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sat, 13 Jun 2026 20:23:29 +0800
Subject: [PATCH] Prepare 7.9.1 usage tips release

---
 src/Apptag/ContentView.swift |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/src/Apptag/ContentView.swift b/src/Apptag/ContentView.swift
index 1afa3e3..ed6f932 100644
--- a/src/Apptag/ContentView.swift
+++ b/src/Apptag/ContentView.swift
@@ -353,6 +353,8 @@
     @State private var groupLayoutVersion = 0
     @State private var appGridScrollTargetID: String? = nil
     @State private var appGridScrollRequestToken = 0
+    @State private var selectedUsageTipIndex = 0
+    @State private var usageTipsHovered = false
 
     // Edit mode
     @State private var editPhase: EditPhase = .none
@@ -414,6 +416,7 @@
     @AppStorage("displayMode") private var displayMode = AppDefaults.displayMode
     @AppStorage("hideAppNames") private var hideAppNames = AppDefaults.hideAppNames
     @AppStorage("showUncommonAppBubbles") private var showUncommonAppBubbles = AppDefaults.showUncommonAppBubbles
+    @AppStorage("hideUsageTips") private var hideUsageTips = AppDefaults.hideUsageTips
     @AppStorage("useAppKitTagNavigation") private var useAppKitTagNavigation = AppDefaults.useAppKitTagNavigation
     @AppStorage("skipTagRemovalDropConfirm") private var skipTagRemovalDropConfirm = false
     @AppStorage("skipUncategorizedDropConfirm") private var skipUncategorizedDropConfirm = false
@@ -423,7 +426,8 @@
     private let floatingControlsTrailingInset: CGFloat = 20
     private let floatingControlsReservedWidth: CGFloat = 120
     private var appBubbleDisabled: Bool {
-        appGridInteraction.appDragModeActive
+        usageTipsHovered
+            || appGridInteraction.appDragModeActive
             || appGridInteraction.pendingUncategorizedDrop != nil
             || appGridInteraction.pendingTagRemovalDrop != nil
     }
@@ -448,6 +452,23 @@
 
     private var isColorlessContainerMode: Bool {
         displayMode == "container" || displayMode == "gridContainer"
+    }
+
+    private var shouldShowUsageTips: Bool {
+        !hideUsageTips && !allApps.isEmpty && !quickSearchOnlySession
+    }
+
+    private var appGridUsageTips: [AppGridUsageTip] {
+        [
+            AppGridUsageTip(id: 1, titleKey: "usageTips.tip1.title", detailKey: "usageTips.tip1.detail"),
+            AppGridUsageTip(id: 2, titleKey: "usageTips.tip2.title", detailKey: "usageTips.tip2.detail"),
+            AppGridUsageTip(id: 3, titleKey: "usageTips.tip3.title", detailKey: "usageTips.tip3.detail"),
+            AppGridUsageTip(id: 4, titleKey: "usageTips.tip4.title", detailKey: "usageTips.tip4.detail"),
+            AppGridUsageTip(id: 5, titleKey: "usageTips.tip5.title", detailKey: "usageTips.tip5.detail"),
+            AppGridUsageTip(id: 6, titleKey: "usageTips.tip6.title", detailKey: "usageTips.tip6.detail"),
+            AppGridUsageTip(id: 7, titleKey: "usageTips.tip7.title", detailKey: "usageTips.tip7.detail"),
+            AppGridUsageTip(id: 8, titleKey: "usageTips.tip8.title", detailKey: "usageTips.tip8.detail"),
+        ]
     }
 
     private var shouldRenderAppGridBehindQuickSearch: Bool {
@@ -1121,6 +1142,10 @@
                     bubbleDisabled: appBubbleDisabled,
                     showUncommonAppBubbles: showUncommonAppBubbles,
                     highlightedGroupName: appGridHighlightedGroupName,
+                    bottomContentPadding: shouldShowUsageTips ? AppGridUsageTipsMetrics.reservedHeight : 0,
+                    usageTipsVisible: shouldShowUsageTips,
+                    usageTips: appGridUsageTips,
+                    selectedUsageTipIndex: $selectedUsageTipIndex,
                     contentRevision: groupLayoutVersion,
                     scrollTargetID: appGridScrollTargetID,
                     scrollRequestToken: appGridScrollRequestToken,
@@ -1142,7 +1167,8 @@
                         }
                     },
                     onScrollActivity: handleAppGridScrollActivity,
-                    onDragModeChange: { setAppDragMode($0) }
+                    onDragModeChange: { setAppDragMode($0) },
+                    onUsageTipsHoverChange: handleUsageTipsHoverChange
                 )
             }
         }
@@ -1866,6 +1892,13 @@
         }
     }
 
+    private func handleUsageTipsHoverChange(_ hovering: Bool) {
+        usageTipsHovered = hovering
+        if hovering, appGridInteraction.hoveredBubble != nil {
+            appGridInteraction.hoveredBubble = nil
+        }
+    }
+
     private func handleBubbleHover(app: AppInfo, frame: CGRect, event: AppBubbleHoverEvent) {
         guard !appBubbleDisabled else {
             clearAppBubbleState()

--
Gitblit v1.9.3