feat(app): add flow diagnostics and refine interface
CI / Validate manifests (push) Has been cancelled
CI / SwiftLint (push) Has been cancelled
CI / iOS / Extension (push) Has been cancelled
CI / macOS (push) Has been cancelled

Improve failure recovery visibility, strengthen account-session handling, and make the cross-platform interface more consistent.
This commit is contained in:
Rocky
2026-08-26 14:40:06 +08:00
parent 1ee032bdb9
commit 39002336c0
78 changed files with 2737 additions and 735 deletions
+5 -5
View File
@@ -104,9 +104,9 @@ struct MacToggleStyle: ToggleStyle {
Capsule()
.fill(configuration.isOn ? palette.accent : offTrackColor)
Circle()
.fill(Color.white)
.fill(OSGColor.macToggleKnob)
.frame(width: 16, height: 16)
.shadow(color: .black.opacity(0.25), radius: 1, y: 1)
.shadow(color: OSGColor.macToggleKnobShadow, radius: 1, y: 1)
.padding(2)
}
.frame(width: 36, height: 20)
@@ -117,8 +117,8 @@ struct MacToggleStyle: ToggleStyle {
private var offTrackColor: Color {
colorScheme == .dark
? Color.white.opacity(0.18)
: Color.black.opacity(0.15)
? OSGColor.macToggleOffTrackDark
: OSGColor.macToggleOffTrackLight
}
}
@@ -411,7 +411,7 @@ struct MacHeaderActionButtonStyle: ButtonStyle {
configuration.label
.padding(.horizontal, Spacing.md)
.frame(height: MacMetrics.pageHeaderControlHeight)
.foregroundStyle(.white)
.foregroundStyle(OSGColor.fixedLightContent)
.background(
palette.accent.opacity(configuration.isPressed ? 0.82 : 1),
in: Capsule()
+1 -1
View File
@@ -71,7 +71,7 @@ struct MacDictationOverlayView: View {
Capsule(style: .continuous)
.stroke(palette.dividerStrong, lineWidth: 0.5)
)
.shadow(color: Color.black.opacity(0.22), radius: 14, y: 5)
.shadow(color: OSGColor.macOverlayShadow, radius: 14, y: 5)
.padding(Self.shadowMargin)
.contentShape(Capsule(style: .continuous))
// Manual drag: `isMovableByWindowBackground` doesn't work on a
+7 -3
View File
@@ -173,7 +173,7 @@ struct MacDictionaryView: View {
}
.padding(.horizontal, Spacing.sm)
.frame(width: 220, height: MacMetrics.pageHeaderControlHeight)
.background(palette.surface, in: Capsule())
.background(palette.formSurface, in: Capsule())
.overlay(Capsule().stroke(palette.divider, lineWidth: 0.5))
}
@@ -289,9 +289,13 @@ private struct MacDictionaryEntryEditor: View {
Button(MacL10n.string("mac.cancel", language: language)) {
dismiss()
}
Button(MacL10n.string("mac.save", language: language), action: save)
.tint(palette.textPrimary)
Button(action: save) {
Text(MacL10n.string("mac.save", language: language))
.foregroundStyle(palette.background)
}
.buttonStyle(.borderedProminent)
.tint(palette.accent)
.tint(palette.textPrimary)
.disabled(trimmedTerm.isEmpty)
}
}
@@ -385,7 +385,7 @@ struct MacLocalASRModelSettingsView: View {
MacSettingsToolButton(
title: MacL10n.string("mac.localASR.download", language: lang),
fill: palette.accent,
foreground: .white
foreground: OSGColor.fixedLightContent
) {
modelVM.installModel(model)
}
+3 -1
View File
@@ -272,7 +272,9 @@ struct MacOnboardingView: View {
.resizable()
.scaledToFit()
.frame(width: 128, height: 128)
.foregroundStyle(colorScheme == .dark ? Color.white : palette.accent)
.foregroundStyle(
colorScheme == .dark ? OSGColor.fixedLightContent : palette.accent
)
.accessibilityLabel("OSGKeyboard")
.allowsHitTesting(false)
}
+1 -1
View File
@@ -514,7 +514,7 @@ private struct MacPolishStyleEditor: View {
.font(.body.monospaced())
.frame(minHeight: 320)
.padding(4)
.background(palette.surface, in: RoundedRectangle(cornerRadius: Radius.medium))
.background(palette.formSurface, in: RoundedRectangle(cornerRadius: Radius.medium))
.overlay(
RoundedRectangle(cornerRadius: Radius.medium)
.stroke(palette.divider, lineWidth: 1)
+3 -3
View File
@@ -421,14 +421,14 @@ struct MacProviderModelRow: View {
HStack(spacing: Spacing.sm) {
Text(modelId)
.font(TypeStyle.mono)
.foregroundStyle(isSelected ? palette.accent : palette.textPrimary)
.foregroundStyle(palette.textPrimary)
.lineLimit(1)
.truncationMode(.middle)
Spacer(minLength: 0)
if isSelected {
Image(systemName: "checkmark")
.font(.system(size: 11, weight: .semibold))
.foregroundStyle(palette.accent)
.foregroundStyle(palette.textPrimary)
}
}
.padding(.horizontal, Spacing.sm)
@@ -436,7 +436,7 @@ struct MacProviderModelRow: View {
.frame(maxWidth: .infinity, alignment: .leading)
.background(
RoundedRectangle(cornerRadius: Radius.small, style: .continuous)
.fill(isSelected ? palette.accentMuted : Color.clear)
.fill(isSelected ? palette.textPrimary.opacity(0.10) : Color.clear)
)
.contentShape(Rectangle())
}
@@ -56,6 +56,7 @@ struct MacSupportDeveloperTipRows: View {
Button(SharedL10n.string("tip.alert.dismiss", language: language)) {
tipManager.acknowledgePurchaseState()
}
.tint(palette.textPrimary)
} message: {
Text(SharedL10n.string("tip.thankYou.message", language: language))
}
@@ -66,6 +67,7 @@ struct MacSupportDeveloperTipRows: View {
Button(SharedL10n.string("tip.alert.dismiss", language: language)) {
tipManager.acknowledgePurchaseState()
}
.tint(palette.textPrimary)
} message: {
Text(errorMessage)
}
+18 -13
View File
@@ -30,6 +30,7 @@ enum MacSystemPalette {
ThemePalette(
background: resolved(dark ? darkBackground : warmBackground, dark: dark),
surface: resolved(dark ? darkSurface : warmSurface, dark: dark),
formSurface: resolved(dark ? darkFormSurface : warmFormSurface, dark: dark),
surfaceElevated: resolved(dark ? darkElevated : warmElevated, dark: dark),
surfaceMuted: resolved(dark ? darkMuted : warmMuted, dark: dark),
@@ -45,14 +46,14 @@ enum MacSystemPalette {
textPrimary: resolved(.labelColor, dark: dark),
textSecondary: resolved(.secondaryLabelColor, dark: dark),
textTertiary: resolved(.tertiaryLabelColor, dark: dark),
textOnAccent: Color.white,
textOnAccent: OSGColor.fixedLightContent,
divider: dark
? Color.white.opacity(0.08)
: Color.black.opacity(0.06),
? OSGColor.macDarkDivider
: OSGColor.lightDivider,
dividerStrong: dark
? Color.white.opacity(0.12)
: Color.black.opacity(0.10),
? OSGColor.macDarkDividerStrong
: OSGColor.lightDividerStrong,
recordRed: resolved(.systemRed, dark: dark),
recordBlue: resolved(.systemBlue, dark: dark)
@@ -62,13 +63,15 @@ enum MacSystemPalette {
// MARK: - Warm Light-mode surfaces (matched to iOS `Palette.light`)
/// #F2F1EE warm gray page background.
private static let warmBackground = NSColor(srgbRed: 0.949, green: 0.945, blue: 0.933, alpha: 1)
private static let warmBackground = NSColor(OSGColor.lightBackground)
/// #FCFBF9 warm off-white card/control surface.
private static let warmSurface = NSColor(srgbRed: 0.988, green: 0.984, blue: 0.976, alpha: 1)
private static let warmSurface = NSColor(OSGColor.lightSurface)
/// #FCFBF9 forms retain the ordinary card fill in light mode.
private static let warmFormSurface = warmSurface
/// #EBEAE7 slightly recessed elevated surface.
private static let warmElevated = NSColor(srgbRed: 0.922, green: 0.918, blue: 0.906, alpha: 1)
private static let warmElevated = NSColor(OSGColor.lightSurfaceElevated)
/// #EEEDE9 muted fill between background and surface.
private static let warmMuted = NSColor(srgbRed: 0.933, green: 0.929, blue: 0.918, alpha: 1)
private static let warmMuted = NSColor(OSGColor.lightSurfaceMuted)
// MARK: - Dark-mode surfaces (Apple standard elevated grays)
//
@@ -78,13 +81,15 @@ enum MacSystemPalette {
// clearly elevated above the background mirroring the iOS dark palette.
/// #1C1C1E page background.
private static let darkBackground = NSColor(srgbRed: 0.110, green: 0.110, blue: 0.118, alpha: 1)
private static let darkBackground = NSColor(OSGColor.macDarkBackground)
/// #2C2C2E card / control surface, clearly lighter than the background.
private static let darkSurface = NSColor(srgbRed: 0.173, green: 0.173, blue: 0.180, alpha: 1)
private static let darkSurface = NSColor(OSGColor.macDarkSurface)
/// #343438 interactive form fill between cards and elevated chrome.
private static let darkFormSurface = NSColor(OSGColor.macDarkFormSurface)
/// #3A3A3C elevated fill for selected / raised chrome.
private static let darkElevated = NSColor(srgbRed: 0.227, green: 0.227, blue: 0.235, alpha: 1)
private static let darkElevated = NSColor(OSGColor.macDarkSurfaceElevated)
/// #242426 muted fill between background and surface.
private static let darkMuted = NSColor(srgbRed: 0.141, green: 0.141, blue: 0.149, alpha: 1)
private static let darkMuted = NSColor(OSGColor.macDarkSurfaceMuted)
/// Resolves a (possibly dynamic) AppKit colour to its concrete value under
/// the requested appearance, so the two static palettes differ by value.