From 9c9aa6e7ed0c11c741e1950a5f62737581c83bcd Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Fri, 12 Jun 2026 11:34:30 +0800
Subject: [PATCH] Record 7.9.0 App Store release pack

---
 src/Apptag/ContentView.swift |   51 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/src/Apptag/ContentView.swift b/src/Apptag/ContentView.swift
index a6011b8..1afa3e3 100644
--- a/src/Apptag/ContentView.swift
+++ b/src/Apptag/ContentView.swift
@@ -348,6 +348,8 @@
     @State private var allApps: [AppInfo] = []
     @State private var displayGroups: [TagGroup] = []
     @State private var tagColors: [String: Int] = [:]
+    @State private var tagDefinitions: [String: TagDatabase.TagDef] = [:]
+    @State private var containerAppOrder: [String: [String]] = [:]
     @State private var groupLayoutVersion = 0
     @State private var appGridScrollTargetID: String? = nil
     @State private var appGridScrollRequestToken = 0
@@ -619,6 +621,9 @@
         .onChange(of: appGridInteraction.pendingTagRemovalDrop != nil) { _, _ in
             publishModalInteractionState()
         }
+        .onChange(of: smartStartNotice != nil) { _, _ in
+            publishModalInteractionState()
+        }
         .onDisappear {
             NotificationCenter.default.post(
                 name: .tagLauncherModalInteractionChanged,
@@ -632,7 +637,11 @@
         NotificationCenter.default.post(
             name: .tagLauncherModalInteractionChanged,
             object: nil,
-            userInfo: ["active": appGridInteraction.pendingUncategorizedDrop != nil || appGridInteraction.pendingTagRemovalDrop != nil]
+            userInfo: [
+                "active": smartStartNotice != nil
+                    || appGridInteraction.pendingUncategorizedDrop != nil
+                    || appGridInteraction.pendingTagRemovalDrop != nil
+            ]
         )
     }
 
@@ -1123,6 +1132,9 @@
                     },
                     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 {
@@ -1771,13 +1783,27 @@
 
     private func makeDisplayGroups(apps: [AppInfo], tagOrder: [String]) -> [TagGroup] {
         let order = tagOrder.isEmpty ? TagEditor.orderedTagNames() : tagOrder
-        let rawGroups = AppIndexer.group(apps: apps, defaultGroupName: defaultGroupName, tagOrder: order)
+        let rawGroups = AppIndexer.group(
+            apps: apps,
+            defaultGroupName: defaultGroupName,
+            tagOrder: order,
+            tagDefinitions: tagDefinitions,
+            containerAppOrder: containerAppOrder
+        )
         return rawGroups.map { group in
             if group.name == defaultGroupName {
-                return TagGroup(name: tr("group.uncategorized"), apps: group.apps)
+                return TagGroup(
+                    containerID: group.containerID,
+                    name: tr("group.uncategorized"),
+                    apps: group.apps
+                )
             }
             if group.name == "Mac自带" {
-                return TagGroup(name: tr("group.appleBuiltIn"), apps: group.apps)
+                return TagGroup(
+                    containerID: group.containerID,
+                    name: tr("group.appleBuiltIn"),
+                    apps: group.apps
+                )
             }
             return group
         }
@@ -2119,6 +2145,8 @@
     private func dropApp(path: String, sourceTag: String, targetTag: String, copy: Bool) {
         resetTransientDragState(keepingPendingUncategorizedDrop: true)
 
+        guard sourceTag != targetTag else { return }
+
         if isUncategorizedDropTarget(targetTag) {
             confirmAndMoveAppToUncategorized(path: path)
             return
@@ -2130,7 +2158,6 @@
         }
 
         guard tagColors[targetTag] != nil else { return }
-        guard sourceTag != targetTag || copy else { return }
         TagEditor.moveApp(
             path: path,
             from: sourceTag,
@@ -2149,6 +2176,18 @@
         guard !appHasTag(app, tagName: targetTag) else { return }
         TagEditor.appendTags([targetTag], to: [path])
         showDropRefresh()
+        refreshApps(forceLayoutRefresh: true)
+    }
+
+    private func reorderApps(inContainer containerID: String, orderedPaths: [String]) {
+        resetTransientDragState()
+        let key = TagDatabase.normalizedContainerID(containerID, tags: tagDefinitions)
+        let paths = TagDatabase.normalizedAppOrderPaths(orderedPaths)
+        guard !key.isEmpty, !paths.isEmpty else { return }
+
+        containerAppOrder[key] = paths
+        rebuildDisplayGroups(apps: allApps, tagOrder: draggedTagNames)
+        TagEditor.reorderApps(inContainer: key, orderedPaths: paths)
         refreshApps(forceLayoutRefresh: true)
     }
 
@@ -2455,6 +2494,8 @@
         allApps = snapshot.apps
         quickSearchDocuments = snapshot.quickSearchDocuments
         tagColors = snapshot.tagColors
+        tagDefinitions = snapshot.tagDefinitions
+        containerAppOrder = snapshot.containerAppOrder
         draggedTagNames = snapshot.tagOrder
         rebuildDisplayGroups(apps: snapshot.apps, tagOrder: snapshot.tagOrder)
         if quickSearchVisible {

--
Gitblit v1.9.3