From beebaf7b68b3749f4a1bc4d916e23906b8c16d7f Mon Sep 17 00:00:00 2001
From: Ariver <ar@MacBook-Air.local>
Date: Wed, 13 May 2026 23:31:23 +0800
Subject: [PATCH] Release TagLauncher 5.6.0

---
 Apptag/TagEditorView.swift |   40 ++++++++++++++++++++--------------------
 1 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/Apptag/TagEditorView.swift b/Apptag/TagEditorView.swift
index 96e839d..866b7ef 100644
--- a/Apptag/TagEditorView.swift
+++ b/Apptag/TagEditorView.swift
@@ -16,9 +16,11 @@
     @State private var newTagColorIndex = 0
 
     private var sortedTagNames: [String] {
-        tagColors.keys
-            .filter { !excludedTagNames.contains($0) }
-            .sorted { $0.localizedStandardCompare($1) == .orderedAscending }
+        let order = TagEditor.orderedTagNames()
+        let filtered = tagColors.keys.filter { !excludedTagNames.contains($0) }
+        let ordered = order.filter { filtered.contains($0) }
+        let remaining = filtered.filter { !ordered.contains($0) }.sorted()
+        return ordered + remaining
     }
 
     var body: some View {
@@ -31,7 +33,7 @@
                     newTagNameText = ""
                     newTagColorIndex = 0
                 } label: {
-                    Label("New Tag", systemImage: "plus")
+                    Label(tr("tag.newTag"), systemImage: "plus")
                         .font(.system(size: 12))
                 }
                 .buttonStyle(.bordered)
@@ -43,17 +45,17 @@
             ScrollView {
                 VStack(spacing: 0) {
                     if sortedTagNames.isEmpty && !addingNewTag {
-                        Text("No tags yet. Click \"New Tag\" to create one.")
+                        Text(tr("edit.noTags"))
                             .font(.caption)
                             .foregroundStyle(.secondary)
                             .padding(.vertical, 40)
                     }
-                    ForEach(sortedTagNames, id: \.self) { tagName in
-                        tagEditRow(tagName)
-                        Divider().opacity(0.15).padding(.leading, 16)
-                    }
                     if addingNewTag {
                         newTagRow()
+                        Divider().opacity(0.15).padding(.leading, 16)
+                    }
+                    ForEach(sortedTagNames, id: \.self) { tagName in
+                        tagEditRow(tagName)
                         Divider().opacity(0.15).padding(.leading, 16)
                     }
                 }
@@ -79,13 +81,13 @@
             if editingTagName == tagName {
                 MacTextField(
                     text: $editingTagText,
-                    placeholder: "Tag name",
+                    placeholder: tr("tag.name"),
                     onSubmit: { commitTagRename(tagName) }
                 )
                 .frame(width: 160, height: 24)
-                Button("Save") { commitTagRename(tagName) }
+                Button(tr("tag.save")) { commitTagRename(tagName) }
                     .buttonStyle(.borderedProminent).controlSize(.small)
-                Button("Cancel") { editingTagName = nil }
+                Button(tr("tag.cancel")) { editingTagName = nil }
                     .buttonStyle(.plain).foregroundStyle(.secondary)
             } else {
                 Text(tagName).font(.system(size: 14)).frame(width: 160, alignment: .leading)
@@ -116,13 +118,13 @@
             }
             MacTextField(
                 text: $newTagNameText,
-                placeholder: "New tag name",
+                placeholder: tr("tag.newName"),
                 onSubmit: { addNewTag() }
             )
             .frame(width: 160, height: 24)
-            Button("Add") { addNewTag() }
+            Button(tr("tag.add")) { addNewTag() }
                 .buttonStyle(.borderedProminent).controlSize(.small)
-            Button("Cancel") { addingNewTag = false; newTagNameText = "" }
+            Button(tr("tag.cancel")) { addingNewTag = false; newTagNameText = "" }
                 .buttonStyle(.plain).foregroundStyle(.secondary)
             Spacer()
         }
@@ -143,17 +145,15 @@
         tagColors[newName] = tagColors[oldName]
         tagColors.removeValue(forKey: oldName)
         editingTagName = nil
-        // Don't call onRefresh — re-scan may re-discover old tag from
-        // SIP-protected apps where xattr write silently fails.
+        onRefresh?()
     }
 
-    /// Add a new tag name+color to the local registry only (no xattr write until
-    /// the tag is assigned to apps via "Edit App Categories").
-    /// Does NOT call onRefresh — would overwrite tagColors with scan results.
+    /// Add a new tag name+color and persist to the database.
     private func addNewTag() {
         let name = newTagNameText.trimmingCharacters(in: .whitespaces)
         guard !name.isEmpty else { return }
         tagColors[name] = newTagColorIndex
+        TagEditor.createTag(name, color: newTagColorIndex)
         addingNewTag = false
         newTagNameText = ""
     }

--
Gitblit v1.9.3