From 192a009cb0b0f1b34b39d7ba3a7d1d790867e677 Mon Sep 17 00:00:00 2001
From: Ariver <ar@MacBook-Air.local>
Date: Sun, 10 May 2026 23:11:39 +0800
Subject: [PATCH] Lock colorless container interactions
---
Apptag/ContentView.swift | 44 ++++++++++++++++++++++++++++++++++++++++----
Apptag/Info.plist | 2 +-
Decisions.md | 9 ++++++++-
CHANGELOG.md | 5 +++++
4 files changed, 54 insertions(+), 6 deletions(-)
diff --git a/Apptag/ContentView.swift b/Apptag/ContentView.swift
index 7411edc..d5ab10b 100644
--- a/Apptag/ContentView.swift
+++ b/Apptag/ContentView.swift
@@ -204,6 +204,8 @@
@State private var draggedTagNames: [String] = [] // live drag order
@State private var dragItem: String? = nil // currently dragged tag
@State private var hoveredContainer: String? = nil // colored container lift
+ // Fixed interaction for "Colorless Container": hover fills persistently; click clears.
+ @State private var filledColorlessContainer: String? = nil
// Configurable defaults
@AppStorage("defaultGroupName") private var defaultGroupName = "Other"
@@ -337,10 +339,16 @@
ForEach(tagLabels) { tag in
TagPill(name: tag.name, colorIndex: tag.colorIndex,
action: {
+ if displayMode == "container" {
+ toggleColorlessFill(tag.id)
+ }
scrollTo(tag.id)
})
.onHover { hovering in
- if hovering { scrollTo(tag.id) }
+ if hovering {
+ fillColorlessContainer(tag.id)
+ scrollTo(tag.id)
+ }
}
}
}.padding(.horizontal, 24)
@@ -353,10 +361,16 @@
ForEach(tagLabels) { tag in
SideTagPill(name: tag.name, colorIndex: tag.colorIndex,
action: {
+ if displayMode == "container" {
+ toggleColorlessFill(tag.id)
+ }
scrollTo(tag.id)
})
.onHover { hovering in
- if hovering { scrollTo(tag.id) }
+ if hovering {
+ fillColorlessContainer(tag.id)
+ scrollTo(tag.id)
+ }
}
}
}.padding(12)
@@ -455,6 +469,8 @@
private func masonryCard(_ group: TagGroup, width: CGFloat) -> some View {
let isColored = displayMode == "coloredContainer"
+ let isColorless = displayMode == "container"
+ let isColorlessFilled = isColorless && filledColorlessContainer == group.name
let isHovered = hoveredContainer == group.name
let tagColor = Color(nsColor: TagColor.nsColor(for: tagColors[group.name] ?? 0))
return VStack(alignment: .leading, spacing: 6) {
@@ -485,7 +501,7 @@
.padding(16)
.background(
RoundedRectangle(cornerRadius: 14)
- .fill(isColored ? tagColor.opacity(0.30) : Color.clear)
+ .fill((isColored || isColorlessFilled) ? tagColor.opacity(0.30) : Color.clear)
.background(
RoundedRectangle(cornerRadius: 14)
.fill(.ultraThinMaterial)
@@ -501,7 +517,17 @@
.scaleEffect(isColored && isHovered ? 1.015 : 1.0)
.animation(.spring(response: 0.25, dampingFraction: 0.82), value: isHovered)
.onHover { hovering in
- hoveredContainer = hovering ? group.name : nil
+ if isColored {
+ hoveredContainer = hovering ? group.name : nil
+ } else if hovering {
+ fillColorlessContainer(group.name)
+ }
+ }
+ .contentShape(RoundedRectangle(cornerRadius: 14))
+ .onTapGesture {
+ if isColorlessFilled {
+ filledColorlessContainer = nil
+ }
}
}
@@ -767,6 +793,16 @@
withAnimation(.easeInOut(duration: 0.25)) { scrollProxy?.scrollTo(id, anchor: .top) }
}
+ private func fillColorlessContainer(_ id: String) {
+ guard displayMode == "container" else { return }
+ filledColorlessContainer = id
+ }
+
+ private func toggleColorlessFill(_ id: String) {
+ guard displayMode == "container" else { return }
+ filledColorlessContainer = (filledColorlessContainer == id) ? nil : id
+ }
+
func refreshApps() {
DispatchQueue.global(qos: .userInitiated).async {
var apps = AppIndexer.scan()
diff --git a/Apptag/Info.plist b/Apptag/Info.plist
index 5e1f15d..55581ed 100644
--- a/Apptag/Info.plist
+++ b/Apptag/Info.plist
@@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>3.2.0</string>
+ <string>3.2.1</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSMinimumSystemVersion</key>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b14b809..ea4b7fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
# Apptag Changelog
+## [3.2.1] — 2026-05-10
+
+- 固定「无色容器」交互逻辑:hover 标签或容器时保持标签色填充,再次点击标签或点击容器空白处清除填充
+- 保持「彩色容器」逻辑独立:默认标签色填充,hover 仅增加阴影凸起效果
+
## [3.2.0] — 2026-05-10
- 新增 App 列表显示样式「彩色容器」:所有容器默认填充标签色,鼠标 hover 容器时增加阴影凸起效果
diff --git a/Decisions.md b/Decisions.md
index 67ff5fc..6e6a577 100644
--- a/Decisions.md
+++ b/Decisions.md
@@ -1,2 +1,9 @@
项目决策记录(DECISIONS.md)
-由 Hermes Agent 自动维护,用于记录每个版本的需求背景和决策过程。
\ No newline at end of file
+由 Hermes Agent 自动维护,用于记录每个版本的需求背景和决策过程。
+
+## 2026-05-10 — 无色容器交互锁定
+
+- 「无色容器」是 App 列表第 2 种视图样式,对应 `displayMode == "container"`。
+- 固定交互:hover 标签或对应容器区域时,容器保持标签色填充;鼠标移开后不自动清除。
+- 清除方式:再次点击同一标签,或点击对应容器内部空白处。
+- 后续迭代新增/修改其他样式时,不应改变以上无色容器交互逻辑;「彩色容器」应使用独立交互状态。
--
Gitblit v1.9.3