Overhaul native approval UX and add widget surfaces
CI / test (push) Has been cancelled

Bring the SwiftUI app in line with the Apple-native mock and keep pending approvals actionable from Live Activities and watch complications.
This commit is contained in:
2026-04-19 16:29:13 +02:00
parent a6939453f8
commit 61a0cc1f7d
63 changed files with 3496 additions and 1769 deletions
@@ -0,0 +1,72 @@
import SwiftUI
struct PrimaryActionStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
PrimaryActionBody(configuration: configuration)
}
private struct PrimaryActionBody: View {
let configuration: Configuration
@Environment(\.isEnabled) private var isEnabled
var body: some View {
configuration.label
.font(.headline)
.frame(maxWidth: .infinity)
.padding(.horizontal, 18)
.padding(.vertical, 14)
.foregroundStyle(.white)
.background(
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
.fill(isEnabled ? IdP.tint : Color.secondary.opacity(0.25))
)
.opacity(configuration.isPressed ? 0.92 : 1)
.scaleEffect(configuration.isPressed ? 0.985 : 1)
.animation(.easeOut(duration: 0.16), value: configuration.isPressed)
}
}
}
struct SecondaryActionStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.headline)
.frame(maxWidth: .infinity)
.padding(.horizontal, 18)
.padding(.vertical, 14)
.foregroundStyle(.primary)
.background(
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
.fill(Color.idpSecondaryGroupedBackground)
)
.overlay(
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
.stroke(Color.idpSeparator.opacity(0.55), lineWidth: 1)
)
.opacity(configuration.isPressed ? 0.9 : 1)
.scaleEffect(configuration.isPressed ? 0.985 : 1)
.animation(.easeOut(duration: 0.16), value: configuration.isPressed)
}
}
struct DestructiveStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.font(.headline)
.frame(maxWidth: .infinity)
.padding(.horizontal, 18)
.padding(.vertical, 14)
.foregroundStyle(.red)
.background(
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
.fill(Color.red.opacity(0.10))
)
.overlay(
RoundedRectangle(cornerRadius: IdP.controlRadius, style: .continuous)
.stroke(Color.red.opacity(0.18), lineWidth: 1)
)
.opacity(configuration.isPressed ? 0.9 : 1)
.scaleEffect(configuration.isPressed ? 0.985 : 1)
.animation(.easeOut(duration: 0.16), value: configuration.isPressed)
}
}