From 70a1cc2e63d2c49a135bd89cec3ffb1d427d90ee Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Tue, 30 Jun 2026 16:21:47 +0800
Subject: [PATCH] Freeze prep TagLauncher 8.2.9 Pro status UI
---
src/Apptag/EditModeViews.swift | 310 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 290 insertions(+), 20 deletions(-)
diff --git a/src/Apptag/EditModeViews.swift b/src/Apptag/EditModeViews.swift
index 3e7a0cf..619a0d7 100644
--- a/src/Apptag/EditModeViews.swift
+++ b/src/Apptag/EditModeViews.swift
@@ -2,6 +2,7 @@
import AppKit
struct EditAppsHeaderView: View {
+ let theme: AppGridTheme
let operation: EditTagOperation
let hintText: String
let confirmTitle: String
@@ -16,19 +17,34 @@
Button(action: onExit) {
Label(tr("edit.exit"), systemImage: "rectangle.portrait.and.arrow.right")
.font(.system(size: 12))
+ .foregroundStyle(theme.editPrimaryTextColor)
+ .padding(.horizontal, 8)
+ .frame(height: 28)
+ .background(
+ RoundedRectangle(cornerRadius: 7, style: .continuous)
+ .fill(theme.editControlSurfaceColor)
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 7, style: .continuous)
+ .stroke(theme.editControlStrokeColor, lineWidth: 1)
+ )
}
- .buttonStyle(.bordered)
+ .buttonStyle(.plain)
+ .help(tr("edit.exit"))
+ .shadow(color: theme.editButtonShadowColor, radius: 10, y: 4)
Spacer(minLength: 20)
VStack(alignment: .trailing, spacing: 5) {
HStack(alignment: .center, spacing: 14) {
EditOperationPicker(
+ theme: theme,
operation: operation,
onSelect: onSelectOperation
)
EditConfirmButton(
+ theme: theme,
title: confirmTitle,
isDisabled: isConfirmDisabled,
action: onConfirm
@@ -37,7 +53,7 @@
Text(hintText)
.font(.system(size: 11, weight: .medium))
- .foregroundStyle(.secondary)
+ .foregroundStyle(theme.editSecondaryTextColor)
.lineLimit(2)
.multilineTextAlignment(.trailing)
.frame(maxWidth: 460, alignment: .trailing)
@@ -48,10 +64,12 @@
.padding(.horizontal, 24)
.padding(.top, notchHeight > 0 ? notchHeight + 10 : 20)
.padding(.bottom, 10)
+ .background(theme.editToolbarSurfaceColor)
}
}
private struct EditOperationPicker: View {
+ let theme: AppGridTheme
let operation: EditTagOperation
let onSelect: (EditTagOperation) -> Void
@@ -59,16 +77,18 @@
HStack(spacing: 10) {
Text(tr("edit.operationLabel"))
.font(.system(size: 12, weight: .medium))
- .foregroundStyle(.secondary)
+ .foregroundStyle(theme.editSecondaryTextColor)
HStack(spacing: 14) {
EditOperationModeButton(
+ theme: theme,
operation: operation,
mode: .add,
titleKey: "edit.modeAdd",
onSelect: onSelect
)
EditOperationModeButton(
+ theme: theme,
operation: operation,
mode: .remove,
titleKey: "edit.modeRemove",
@@ -76,10 +96,22 @@
)
}
}
+ .padding(.horizontal, 10)
+ .frame(height: 34)
+ .background(
+ RoundedRectangle(cornerRadius: 8, style: .continuous)
+ .fill(theme.editControlSurfaceColor)
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 8, style: .continuous)
+ .stroke(theme.editControlStrokeColor, lineWidth: 1)
+ )
+ .shadow(color: theme.editButtonShadowColor, radius: 10, y: 4)
}
}
private struct EditOperationModeButton: View {
+ let theme: AppGridTheme
let operation: EditTagOperation
let mode: EditTagOperation
let titleKey: String
@@ -97,23 +129,24 @@
ZStack {
Circle()
.strokeBorder(
- isActive ? Color.accentColor : Color.secondary.opacity(0.58),
+ isActive ? theme.editAccentColor : theme.editInactiveIndicatorColor,
lineWidth: 1.6
)
.frame(width: 13, height: 13)
if isActive {
Circle()
- .fill(Color.accentColor)
+ .fill(theme.editAccentColor)
.frame(width: 7, height: 7)
}
}
Text(tr(titleKey))
.font(.system(size: 12, weight: .semibold))
- .foregroundStyle(isActive ? Color.primary : Color.secondary)
+ .foregroundStyle(isActive ? theme.editPrimaryTextColor : theme.editSecondaryTextColor)
.lineLimit(1)
}
.padding(.vertical, 4)
+ .padding(.horizontal, 2)
.contentShape(Rectangle())
}
.buttonStyle(.plain)
@@ -123,6 +156,7 @@
}
private struct EditConfirmButton: View {
+ let theme: AppGridTheme
let title: String
let isDisabled: Bool
let action: () -> Void
@@ -131,7 +165,7 @@
Button(action: action) {
Text(title)
.font(.system(size: 13, weight: .semibold))
- .foregroundStyle(Color.white.opacity(isDisabled ? 0.76 : 1.0))
+ .foregroundStyle(isDisabled ? theme.editDisabledTextColor : theme.editConfirmForegroundColor)
.lineLimit(1)
.minimumScaleFactor(0.82)
.frame(minWidth: 116)
@@ -139,20 +173,22 @@
.padding(.horizontal, 8)
.background(
RoundedRectangle(cornerRadius: 8, style: .continuous)
- .fill(Color.accentColor.opacity(isDisabled ? 0.40 : 1.0))
+ .fill(isDisabled ? theme.editDisabledSurfaceColor : theme.editAccentColor)
)
.overlay(
RoundedRectangle(cornerRadius: 8, style: .continuous)
- .stroke(Color.accentColor.opacity(isDisabled ? 0.18 : 0.24), lineWidth: 1)
+ .stroke(isDisabled ? theme.editControlStrokeColor : theme.editAccentColor.opacity(0.72), lineWidth: 1)
)
}
.buttonStyle(.plain)
.disabled(isDisabled)
.contentShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
+ .shadow(color: isDisabled ? Color.clear : theme.editButtonShadowColor, radius: 12, y: 5)
}
}
struct EditAppsSidebarIntroView: View {
+ let theme: AppGridTheme
let width: CGFloat
let horizontalInset: CGFloat
@@ -160,7 +196,7 @@
VStack(alignment: .leading, spacing: 6) {
Text(tr("edit.selectTags"))
.font(.caption)
- .foregroundStyle(.secondary)
+ .foregroundStyle(theme.editSecondaryTextColor)
.lineLimit(2)
.fixedSize(horizontal: false, vertical: true)
.multilineTextAlignment(.leading)
@@ -168,7 +204,7 @@
Text(tr("edit.dragHint"))
.font(.caption2)
- .foregroundStyle(.tertiary)
+ .foregroundStyle(theme.editTertiaryTextColor)
.lineLimit(nil)
.fixedSize(horizontal: false, vertical: true)
.multilineTextAlignment(.leading)
@@ -188,6 +224,7 @@
let operation: EditTagOperation
let isSelected: Bool
let isRemovableCandidate: Bool
+ let theme: AppGridTheme
let onToggle: () -> Void
private var isEnabled: Bool {
@@ -205,7 +242,7 @@
var body: some View {
HStack(spacing: 6) {
Circle()
- .fill(isSelected ? Color.accentColor : Color.secondary.opacity(isEnabled ? 0.3 : 0.18))
+ .fill(isSelected ? theme.editAccentColor : theme.editInactiveIndicatorColor.opacity(isEnabled ? 1.0 : 0.56))
.frame(width: 16, height: 16)
.overlay(
isSelected
@@ -217,7 +254,7 @@
Text(displayName)
.font(.system(size: 13, weight: isUncommon ? .semibold : .medium))
- .foregroundStyle(isEnabled ? Color.primary : Color.secondary.opacity(0.66))
+ .foregroundStyle(isEnabled ? theme.editPrimaryTextColor : theme.editDisabledTextColor)
.lineLimit(1)
.truncationMode(.tail)
.frame(maxWidth: .infinity, alignment: .leading)
@@ -226,13 +263,13 @@
if isUncommon {
Image(systemName: "questionmark.bubble.fill")
.font(.system(size: 11, weight: .semibold))
- .foregroundStyle(isEnabled ? Color.secondary : Color.secondary.opacity(0.55))
+ .foregroundStyle(isEnabled ? theme.editSecondaryTextColor : theme.editDisabledTextColor)
.frame(width: 16, height: 16)
}
if showsPendingRemoval {
Image(systemName: "trash.fill")
.font(.system(size: 11, weight: .bold))
- .foregroundStyle(.red)
+ .foregroundStyle(Color.red.opacity(theme.usesDarkGlass ? 0.96 : 0.84))
.frame(width: 16, height: 16)
.transition(.scale(scale: 0.85).combined(with: .opacity))
} else if operation == .remove {
@@ -255,9 +292,13 @@
.fill(
Color(
nsColor: TagColor.nsColor(for: colorIndex)
- .withAlphaComponent(isEnabled ? (isUncommon ? 0.22 : 0.3) : 0.12)
+ .withAlphaComponent(isEnabled ? (isUncommon ? 0.26 : 0.34) : 0.16)
)
)
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 6)
+ .stroke(theme.editControlStrokeColor.opacity(isSelected ? 1.0 : 0.44), lineWidth: isSelected ? 1.1 : 0.6)
)
.contentShape(RoundedRectangle(cornerRadius: 6))
.onTapGesture {
@@ -273,6 +314,7 @@
let app: AppInfo
let iconSize: CGFloat
let isSelected: Bool
+ let theme: AppGridTheme
let onToggle: () -> Void
var body: some View {
@@ -285,7 +327,7 @@
.frame(width: iconSize, height: iconSize)
Circle()
- .fill(isSelected ? Color.accentColor : Color.secondary.opacity(0.3))
+ .fill(isSelected ? theme.editAccentColor : theme.editInactiveIndicatorColor)
.frame(width: 20, height: 20)
.overlay(
isSelected
@@ -299,6 +341,7 @@
Text(app.displayName)
.font(.system(size: 11, weight: .medium))
+ .foregroundStyle(theme.editPrimaryTextColor)
.lineLimit(1)
.truncationMode(.tail)
.frame(maxWidth: iconSize + 20)
@@ -307,6 +350,14 @@
.padding(.horizontal, 4)
.contentShape(RoundedRectangle(cornerRadius: 10))
.opacity(isSelected ? 1.0 : 0.65)
+ .background(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .fill(isSelected ? theme.editControlSurfaceColor : Color.clear)
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .stroke(isSelected ? theme.editControlStrokeColor : Color.clear, lineWidth: 1)
+ )
}
.buttonStyle(.plain)
}
@@ -391,9 +442,9 @@
}
Text(message)
- .font(.system(size: 15, weight: .medium))
- .lineSpacing(4)
- .foregroundStyle(.white.opacity(0.84))
+ .font(.system(size: 17, weight: .semibold))
+ .lineSpacing(5)
+ .foregroundStyle(.white.opacity(0.70))
.multilineTextAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
.frame(maxWidth: .infinity, alignment: .leading)
@@ -570,3 +621,222 @@
.onExitCommand(perform: onCancel)
}
}
+
+struct UsageTipsCloseReminderBubble: View {
+ let title: String
+ let message: String
+ let previewCallout: String
+ let doNotRemindTitle: String
+ @Binding var doNotRemind: Bool
+ let confirmTitle: String
+ let onCancel: () -> Void
+ let onConfirm: () -> Void
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 16) {
+ HStack(alignment: .top, spacing: 12) {
+ Text(title)
+ .font(.system(size: 22, weight: .bold))
+ .foregroundStyle(.white)
+ .fixedSize(horizontal: false, vertical: true)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ Button(action: onCancel) {
+ Image(systemName: "xmark")
+ .font(.system(size: 12, weight: .bold))
+ .foregroundStyle(.white.opacity(0.82))
+ .frame(width: 26, height: 26)
+ .background(Circle().fill(Color.white.opacity(0.12)))
+ }
+ .buttonStyle(.plain)
+ .help(tr("tag.cancel"))
+ }
+
+ UsageTipsCloseReminderSettingsPreview(callout: previewCallout)
+
+ Text(message)
+ .font(.system(size: 15, weight: .medium))
+ .lineSpacing(4)
+ .foregroundStyle(.white.opacity(0.84))
+ .multilineTextAlignment(.leading)
+ .fixedSize(horizontal: false, vertical: true)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ HStack(alignment: .bottom, spacing: 16) {
+ Button {
+ doNotRemind.toggle()
+ } label: {
+ HStack(spacing: 10) {
+ ZStack {
+ RoundedRectangle(cornerRadius: 4, style: .continuous)
+ .fill(doNotRemind ? Color.accentColor : Color.white.opacity(0.10))
+ RoundedRectangle(cornerRadius: 4, style: .continuous)
+ .stroke(Color.white.opacity(0.92), lineWidth: 1.6)
+ if doNotRemind {
+ Image(systemName: "checkmark")
+ .font(.system(size: 12, weight: .bold))
+ .foregroundStyle(.white)
+ }
+ }
+ .frame(width: 18, height: 18)
+
+ Text(doNotRemindTitle)
+ .font(.system(size: 13, weight: .semibold))
+ .foregroundStyle(.white.opacity(0.86))
+ .lineLimit(2)
+ .multilineTextAlignment(.leading)
+ }
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .contentShape(Rectangle())
+ }
+ .buttonStyle(.plain)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ Button(action: onConfirm) {
+ Text(confirmTitle)
+ .font(.system(size: 13, weight: .semibold))
+ .foregroundStyle(.white)
+ .frame(minWidth: 96)
+ .frame(height: 32)
+ .padding(.horizontal, 10)
+ .background(
+ RoundedRectangle(cornerRadius: 8, style: .continuous)
+ .fill(Color.accentColor)
+ )
+ }
+ .buttonStyle(.plain)
+ }
+ .padding(.top, 4)
+ }
+ .padding(.horizontal, 24)
+ .padding(.vertical, 20)
+ .background(
+ RoundedRectangle(cornerRadius: 18, style: .continuous)
+ .fill(Color.black.opacity(0.92))
+ .shadow(color: .black.opacity(0.34), radius: 24, y: 16)
+ .shadow(color: .black.opacity(0.18), radius: 8, y: 3)
+ )
+ .onExitCommand(perform: onCancel)
+ }
+}
+
+private struct UsageTipsCloseReminderSettingsPreview: View {
+ let callout: String
+
+ var body: some View {
+ VStack(alignment: .leading, spacing: 10) {
+ HStack(spacing: 6) {
+ Circle().fill(Color.red.opacity(0.78)).frame(width: 10, height: 10)
+ Circle().fill(Color.gray.opacity(0.45)).frame(width: 10, height: 10)
+ Circle().fill(Color.gray.opacity(0.36)).frame(width: 10, height: 10)
+ Text(verbatim: "TagLauncher Settings")
+ .font(.system(size: 11, weight: .semibold))
+ .foregroundStyle(Color.black.opacity(0.62))
+ .padding(.leading, 6)
+ Spacer()
+ }
+
+ HStack(spacing: 18) {
+ previewTab(systemImage: "globe", title: tr("settings.language"), active: false)
+ previewTab(systemImage: "gearshape", title: tr("settings.general"), active: true)
+ previewTab(systemImage: "keyboard", title: tr("quickSearch.hotkeys"), active: false)
+ previewTab(systemImage: "tag", title: tr("settings.tags"), active: false)
+ previewTab(systemImage: "externaldrive.fill", title: tr("settings.data"), active: false)
+ previewTab(systemImage: "info.circle", title: tr("settings.about"), active: false)
+ }
+ .frame(maxWidth: .infinity, alignment: .center)
+ .padding(.vertical, 8)
+
+ HStack(spacing: 12) {
+ previewCheckbox(title: tr("settings.launchAtLogin"), highlighted: false)
+ previewCheckbox(title: tr("settings.showInDock"), highlighted: false)
+ previewCheckbox(title: tr("settings.hideAppNames"), highlighted: false)
+ previewCheckbox(title: tr("settings.hideUsageTips"), highlighted: true)
+ }
+ .frame(maxWidth: .infinity, alignment: .center)
+ .padding(10)
+ .background(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .fill(Color.white.opacity(0.84))
+ )
+
+ HStack(spacing: 8) {
+ Image(systemName: "arrow.up.left")
+ .font(.system(size: 12, weight: .bold))
+ .foregroundStyle(Color.accentColor)
+ Text(callout)
+ .font(.system(size: 11, weight: .semibold))
+ .foregroundStyle(Color.accentColor)
+ .lineLimit(2)
+ .multilineTextAlignment(.center)
+ .fixedSize(horizontal: false, vertical: true)
+ }
+ .frame(maxWidth: .infinity, alignment: .trailing)
+ .padding(.trailing, 44)
+ }
+ .padding(14)
+ .background(
+ RoundedRectangle(cornerRadius: 14, style: .continuous)
+ .fill(
+ LinearGradient(
+ colors: [
+ Color.white.opacity(0.98),
+ Color(red: 0.93, green: 0.96, blue: 1.0).opacity(0.96)
+ ],
+ startPoint: .topLeading,
+ endPoint: .bottomTrailing
+ )
+ )
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 14, style: .continuous)
+ .stroke(Color.white.opacity(0.64), lineWidth: 1)
+ )
+ }
+
+ private func previewTab(systemImage: String, title: String, active: Bool) -> some View {
+ VStack(spacing: 4) {
+ Image(systemName: systemImage)
+ .font(.system(size: 18, weight: .semibold))
+ Text(title)
+ .font(.system(size: 9, weight: .semibold))
+ .lineLimit(1)
+ .minimumScaleFactor(0.62)
+ }
+ .foregroundStyle(active ? Color.accentColor : Color.gray.opacity(0.82))
+ .frame(width: 70, height: 48)
+ .background(
+ RoundedRectangle(cornerRadius: 9, style: .continuous)
+ .fill(active ? Color.accentColor.opacity(0.12) : Color.clear)
+ )
+ }
+
+ private func previewCheckbox(title: String, highlighted: Bool) -> some View {
+ HStack(spacing: 6) {
+ ZStack {
+ RoundedRectangle(cornerRadius: 4, style: .continuous)
+ .fill(highlighted ? Color.accentColor : Color.gray.opacity(0.24))
+ Image(systemName: "checkmark")
+ .font(.system(size: 9, weight: .bold))
+ .foregroundStyle(.white)
+ }
+ .frame(width: 16, height: 16)
+
+ Text(title)
+ .font(.system(size: 10, weight: highlighted ? .bold : .semibold))
+ .foregroundStyle(Color.black.opacity(0.72))
+ .lineLimit(1)
+ .minimumScaleFactor(0.58)
+ }
+ .padding(.horizontal, 8)
+ .frame(height: 30)
+ .background(
+ RoundedRectangle(cornerRadius: 8, style: .continuous)
+ .fill(highlighted ? Color.accentColor.opacity(0.12) : Color.clear)
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 8, style: .continuous)
+ .stroke(highlighted ? Color.accentColor.opacity(0.72) : Color.clear, lineWidth: 1.5)
+ )
+ }
+}
--
Gitblit v1.9.3