release(ios): 0.2.2 构建 8 中性化批量标签禁用态并去蓝化图标底色
- FleetTagBatchSheet:无勾选时标签胶囊不再走 Button 禁用态(系统会压成灰块,像加载 失败),改为中性标签原样渲染;覆盖度文案留空,图标改 tag;新建标签输入与按钮置灰 并补一句「勾选节点后即可新建标签并批量贴上」。 - 应用图标:底色与插槽从偏青绿的石墨(R>G=B,亮壁纸上读作蓝)改为严格等值中性灰 20/19/10,金色跨度拉大(#FADD98 -> #C78D2F)去掉芥末黄塑料感;AppIcon.svg 同步。 - 版本号:marketing 0.2.2 不带括号,构建号 7 -> 8;文档里 0.2.x (N) 一律改写为 「0.2.x 构建 N」,README 与现行说明同步。
This commit is contained in:
@@ -2,5 +2,5 @@ public enum AppMetadata {
|
||||
public static let name = "MultiSimAdmin"
|
||||
public static let bundleIdentifier = "fun.chick.multi-simadmin"
|
||||
public static let marketingVersion = "0.2.2"
|
||||
public static let buildVersion = "7"
|
||||
public static let buildVersion = "8"
|
||||
}
|
||||
|
||||
@@ -102,10 +102,16 @@ struct FleetTagBatchSheet: View {
|
||||
.accessibilityLabel("新标签名称")
|
||||
.submitLabel(.done)
|
||||
.onSubmit { submitDraft() }
|
||||
.disabled(isBusy)
|
||||
.disabled(isBusy || targets.isEmpty)
|
||||
Button(isBusy ? "处理中" : "添加") { submitDraft() }
|
||||
.buttonStyle(AIButtonStyle(kind: .primary, size: .regular, fixedWidth: 84))
|
||||
.disabled(draft.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isBusy)
|
||||
.disabled(draft.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty || isBusy || targets.isEmpty)
|
||||
}
|
||||
// 没有勾选节点时这个表单按下去只会清空输入,先说清楚为什么不能动。
|
||||
if targets.isEmpty {
|
||||
Text("勾选节点后即可新建标签并批量贴上。")
|
||||
.font(.caption2)
|
||||
.foregroundStyle(AITheme.faint)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,44 +141,87 @@ struct FleetTagBatchSheet: View {
|
||||
|
||||
private var isComplete: Bool { total > 0 && covered == total }
|
||||
private var isPartial: Bool { covered > 0 && covered < total }
|
||||
// 没有勾选任何节点时这一整片都是不可操作状态,此时不该用「未贴」这种带暗示的
|
||||
// 灰字,直接按中性标签渲染,避免看起来像加载失败的禁用控件。
|
||||
private var isInert: Bool { total == 0 }
|
||||
|
||||
private var stateText: String {
|
||||
if isInert { return "" }
|
||||
if isComplete { return "全部" }
|
||||
if isPartial { return "\(covered)/\(total)" }
|
||||
return "未贴"
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Button(action: action) {
|
||||
HStack(spacing: 6) {
|
||||
Image(systemName: isComplete ? "checkmark.circle.fill" : (isPartial ? "circle.lefthalf.filled" : "circle"))
|
||||
.font(.system(size: 12, weight: .semibold))
|
||||
.accessibilityHidden(true)
|
||||
Text(title)
|
||||
.font(.footnote.weight(isComplete || isPartial ? .semibold : .medium))
|
||||
.lineLimit(1)
|
||||
.truncationMode(.middle)
|
||||
if isInert {
|
||||
// 不可操作时不渲染 Button:系统禁用态会把整枚胶囊压成灰色,
|
||||
// 看起来像加载失败,而标签本身是需要读清楚的内容。
|
||||
label
|
||||
.accessibilityLabel("标签 \(title),勾选节点后可贴上")
|
||||
} else {
|
||||
Button(action: action) { label }
|
||||
.buttonStyle(.plain)
|
||||
.disabled(isBusy)
|
||||
.accessibilityLabel(isComplete ? "从已选节点移除标签 \(title)" : "给已选节点贴上标签 \(title)")
|
||||
.accessibilityAddTraits(isComplete ? [.isButton, .isSelected] : .isButton)
|
||||
}
|
||||
}
|
||||
|
||||
private var label: some View {
|
||||
HStack(spacing: 6) {
|
||||
Image(systemName: iconName)
|
||||
.font(.system(size: 12, weight: .semibold))
|
||||
.accessibilityHidden(true)
|
||||
Text(title)
|
||||
.font(.footnote.weight(isComplete || isPartial ? .semibold : .medium))
|
||||
.lineLimit(1)
|
||||
.truncationMode(.middle)
|
||||
if stateText.isEmpty == false {
|
||||
Text(stateText)
|
||||
.font(.caption2.weight(.semibold))
|
||||
.monospacedDigit()
|
||||
.opacity(0.72)
|
||||
Spacer(minLength: 0)
|
||||
}
|
||||
.padding(.horizontal, 10)
|
||||
.frame(height: 38)
|
||||
.foregroundStyle(isComplete ? AITheme.onPrimary : (isPartial ? AITheme.ink : AITheme.muted))
|
||||
.background(isComplete ? AITheme.primary : (isPartial ? AITheme.tile : AITheme.surface))
|
||||
.clipShape(Capsule(style: .continuous))
|
||||
.overlay {
|
||||
Capsule(style: .continuous)
|
||||
.strokeBorder(isComplete ? AITheme.primary : (isPartial ? AITheme.primary.opacity(0.42) : AITheme.line))
|
||||
}
|
||||
.contentShape(Capsule(style: .continuous))
|
||||
Spacer(minLength: 0)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.disabled(isBusy || total == 0)
|
||||
.accessibilityLabel(isComplete ? "从已选节点移除标签 \(title)" : "给已选节点贴上标签 \(title)")
|
||||
.accessibilityAddTraits(isComplete ? [.isButton, .isSelected] : .isButton)
|
||||
.padding(.horizontal, 10)
|
||||
.frame(height: 38)
|
||||
.foregroundStyle(foreground)
|
||||
.background(background)
|
||||
.clipShape(Capsule(style: .continuous))
|
||||
.overlay {
|
||||
Capsule(style: .continuous)
|
||||
.strokeBorder(border)
|
||||
}
|
||||
.contentShape(Capsule(style: .continuous))
|
||||
}
|
||||
|
||||
private var iconName: String {
|
||||
if isInert { return "tag" }
|
||||
if isComplete { return "checkmark.circle.fill" }
|
||||
if isPartial { return "circle.lefthalf.filled" }
|
||||
return "circle"
|
||||
}
|
||||
|
||||
private var foreground: Color {
|
||||
if isInert { return AITheme.ink }
|
||||
if isComplete { return AITheme.onPrimary }
|
||||
if isPartial { return AITheme.ink }
|
||||
return AITheme.muted
|
||||
}
|
||||
|
||||
private var background: Color {
|
||||
if isInert { return AITheme.tile }
|
||||
if isComplete { return AITheme.primary }
|
||||
if isPartial { return AITheme.tile }
|
||||
return AITheme.surface
|
||||
}
|
||||
|
||||
private var border: Color {
|
||||
if isInert { return AITheme.tileLine }
|
||||
if isComplete { return AITheme.primary }
|
||||
if isPartial { return AITheme.primary.opacity(0.42) }
|
||||
return AITheme.line
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 936 KiB After Width: | Height: | Size: 812 KiB |
@@ -10,7 +10,7 @@
|
||||
<key>CFBundleName</key><string>MultiSimAdmin</string>
|
||||
<key>CFBundlePackageType</key><string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key><string>0.2.2</string>
|
||||
<key>CFBundleVersion</key><string>7</string>
|
||||
<key>CFBundleVersion</key><string>8</string>
|
||||
<key>LSRequiresIPhoneOS</key><true/>
|
||||
<key>MinimumOSVersion</key><string>16.0</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
||||
Reference in New Issue
Block a user