Files
mobile-ios/Rosetta/Features/Auth/WelcomeView.swift
senseiGai 196765f038 Откат случайно включённых изменений дизайн-системы
Предыдущий коммит случайно включил изменения из рабочей
директории: упрощение GlassModifier, GlassModifiers,
RosettaTabBar, ButtonStyles, GlassCard и других файлов,
что сломало iOS 26 glass-эффекты и внешний вид tab bar.

Восстановлены оригинальные файлы из состояния до этих изменений.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 05:23:09 +05:00

175 lines
5.5 KiB
Swift

import SwiftUI
import Lottie
struct WelcomeView: View {
let onGenerateSeed: () -> Void
let onImportSeed: () -> Void
var onBack: (() -> Void)?
@State private var isVisible: Bool
private static var hasAnimated = false
init(onGenerateSeed: @escaping () -> Void, onImportSeed: @escaping () -> Void, onBack: (() -> Void)? = nil) {
self.onGenerateSeed = onGenerateSeed
self.onImportSeed = onImportSeed
self.onBack = onBack
_isVisible = State(initialValue: Self.hasAnimated)
}
var body: some View {
ZStack(alignment: .topLeading) {
VStack(spacing: 0) {
Spacer()
lockAnimation
.padding(.bottom, 32)
titleSection
.padding(.bottom, 16)
subtitleSection
.padding(.bottom, 24)
featureBadges
.padding(.bottom, 32)
Spacer()
Spacer().frame(height: 16)
buttonsSection
.padding(.horizontal, 24)
.padding(.bottom, 16)
}
// Back button (only shows when coming from Unlock screen)
if let onBack {
GlassBackButton(action: onBack)
.padding(.leading, 12)
.padding(.top, 8)
.accessibilityLabel("Back")
}
}
.onAppear {
guard !isVisible else { return }
withAnimation(.easeOut(duration: 0.5)) { isVisible = true }
Self.hasAnimated = true
}
}
}
// MARK: - Lock Animation
private extension WelcomeView {
var lockAnimation: some View {
LottieView(
animationName: "lock",
loopMode: .loop,
animationSpeed: 1.0
)
.frame(width: 120, height: 120)
.opacity(isVisible ? 1.0 : 0.0)
.scaleEffect(isVisible ? 1.0 : 0.5)
.animation(.spring(response: 0.5, dampingFraction: 0.7).delay(0.1), value: isVisible)
.accessibilityHidden(true)
}
}
// MARK: - Text Sections
private extension WelcomeView {
var titleSection: some View {
Text("Your Keys,\nYour Messages")
.font(.system(size: 32, weight: .bold))
.foregroundStyle(.white)
.multilineTextAlignment(.center)
.opacity(isVisible ? 1.0 : 0.0)
.offset(y: isVisible ? 0 : 16)
.animation(.easeOut(duration: 0.4).delay(0.2), value: isVisible)
}
var subtitleSection: some View {
Text("Secure messaging with\ncryptographic keys")
.font(.system(size: 16))
.foregroundStyle(Color.white.opacity(0.7))
.multilineTextAlignment(.center)
.opacity(isVisible ? 1.0 : 0.0)
.offset(y: isVisible ? 0 : 12)
.animation(.easeOut(duration: 0.4).delay(0.3), value: isVisible)
}
}
// MARK: - Feature Badges
private extension WelcomeView {
var featureBadges: some View {
HStack(spacing: 24) {
featureBadge(icon: "lock.shield.fill", label: "Encrypted", index: 0)
featureBadge(icon: "person.crop.circle.badge.minus", label: "No Phone", index: 1)
featureBadge(icon: "key.fill", label: "Your Keys", index: 2)
}
.opacity(isVisible ? 1.0 : 0.0)
.animation(.easeOut(duration: 0.5).delay(0.4), value: isVisible)
}
func featureBadge(icon: String, label: String, index: Int) -> some View {
VStack(spacing: 8) {
GlassCard(cornerRadius: 24, fillOpacity: 0.12) {
Image(systemName: icon)
.font(.system(size: 22))
.foregroundStyle(RosettaColors.primaryBlue)
.frame(width: 48, height: 48)
}
Text(label)
.font(.system(size: 13, weight: .medium))
.foregroundStyle(Color.white.opacity(0.7))
}
.accessibilityElement(children: .combine)
.accessibilityLabel(label)
}
}
// MARK: - Buttons
private extension WelcomeView {
var buttonsSection: some View {
VStack(spacing: 12) {
Button(action: onGenerateSeed) {
HStack(spacing: 10) {
Image(systemName: "sparkles")
.font(.system(size: 18))
Text("Generate New Seed Phrase")
.font(.system(size: 16, weight: .semibold))
}
.foregroundStyle(.white)
.frame(maxWidth: .infinity)
.frame(height: 56)
}
.buttonStyle(RosettaPrimaryButtonStyle())
.shine()
.accessibilityHint("Creates a new encrypted account")
Button(action: onImportSeed) {
HStack(spacing: 8) {
Image(systemName: "square.and.arrow.down")
.font(.system(size: 16))
Text("I Already Have a Seed Phrase")
.font(.system(size: 15, weight: .medium))
}
.foregroundStyle(RosettaColors.primaryBlue)
.frame(maxWidth: .infinity)
.frame(height: 44)
}
.accessibilityHint("Restores an existing account")
}
.opacity(isVisible ? 1.0 : 0.0)
.animation(.easeOut(duration: 0.4).delay(0.6), value: isVisible)
}
}
#Preview {
WelcomeView(onGenerateSeed: {}, onImportSeed: {}, onBack: {})
.preferredColorScheme(.dark)
.background(RosettaColors.authBackground)
}