From 6ea714f104ac6a486d8ce5d64cd87203543ed1a3 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Sun, 14 Jun 2026 10:53:41 +0800
Subject: [PATCH] Make localized site generator source optional

---
 src/Apptag/ContentView.swift |  206 +++++++++++---------------------------------------
 1 files changed, 47 insertions(+), 159 deletions(-)

diff --git a/src/Apptag/ContentView.swift b/src/Apptag/ContentView.swift
index 122addf..ed6f932 100644
--- a/src/Apptag/ContentView.swift
+++ b/src/Apptag/ContentView.swift
@@ -340,120 +340,6 @@
     let tagName: String
 }
 
-private struct AppGridUsageTip: Identifiable {
-    let id: Int
-    let titleKey: String
-    let detailKey: String
-}
-
-private struct AppGridUsageTipsBar: View {
-    static let reservedHeight: CGFloat = 64
-
-    let tips: [AppGridUsageTip]
-    @Binding var selectedIndex: Int
-    let dragModeActive: Bool
-
-    @State private var textHovered = false
-
-    private var safeIndex: Int {
-        guard tips.indices.contains(selectedIndex) else { return 0 }
-        return selectedIndex
-    }
-
-    private var currentTip: AppGridUsageTip? {
-        guard !tips.isEmpty else { return nil }
-        return tips[safeIndex]
-    }
-
-    var body: some View {
-        if let tip = currentTip {
-            HStack(spacing: 0) {
-                Text(tr(tip.titleKey))
-                    .font(.system(size: 14, weight: .semibold))
-                    .foregroundStyle(Color.primary)
-                    .lineLimit(1)
-                    .minimumScaleFactor(0.82)
-                    .padding(.horizontal, 14)
-                    .frame(width: 174, height: 42, alignment: .leading)
-                    .background(Color(nsColor: .controlBackgroundColor).opacity(0.96))
-
-                tipDetailText(tip)
-                    .frame(height: 42)
-                    .frame(maxWidth: .infinity, alignment: .leading)
-                    .background(Color.black.opacity(0.88))
-
-                tipsControls
-                    .frame(width: 86, height: 42)
-                    .background(Color.black.opacity(0.88))
-            }
-            .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
-            .overlay(
-                RoundedRectangle(cornerRadius: 8, style: .continuous)
-                    .stroke(Color.primary.opacity(0.18), lineWidth: 1)
-            )
-            .shadow(color: .black.opacity(0.20), radius: 14, y: 7)
-            .frame(maxWidth: 980)
-            .padding(.horizontal, 18)
-            .padding(.bottom, 12)
-            .opacity(dragModeActive ? 0.72 : 1.0)
-            .allowsHitTesting(!dragModeActive)
-            .accessibilityElement(children: .combine)
-            .accessibilityLabel("\(tr(tip.titleKey)) \(tr(tip.detailKey))")
-        }
-    }
-
-    private func tipDetailText(_ tip: AppGridUsageTip) -> some View {
-        ScrollView(.horizontal, showsIndicators: textHovered) {
-            Text(tr(tip.detailKey))
-                .font(.system(size: 15, weight: .medium))
-                .foregroundStyle(Color.white.opacity(0.96))
-                .lineLimit(1)
-                .fixedSize(horizontal: true, vertical: false)
-                .padding(.horizontal, 14)
-                .frame(minHeight: 42, alignment: .center)
-        }
-        .onHover { textHovered = $0 }
-        .help(tr(tip.detailKey))
-    }
-
-    private var tipsControls: some View {
-        VStack(spacing: 4) {
-            HStack(spacing: 8) {
-                usageTipNavigationButton(systemImage: "chevron.left", labelKey: "usageTips.previous") {
-                    selectedIndex = (safeIndex - 1 + tips.count) % tips.count
-                }
-                usageTipNavigationButton(systemImage: "chevron.right", labelKey: "usageTips.next") {
-                    selectedIndex = (safeIndex + 1) % tips.count
-                }
-            }
-
-            HStack(spacing: 3) {
-                ForEach(tips.indices, id: \.self) { index in
-                    Circle()
-                        .fill(index == safeIndex ? Color.accentColor : Color.white.opacity(0.58))
-                        .frame(width: 4, height: 4)
-                }
-            }
-        }
-    }
-
-    private func usageTipNavigationButton(
-        systemImage: String,
-        labelKey: String,
-        action: @escaping () -> Void
-    ) -> some View {
-        Button(action: action) {
-            Image(systemName: systemImage)
-                .font(.system(size: 15, weight: .bold))
-                .foregroundStyle(Color.white.opacity(0.96))
-                .frame(width: 24, height: 22)
-                .contentShape(Rectangle())
-        }
-        .buttonStyle(.plain)
-        .accessibilityLabel(tr(labelKey))
-    }
-}
-
 struct ContentView: View {
     let hideOverlay: () -> Void
     private let initialQuickSearchSource: String?
@@ -468,6 +354,7 @@
     @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
@@ -539,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
     }
@@ -1245,50 +1133,43 @@
                 ProgressView().scaleEffect(0.8)
                 Spacer()
             } else {
-                ZStack(alignment: .bottom) {
-                    AppGridCollectionView(
-                        groups: displayGroups,
-                        tagColors: tagColors,
-                        displayMode: displayMode,
-                        iconSize: iconSize,
-                        showNames: !hideAppNames,
-                        bubbleDisabled: appBubbleDisabled,
-                        showUncommonAppBubbles: showUncommonAppBubbles,
-                        highlightedGroupName: appGridHighlightedGroupName,
-                        bottomContentPadding: shouldShowUsageTips ? AppGridUsageTipsBar.reservedHeight : 0,
-                        contentRevision: groupLayoutVersion,
-                        scrollTargetID: appGridScrollTargetID,
-                        scrollRequestToken: appGridScrollRequestToken,
-                        onSelectApp: { app in openApp(app) },
-                        onBubbleHover: handleBubbleHover,
-                        onEditNote: beginEditingBubbleNote,
-                        onDropApp: { path, source, target, copy in
-                            dropApp(path: path, sourceTag: source, targetTag: target, copy: copy)
-                        },
-                        onDropOutsideGroup: { path, source, copy in
-                            dropAppOutsideGroup(path: path, sourceTag: source, copy: copy)
-                        },
-                        onReorderApps: { containerID, orderedPaths in
-                            reorderApps(inContainer: containerID, orderedPaths: orderedPaths)
-                        },
-                        onGroupActivate: { groupName in
-                            if isColorlessContainerMode {
-                                toggleColorlessFill(groupName)
-                            }
-                        },
-                        onScrollActivity: handleAppGridScrollActivity,
-                        onDragModeChange: { setAppDragMode($0) }
-                    )
-
-                    if shouldShowUsageTips {
-                        AppGridUsageTipsBar(
-                            tips: appGridUsageTips,
-                            selectedIndex: $selectedUsageTipIndex,
-                            dragModeActive: appGridInteraction.appDragModeActive
-                        )
-                        .zIndex(3)
-                    }
-                }
+                AppGridCollectionView(
+                    groups: displayGroups,
+                    tagColors: tagColors,
+                    displayMode: displayMode,
+                    iconSize: iconSize,
+                    showNames: !hideAppNames,
+                    bubbleDisabled: appBubbleDisabled,
+                    showUncommonAppBubbles: showUncommonAppBubbles,
+                    highlightedGroupName: appGridHighlightedGroupName,
+                    bottomContentPadding: shouldShowUsageTips ? AppGridUsageTipsMetrics.reservedHeight : 0,
+                    usageTipsVisible: shouldShowUsageTips,
+                    usageTips: appGridUsageTips,
+                    selectedUsageTipIndex: $selectedUsageTipIndex,
+                    contentRevision: groupLayoutVersion,
+                    scrollTargetID: appGridScrollTargetID,
+                    scrollRequestToken: appGridScrollRequestToken,
+                    onSelectApp: { app in openApp(app) },
+                    onBubbleHover: handleBubbleHover,
+                    onEditNote: beginEditingBubbleNote,
+                    onDropApp: { path, source, target, copy in
+                        dropApp(path: path, sourceTag: source, targetTag: target, copy: copy)
+                    },
+                    onDropOutsideGroup: { path, source, copy in
+                        dropAppOutsideGroup(path: path, sourceTag: source, copy: copy)
+                    },
+                    onReorderApps: { containerID, orderedPaths in
+                        reorderApps(inContainer: containerID, orderedPaths: orderedPaths)
+                    },
+                    onGroupActivate: { groupName in
+                        if isColorlessContainerMode {
+                            toggleColorlessFill(groupName)
+                        }
+                    },
+                    onScrollActivity: handleAppGridScrollActivity,
+                    onDragModeChange: { setAppDragMode($0) },
+                    onUsageTipsHoverChange: handleUsageTipsHoverChange
+                )
             }
         }
     }
@@ -2011,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