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
+13 -5
View File
@@ -371,7 +371,9 @@ struct TypingRootView: View {
}
private var expandChevronFill: Color {
colorScheme == .dark ? Color(white: 0.30) : .white
colorScheme == .dark
? OSGColor.keyboardDarkInputFill
: OSGColor.fixedLightContent
}
// MARK: - Editing toolbar (iPad)
@@ -423,7 +425,9 @@ struct TypingRootView: View {
}
private var editingToolbarButtonFill: Color {
colorScheme == .dark ? Color(white: 0.30) : .white
colorScheme == .dark
? OSGColor.keyboardDarkInputFill
: OSGColor.fixedLightContent
}
/// UIKit-recycled labels no SwiftUI Button per candidate.
@@ -773,7 +777,9 @@ struct TypingRootView: View {
}
private var selectedCandidateFill: Color {
colorScheme == .dark ? Color(white: 0.36) : .white
colorScheme == .dark
? OSGColor.keyboardDarkInputFillRaised
: OSGColor.fixedLightContent
}
private var returnKeyFill: Color {
@@ -786,7 +792,9 @@ struct TypingRootView: View {
private var returnKeyBorder: Color {
if state.returnKeyRole.usesActionFill {
return Color.black.opacity(colorScheme == .dark ? 0.10 : 0.08)
return colorScheme == .dark
? OSGColor.keyboardActionBorderDark
: OSGColor.keyboardActionBorderLight
}
return palette.divider
}
@@ -799,7 +807,7 @@ struct TypingRootView: View {
}
private var returnKeyTextColor: Color {
state.returnKeyRole.usesActionFill ? .white : keyTextColor
state.returnKeyRole.usesActionFill ? OSGColor.fixedLightContent : keyTextColor
}
/// The send key stays recognizable in both appearances without becoming neon.
+8 -8
View File
@@ -188,7 +188,7 @@ struct AIKeyboardView: View {
Button(action: state.confirmPendingAIAnswer) {
Image(systemName: "plus")
.font(.system(size: 20, weight: .semibold))
.foregroundStyle(.white)
.foregroundStyle(OSGColor.fixedLightContent)
.frame(width: Layout.fieldActionWidth, height: 44)
.background(palette.accent, in: Capsule())
}
@@ -709,13 +709,13 @@ struct AIKeyboardView: View {
if state.assistantInsertionSucceeded {
Image(systemName: "checkmark")
.font(.system(size: 27, weight: .bold))
.foregroundStyle(.white)
.foregroundStyle(OSGColor.fixedLightContent)
} else {
switch state.aiSession.phase {
case .listening:
waveform(color: .white)
waveform(color: OSGColor.fixedLightContent)
case .preparing, .recognizing, .generating:
ProgressView().tint(.white)
ProgressView().tint(OSGColor.fixedLightContent)
case .inactive, .idle, .ready, .awaitingSend, .inserted, .sent, .failed:
ordinaryMicrophoneContent
}
@@ -726,17 +726,17 @@ struct AIKeyboardView: View {
private var ordinaryMicrophoneContent: some View {
switch state.phase {
case .recording:
waveform(color: Color(red: 1, green: 0.78, blue: 0.78))
waveform(color: OSGColor.recordingWaveform)
case .requestingPermissions, .processing:
ProgressView().tint(.white)
ProgressView().tint(OSGColor.fixedLightContent)
case .error:
Image(systemName: "exclamationmark.triangle.fill")
.font(.system(size: 25, weight: .semibold))
.foregroundStyle(.white)
.foregroundStyle(OSGColor.fixedLightContent)
case .idle, .denied:
Image(systemName: "mic.fill")
.font(.system(size: 28, weight: .semibold))
.foregroundStyle(.white)
.foregroundStyle(OSGColor.fixedLightContent)
.symbolEffect(.breathe, isActive: micIsHoldingForAI)
}
}
@@ -104,7 +104,7 @@ struct ClipboardEnableGuideView: View {
Button(action: onOpenSettings) {
ExtL10n.text("keyboard.clipboard.guide.cta")
.font(.system(size: 15, weight: .semibold))
.foregroundStyle(.white)
.foregroundStyle(OSGColor.fixedLightContent)
.padding(.horizontal, 20)
.padding(.vertical, 10)
.background(palette.accent, in: Capsule())
@@ -222,6 +222,7 @@ struct ClipboardHistoryPanelView: View {
}
.buttonStyle(.glass)
.buttonBorderShape(.capsule)
.tint(palette.textPrimary)
Button {
// Dismiss the popup before publishing an empty history
@@ -231,12 +232,13 @@ struct ClipboardHistoryPanelView: View {
} label: {
ExtL10n.text("keyboard.clipboard.clear.confirm")
.font(.system(size: 13, weight: .semibold))
.foregroundStyle(palette.background)
.frame(maxWidth: .infinity)
.frame(height: 36)
}
.buttonStyle(.glassProminent)
.buttonBorderShape(.capsule)
.tint(palette.accent)
.tint(palette.textPrimary)
}
}
.padding(16)
+11 -3
View File
@@ -43,7 +43,11 @@ struct KeyboardBrandLogo: View {
.resizable()
.renderingMode(.template)
.scaledToFit()
.foregroundStyle(colorScheme == .dark ? Color.white : Color.black)
.foregroundStyle(
colorScheme == .dark
? OSGColor.fixedLightContent
: OSGColor.fixedDarkContent
)
.frame(
width: KeyboardTopBarMetrics.logoWidth,
height: KeyboardTopBarMetrics.logoHeight
@@ -222,13 +226,17 @@ struct KeyboardTopControls: View {
}
private var pressedFill: Color {
colorScheme == .dark ? Color(white: 0.22) : Color(white: 0.84)
colorScheme == .dark
? OSGColor.keyboardDarkControlFill
: OSGColor.keyboardLightKeyPressed
}
/// NativeKeyboardKeyColors.fill
/// 宿
private var tabTrackFill: Color {
colorScheme == .dark ? Color(white: 0.12) : Color.black.opacity(0.12)
colorScheme == .dark
? OSGColor.keyboardDarkControlBorder
: OSGColor.keyboardLightControlBorder
}
private func isSelected(_ tab: KeyboardInputTab) -> Bool {
+5 -5
View File
@@ -123,7 +123,7 @@ struct LastInputEditView: View {
Color.clear
if case .listening = state.editSession {
Capsule()
.stroke(Color.white.opacity(0.28), lineWidth: 1.5)
.stroke(OSGColor.recordListeningRing, lineWidth: 1.5)
.scaleEffect(1 + min(max(state.level, 0), 1) * 0.08)
.animation(Motion.soft, value: state.level)
}
@@ -161,16 +161,16 @@ struct LastInputEditView: View {
private var primaryIcon: some View {
switch state.editSession {
case .preparing, .processing, .applying, .appending:
ProgressView().tint(.white)
ProgressView().tint(OSGColor.fixedLightContent)
case .review:
Image(systemName: "checkmark")
.font(.system(size: 21, weight: .bold))
.foregroundStyle(.white)
.foregroundStyle(OSGColor.fixedLightContent)
case .listening:
WaveformView(
level: state.level,
barCount: 7,
color: .white,
color: OSGColor.fixedLightContent,
active: true
)
.frame(width: 35, height: 22)
@@ -178,7 +178,7 @@ struct LastInputEditView: View {
default:
Image(systemName: "mic.fill")
.font(.system(size: 21, weight: .semibold))
.foregroundStyle(.white)
.foregroundStyle(OSGColor.fixedLightContent)
}
}
@@ -3,32 +3,37 @@
//
// Shared native-like key surface used by voice and typing action rows.
import OSGKeyboardShared
import SwiftUI
enum NativeKeyboardKeyColors {
static func fill(for colorScheme: ColorScheme) -> Color {
colorScheme == .dark ? Color(white: 0.32) : .white
colorScheme == .dark
? OSGColor.keyboardDarkKeyFill
: OSGColor.fixedLightContent
}
static func pressedFill(for colorScheme: ColorScheme) -> Color {
colorScheme == .dark ? Color(white: 0.23) : Color(white: 0.84)
colorScheme == .dark
? OSGColor.keyboardDarkKeyPressed
: OSGColor.keyboardLightKeyPressed
}
static func text(for colorScheme: ColorScheme) -> Color {
colorScheme == .dark ? .white : Color(red: 0.06, green: 0.06, blue: 0.08)
colorScheme == .dark ? OSGColor.fixedLightContent : OSGColor.keyboardLightText
}
/// Adaptive brand green: brighter in dark mode and deeper in light mode.
static func sendFill(for colorScheme: ColorScheme) -> Color {
colorScheme == .dark
? Color(red: 0.286, green: 0.725, blue: 0.416)
: Color(red: 0.196, green: 0.549, blue: 0.298)
? OSGColor.keyboardDarkSend
: OSGColor.keyboardLightSend
}
static func sendPressedFill(for colorScheme: ColorScheme) -> Color {
colorScheme == .dark
? Color(red: 0.227, green: 0.627, blue: 0.353)
: Color(red: 0.157, green: 0.447, blue: 0.247)
? OSGColor.keyboardDarkSendPressed
: OSGColor.keyboardLightSendPressed
}
}
@@ -67,7 +67,9 @@ private struct ToolbarKeySurface<Content: View>: View {
case .standard:
return palette.divider
case .send:
return Color.black.opacity(colorScheme == .dark ? 0.10 : 0.08)
return colorScheme == .dark
? OSGColor.keyboardActionBorderDark
: OSGColor.keyboardActionBorderLight
}
}
}
@@ -340,7 +342,7 @@ struct RectangularToolbarButton: View {
}
private var buttonForeground: Color {
isSend ? .white : NativeKeyboardKeyColors.text(for: colorScheme)
isSend ? OSGColor.fixedLightContent : NativeKeyboardKeyColors.text(for: colorScheme)
}
// / Button