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
@@ -81,34 +81,134 @@ public struct SurfaceCardModifier: ViewModifier {
@Environment(\.themePalette) private var palette
private let enabled: Bool
private let elevated: Bool
public init(enabled: Bool = true) {
public init(enabled: Bool = true, elevated: Bool = true) {
self.enabled = enabled
self.elevated = elevated
}
@ViewBuilder
public func body(content: Content) -> some View {
if enabled {
let shape = RoundedRectangle(cornerRadius: Radius.xl, style: .continuous)
content
let card = content
.background(
palette.surface,
elevated ? palette.surface : palette.formSurface,
in: shape
)
// Clip child backgrounds as well as the card surface. Without
// this, a full-width child can visually square off a corner.
.clipShape(shape)
if elevated {
card.cardElevation()
} else {
card
}
} else {
content
}
}
}
private struct CardElevationModifier: ViewModifier {
@Environment(\.colorScheme) private var colorScheme
let accented: Bool
@ViewBuilder
func body(content: Content) -> some View {
#if os(iOS)
// Layered low-opacity shadows create direction and length without
// turning the warm background gray.
content
.shadow(
color: nearShadowColor,
radius: 1,
x: 2,
y: 3
)
.shadow(
color: midShadowColor,
radius: 3,
x: 6,
y: 8
)
.shadow(
color: farShadowColor,
radius: 9,
x: 12,
y: 18
)
#else
content
#endif
}
private var nearShadowColor: Color {
guard accented else { return OSGColor.cardShadowNear }
return colorScheme == .dark
? OSGColor.selectedCardShadowNearDark
: OSGColor.selectedCardShadowNearLight
}
private var midShadowColor: Color {
guard accented else { return OSGColor.cardShadowMid }
return colorScheme == .dark
? OSGColor.selectedCardShadowMidDark
: OSGColor.selectedCardShadowMidLight
}
private var farShadowColor: Color {
guard accented else { return OSGColor.cardShadowFar }
return colorScheme == .dark
? OSGColor.selectedCardShadowFarDark
: OSGColor.selectedCardShadowFarLight
}
}
private struct CardListRowModifier: ViewModifier {
let bottomSpacing: CGFloat
let elevated: Bool
func body(content: Content) -> some View {
content
.surfaceCard(elevated: elevated)
.listRowInsets(
EdgeInsets(
top: 0,
leading: 0,
bottom: bottomSpacing,
trailing: 0
)
)
.listRowBackground(Color.clear)
.listRowSeparator(.hidden)
}
}
public extension View {
func cardSectionLabel() -> some View {
modifier(CardSectionLabelModifier())
}
func surfaceCard(enabled: Bool = true) -> some View {
modifier(SurfaceCardModifier(enabled: enabled))
func surfaceCard(
enabled: Bool = true,
elevated: Bool = true
) -> some View {
modifier(SurfaceCardModifier(enabled: enabled, elevated: elevated))
}
func cardElevation(accented: Bool = false) -> some View {
modifier(CardElevationModifier(accented: accented))
}
/// Makes a native List/Form row render as an elevated app card while
/// retaining system scrolling, swipe actions, refresh, and keyboard logic.
func cardListRow(
bottomSpacing: CGFloat = 0,
elevated: Bool = true
) -> some View {
modifier(CardListRowModifier(bottomSpacing: bottomSpacing, elevated: elevated))
}
}