feat(app): add flow diagnostics and refine interface
Improve failure recovery visibility, strengthen account-session handling, and make the cross-platform interface more consistent.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user