102 lines
3.8 KiB
Swift
102 lines
3.8 KiB
Swift
import Lottie
|
|
import SwiftUI
|
|
|
|
/// Full-screen device confirmation overlay — shown when THIS device
|
|
/// needs approval from another Rosetta device (desktop parity: DeviceConfirm.tsx).
|
|
///
|
|
/// Displayed as an overlay in MainTabView, covering nav bar, search, and tab bar.
|
|
struct DeviceConfirmView: View {
|
|
private let deviceName = UIDevice.current.name
|
|
|
|
var body: some View {
|
|
ZStack {
|
|
// Full black background covering everything
|
|
RosettaColors.Dark.background
|
|
.ignoresSafeArea()
|
|
|
|
VStack(spacing: 0) {
|
|
Spacer()
|
|
|
|
// Inbox animation (desktop parity: inbox.json)
|
|
LottieView(
|
|
animationName: "inbox",
|
|
loopMode: .loop,
|
|
animationSpeed: 1.0
|
|
)
|
|
.frame(width: 140, height: 140)
|
|
|
|
Spacer().frame(height: 24)
|
|
|
|
// Title (desktop: fw:500, fz:18)
|
|
Text("Confirm new device")
|
|
.font(.system(size: 18, weight: .medium))
|
|
.foregroundStyle(RosettaColors.Adaptive.text)
|
|
|
|
Spacer().frame(height: 10)
|
|
|
|
// Description (desktop: fz:14, dimmed, centered, px:lg)
|
|
Text("To confirm this device, please check your first device attached to your account and approve the new device.")
|
|
.font(.system(size: 14, weight: .regular))
|
|
.foregroundStyle(RosettaColors.Adaptive.textSecondary)
|
|
.multilineTextAlignment(.center)
|
|
.frame(maxWidth: 320)
|
|
.padding(.horizontal, 16)
|
|
|
|
Spacer().frame(height: 24)
|
|
|
|
// Exit button (desktop: animated red gradient, fullWidth, radius xl)
|
|
Button(action: exitAccount) {
|
|
Text("Exit")
|
|
.font(.system(size: 16, weight: .semibold))
|
|
.foregroundStyle(.white)
|
|
.frame(maxWidth: .infinity)
|
|
.frame(height: 48)
|
|
}
|
|
.buttonStyle(DeviceConfirmExitButtonStyle())
|
|
.padding(.horizontal, 32)
|
|
|
|
Spacer()
|
|
|
|
// Footer with device name (desktop: fz:12, dimmed, bold device name)
|
|
Text("Confirm device **\(deviceName)** on your first device to loading your chats.")
|
|
.font(.system(size: 12, weight: .regular))
|
|
.foregroundStyle(RosettaColors.Adaptive.textSecondary.opacity(0.6))
|
|
.multilineTextAlignment(.center)
|
|
.frame(maxWidth: 300)
|
|
.padding(.bottom, 40)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func exitAccount() {
|
|
ProtocolManager.shared.disconnect()
|
|
}
|
|
}
|
|
|
|
// MARK: - Exit Button Style (red glass capsule, desktop: animated gradient #e03131 → #ff5656)
|
|
|
|
private struct DeviceConfirmExitButtonStyle: ButtonStyle {
|
|
private let fillColor = RosettaColors.error
|
|
|
|
func makeBody(configuration: Configuration) -> some View {
|
|
Group {
|
|
if #available(iOS 26, *) {
|
|
configuration.label
|
|
.background {
|
|
Capsule().fill(fillColor.opacity(configuration.isPressed ? 0.6 : 0.85))
|
|
}
|
|
.glassEffect(.regular, in: Capsule())
|
|
} else {
|
|
configuration.label
|
|
.background {
|
|
Capsule()
|
|
.fill(fillColor.opacity(configuration.isPressed ? 0.6 : 0.85))
|
|
}
|
|
.clipShape(Capsule())
|
|
}
|
|
}
|
|
.scaleEffect(configuration.isPressed ? 0.97 : 1.0)
|
|
.animation(.easeOut(duration: 0.15), value: configuration.isPressed)
|
|
}
|
|
}
|