feat: feedback
This commit is contained in:
parent
0aa1271c93
commit
4e97f8ebb8
41
wake/Utils/Router.swift
Normal file
41
wake/Utils/Router.swift
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
enum AppRoute: Hashable {
|
||||||
|
case avatarBox
|
||||||
|
case feedbackView
|
||||||
|
case feedbackDetail(type: FeedbackView.FeedbackType)
|
||||||
|
// Add other routes here as needed
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
var view: some View {
|
||||||
|
switch self {
|
||||||
|
case .avatarBox:
|
||||||
|
AvatarBoxView()
|
||||||
|
case .feedbackView:
|
||||||
|
FeedbackView()
|
||||||
|
case .feedbackDetail(let type):
|
||||||
|
FeedbackDetailView(feedbackType: type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
class Router: ObservableObject {
|
||||||
|
static let shared = Router()
|
||||||
|
|
||||||
|
@Published var path = NavigationPath()
|
||||||
|
|
||||||
|
private init() {}
|
||||||
|
|
||||||
|
func navigate(to destination: AppRoute) {
|
||||||
|
path.append(destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pop() {
|
||||||
|
path.removeLast()
|
||||||
|
}
|
||||||
|
|
||||||
|
func popToRoot() {
|
||||||
|
path = NavigationPath()
|
||||||
|
}
|
||||||
|
}
|
||||||
105
wake/View/Blind/AvatarBox.swift
Normal file
105
wake/View/Blind/AvatarBox.swift
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AvatarBoxView: View {
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@EnvironmentObject private var router: Router
|
||||||
|
@State private var isAnimating = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
// Background color
|
||||||
|
Color.white
|
||||||
|
.ignoresSafeArea()
|
||||||
|
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// Navigation Bar
|
||||||
|
HStack {
|
||||||
|
Button(action: {
|
||||||
|
dismiss()
|
||||||
|
}) {
|
||||||
|
Image(systemName: "chevron.left")
|
||||||
|
.font(.system(size: 17, weight: .medium))
|
||||||
|
.foregroundColor(.black)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Text("动画页面")
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(.black)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
// Invisible spacer to center the title
|
||||||
|
Color.clear
|
||||||
|
.frame(width: 44, height: 44)
|
||||||
|
}
|
||||||
|
.frame(height: 44)
|
||||||
|
.background(Color.white)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
// Animated Content
|
||||||
|
ZStack {
|
||||||
|
// Pulsing circle animation
|
||||||
|
Circle()
|
||||||
|
.fill(Color.blue.opacity(0.2))
|
||||||
|
.frame(width: 200, height: 200)
|
||||||
|
.scaleEffect(isAnimating ? 1.5 : 1.0)
|
||||||
|
.opacity(isAnimating ? 0.5 : 1.0)
|
||||||
|
.animation(
|
||||||
|
Animation.easeInOut(duration: 1.5)
|
||||||
|
.repeatForever(autoreverses: true),
|
||||||
|
value: isAnimating
|
||||||
|
)
|
||||||
|
|
||||||
|
// Center icon
|
||||||
|
Image(systemName: "sparkles")
|
||||||
|
.font(.system(size: 60))
|
||||||
|
.foregroundColor(.blue)
|
||||||
|
.rotationEffect(.degrees(isAnimating ? 360 : 0))
|
||||||
|
.animation(
|
||||||
|
Animation.linear(duration: 8)
|
||||||
|
.repeatForever(autoreverses: false),
|
||||||
|
value: isAnimating
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
// Bottom Button
|
||||||
|
Button(action: {
|
||||||
|
router.navigate(to: .feedbackView)
|
||||||
|
}) {
|
||||||
|
Text("Continue")
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(.themeTextMessageMain)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.frame(height: 56)
|
||||||
|
.background(Color.themePrimary)
|
||||||
|
.cornerRadius(25)
|
||||||
|
.padding(.horizontal, 24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
}
|
||||||
|
.navigationBarBackButtonHidden(true)
|
||||||
|
.navigationBarHidden(true)
|
||||||
|
.onAppear {
|
||||||
|
isAnimating = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Preview
|
||||||
|
struct AvatarBoxView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationView {
|
||||||
|
AvatarBoxView()
|
||||||
|
.environmentObject(Router.shared)
|
||||||
|
}
|
||||||
|
.navigationViewStyle(StackNavigationViewStyle())
|
||||||
|
}
|
||||||
|
}
|
||||||
273
wake/View/Feedback.swift
Normal file
273
wake/View/Feedback.swift
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct FeedbackView: View {
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@EnvironmentObject private var router: Router
|
||||||
|
|
||||||
|
@State private var selectedFeedback: FeedbackType? = FeedbackType.allCases.first
|
||||||
|
@State private var showNextScreen = false
|
||||||
|
|
||||||
|
enum FeedbackType: String, CaseIterable, Identifiable {
|
||||||
|
case excellent = "Excellent"
|
||||||
|
case good = "Good"
|
||||||
|
case okay = "Okay"
|
||||||
|
case bad = "Bad"
|
||||||
|
|
||||||
|
var id: String { self.rawValue }
|
||||||
|
var icon: String {
|
||||||
|
switch self {
|
||||||
|
case .excellent: return "😘"
|
||||||
|
case .good: return "😊"
|
||||||
|
case .okay: return "😐"
|
||||||
|
case .bad: return "😞"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// Custom Navigation Bar
|
||||||
|
HStack {
|
||||||
|
// Back Button
|
||||||
|
Button(action: { dismiss() }) {
|
||||||
|
Image(systemName: "chevron.left")
|
||||||
|
.font(.system(size: 17, weight: .semibold))
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
.frame(width: 44, height: 44)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Title
|
||||||
|
Text("Feedback")
|
||||||
|
.font(Typography.font(for: .title2, family: .quicksandBold))
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
|
||||||
|
// Spacer to balance the HStack
|
||||||
|
Spacer()
|
||||||
|
.frame(width: 44, height: 44)
|
||||||
|
}
|
||||||
|
.frame(height: 44)
|
||||||
|
.background(Color.themeTextWhiteSecondary)
|
||||||
|
|
||||||
|
// Main Content
|
||||||
|
GeometryReader { geometry in
|
||||||
|
ScrollView {
|
||||||
|
VStack(spacing: 24) {
|
||||||
|
// Top spacing for vertical centering
|
||||||
|
Spacer(minLength: 0)
|
||||||
|
|
||||||
|
VStack(spacing: 24) {
|
||||||
|
Text("How are you feeling?")
|
||||||
|
.font(Typography.font(for: .title2, family: .quicksandBold))
|
||||||
|
.fontWeight(.semibold)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.bottom, 50)
|
||||||
|
|
||||||
|
// Feedback Type Selection
|
||||||
|
VStack(spacing: 12) {
|
||||||
|
ForEach(FeedbackType.allCases) { type in
|
||||||
|
Button(action: {
|
||||||
|
selectedFeedback = type
|
||||||
|
}) {
|
||||||
|
let isSelected = selectedFeedback == type
|
||||||
|
HStack {
|
||||||
|
Text(type.icon)
|
||||||
|
.font(.body)
|
||||||
|
.foregroundColor(isSelected ? .white : .primary)
|
||||||
|
|
||||||
|
Text(type.rawValue)
|
||||||
|
.font(.body)
|
||||||
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 12)
|
||||||
|
.fill(isSelected ? Color.themePrimary : Color.themePrimaryLight)
|
||||||
|
)
|
||||||
|
.overlay(
|
||||||
|
RoundedRectangle(cornerRadius: 12)
|
||||||
|
.stroke(isSelected ? Color.themePrimary : Color.themePrimaryLight, lineWidth: 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.buttonStyle(PlainButtonStyle())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.bottom, 24)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 20)
|
||||||
|
.padding(.vertical, 24)
|
||||||
|
.background(Color.white)
|
||||||
|
.cornerRadius(16)
|
||||||
|
.shadow(color: Color.black.opacity(0.2), radius: 12, x: 0, y: 4)
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.frame(minHeight: geometry.size.height - 120) // Subtract navigation bar and bottom button height
|
||||||
|
|
||||||
|
// Bottom spacing for vertical centering
|
||||||
|
Spacer(minLength: 0)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, minHeight: geometry.size.height - 44) // Subtract navigation bar height
|
||||||
|
}
|
||||||
|
.background(Color.themeTextWhiteSecondary)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue Button
|
||||||
|
Button(action: {
|
||||||
|
if let selected = selectedFeedback {
|
||||||
|
router.navigate(to: .feedbackDetail(type: selected))
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Text("Continue")
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(selectedFeedback != nil ? .white : .gray)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.frame(height: 56)
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 25)
|
||||||
|
.fill(selectedFeedback != nil ?
|
||||||
|
Color.themePrimary : Color(.systemGray5))
|
||||||
|
)
|
||||||
|
.padding(.horizontal, 24)
|
||||||
|
}
|
||||||
|
.disabled(selectedFeedback == nil)
|
||||||
|
}
|
||||||
|
.navigationBarHidden(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feedback Detail View
|
||||||
|
struct FeedbackDetailView: View {
|
||||||
|
let feedbackType: FeedbackView.FeedbackType
|
||||||
|
@State private var feedbackText = ""
|
||||||
|
@State private var contactInfo = ""
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// Navigation Bar
|
||||||
|
HStack {
|
||||||
|
// Back Button
|
||||||
|
Button(action: { dismiss() }) {
|
||||||
|
Image(systemName: "chevron.left")
|
||||||
|
.font(.system(size: 17, weight: .semibold))
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
.frame(width: 44, height: 44)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Title
|
||||||
|
Text(feedbackType.rawValue)
|
||||||
|
.font(.headline)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
|
||||||
|
// Spacer to balance the HStack
|
||||||
|
Spacer()
|
||||||
|
.frame(width: 44, height: 44)
|
||||||
|
}
|
||||||
|
.frame(height: 44)
|
||||||
|
.background(Color.themeTextWhiteSecondary)
|
||||||
|
|
||||||
|
// Form
|
||||||
|
ScrollView {
|
||||||
|
VStack(spacing: 24) {
|
||||||
|
// Feedback Type
|
||||||
|
HStack {
|
||||||
|
Image(systemName: feedbackType.icon)
|
||||||
|
.foregroundColor(.blue)
|
||||||
|
Text(feedbackType.rawValue)
|
||||||
|
.font(.headline)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.background(Color.blue.opacity(0.1))
|
||||||
|
.cornerRadius(12)
|
||||||
|
|
||||||
|
// Feedback Text
|
||||||
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
|
Text("Describe your \(feedbackType.rawValue.lowercased())")
|
||||||
|
.font(.subheadline)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
|
TextEditor(text: $feedbackText)
|
||||||
|
.frame(minHeight: 150)
|
||||||
|
.padding()
|
||||||
|
.background(Color(.systemGray6))
|
||||||
|
.cornerRadius(12)
|
||||||
|
.overlay(
|
||||||
|
RoundedRectangle(cornerRadius: 12)
|
||||||
|
.stroke(Color(.systemGray4), lineWidth: 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contact Info
|
||||||
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
|
Text("Contact Information (Optional)")
|
||||||
|
.font(.subheadline)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
|
TextField("Email or phone number", text: $contactInfo)
|
||||||
|
.padding()
|
||||||
|
.background(Color(.systemGray6))
|
||||||
|
.cornerRadius(12)
|
||||||
|
.overlay(
|
||||||
|
RoundedRectangle(cornerRadius: 12)
|
||||||
|
.stroke(Color(.systemGray4), lineWidth: 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit Button
|
||||||
|
Button(action: {
|
||||||
|
submitFeedback()
|
||||||
|
}) {
|
||||||
|
Text("Submit Feedback")
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.frame(height: 56)
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 25)
|
||||||
|
.fill(Color.themePrimary)
|
||||||
|
)
|
||||||
|
.padding(.horizontal, 24)
|
||||||
|
.padding(.bottom, 24)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationBarHidden(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func submitFeedback() {
|
||||||
|
// TODO: Implement feedback submission logic
|
||||||
|
print("Feedback submitted:")
|
||||||
|
print("Type: \(feedbackType.rawValue)")
|
||||||
|
print("Message: \(feedbackText)")
|
||||||
|
if !contactInfo.isEmpty {
|
||||||
|
print("Contact: \(contactInfo)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dismiss back to feedback type selection
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preview
|
||||||
|
struct FeedbackView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationView {
|
||||||
|
FeedbackView()
|
||||||
|
.environmentObject(Router.shared)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FeedbackDetailView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NavigationView {
|
||||||
|
FeedbackDetailView(feedbackType: .excellent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -71,19 +71,28 @@ struct LoginView: View {
|
|||||||
// MARK: - Views
|
// MARK: - Views
|
||||||
|
|
||||||
private func signInButton() -> some View {
|
private func signInButton() -> some View {
|
||||||
AppleSignInButton { request in
|
print("🟢 [Debug] Sign in button tapped")
|
||||||
|
return AppleSignInButton { request in
|
||||||
|
print("🔵 [Debug] Creating sign in request")
|
||||||
let nonce = String.randomURLSafeString(length: 32)
|
let nonce = String.randomURLSafeString(length: 32)
|
||||||
self.currentNonce = nonce
|
self.currentNonce = nonce
|
||||||
request.nonce = self.sha256(nonce)
|
request.nonce = self.sha256(nonce)
|
||||||
|
request.requestedScopes = [.fullName, .email]
|
||||||
|
print("🔵 [Debug] Sign in request configured with nonce")
|
||||||
} onCompletion: { result in
|
} onCompletion: { result in
|
||||||
|
print("🔵 [Debug] Sign in completion handler triggered")
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let authResults):
|
case .success(let authResults):
|
||||||
print("✅ [Apple Sign In] 登录授权成功")
|
print("✅ [Apple Sign In] 登录授权成功")
|
||||||
if let appleIDCredential = authResults.credential as? ASAuthorizationAppleIDCredential {
|
if let appleIDCredential = authResults.credential as? ASAuthorizationAppleIDCredential {
|
||||||
|
print("🔵 [Debug] Processing Apple ID credential")
|
||||||
self.processAppleIDCredential(appleIDCredential)
|
self.processAppleIDCredential(appleIDCredential)
|
||||||
|
} else {
|
||||||
|
print("❌ [Debug] Failed to cast credential to ASAuthorizationAppleIDCredential")
|
||||||
}
|
}
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
print("❌ [Apple Sign In] 登录失败: \(error.localizedDescription)")
|
print("❌ [Apple Sign In] 登录失败: \(error.localizedDescription)")
|
||||||
|
print("❌ [Debug] Error details: \(error as NSError)")
|
||||||
self.handleSignInError(error)
|
self.handleSignInError(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,8 +257,11 @@ struct LoginView: View {
|
|||||||
|
|
||||||
private func handleSuccessfulAuthentication() {
|
private func handleSuccessfulAuthentication() {
|
||||||
print("✅ [Auth] 登录成功,准备跳转到用户信息页面...")
|
print("✅ [Auth] 登录成功,准备跳转到用户信息页面...")
|
||||||
|
print("🔵 [Debug] isLoggedIn before update: \(isLoggedIn)")
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
print("🔵 [Debug] Setting isLoggedIn to true")
|
||||||
self.isLoggedIn = true
|
self.isLoggedIn = true
|
||||||
|
print("🔵 [Debug] isLoggedIn after update: \(self.isLoggedIn)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import SwiftUI
|
|||||||
|
|
||||||
struct UserInfo: View {
|
struct UserInfo: View {
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
@StateObject private var router = Router.shared
|
||||||
|
|
||||||
// Sample user data - replace with your actual data model
|
// Sample user data - replace with your actual data model
|
||||||
@State private var userName = ""
|
@State private var userName = ""
|
||||||
@ -141,6 +142,7 @@ struct UserInfo: View {
|
|||||||
// Continue Button
|
// Continue Button
|
||||||
Button(action: {
|
Button(action: {
|
||||||
if showUsername {
|
if showUsername {
|
||||||
|
router.navigate(to: .avatarBox)
|
||||||
let parameters: [String: Any] = [
|
let parameters: [String: Any] = [
|
||||||
"username": userName,
|
"username": userName,
|
||||||
"avatar_file_id": uploadedFileId ?? ""
|
"avatar_file_id": uploadedFileId ?? ""
|
||||||
@ -157,15 +159,12 @@ struct UserInfo: View {
|
|||||||
// Update local state with the new user info
|
// Update local state with the new user info
|
||||||
if let userData = response.data {
|
if let userData = response.data {
|
||||||
self.userName = userData.username
|
self.userName = userData.username
|
||||||
// You can update other user data here if needed
|
|
||||||
}
|
}
|
||||||
// Show success message or navigate back
|
// Navigate using router
|
||||||
self.dismiss()
|
router.navigate(to: .avatarBox)
|
||||||
|
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
print("❌ 用户信息更新失败: \(error.localizedDescription)")
|
print("❌ 用户信息更新失败: \(error.localizedDescription)")
|
||||||
// Show error message to user
|
|
||||||
// You can use an @State variable to show an alert or toast
|
|
||||||
self.errorMessage = "更新失败: \(error.localizedDescription)"
|
self.errorMessage = "更新失败: \(error.localizedDescription)"
|
||||||
self.showError = true
|
self.showError = true
|
||||||
}
|
}
|
||||||
@ -190,8 +189,6 @@ struct UserInfo: View {
|
|||||||
}
|
}
|
||||||
.padding(.horizontal, 32) // 添加上下边距,与上方按钮保持一致
|
.padding(.horizontal, 32) // 添加上下边距,与上方按钮保持一致
|
||||||
.padding(.bottom, isKeyboardVisible ? 20 : 40)
|
.padding(.bottom, isKeyboardVisible ? 20 : 40)
|
||||||
.disabled(showUsername && userName.trimmingCharacters(in: .whitespaces).isEmpty)
|
|
||||||
.opacity((showUsername && userName.trimmingCharacters(in: .whitespaces).isEmpty) ? 0.6 : 1.0)
|
|
||||||
.animation(.easeInOut, value: showUsername)
|
.animation(.easeInOut, value: showUsername)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
|
|
||||||
|
|||||||
0
wake/View/Upload/uploadView.swift
Normal file
0
wake/View/Upload/uploadView.swift
Normal file
@ -4,6 +4,7 @@ import SwiftData
|
|||||||
|
|
||||||
@main
|
@main
|
||||||
struct WakeApp: App {
|
struct WakeApp: App {
|
||||||
|
@StateObject private var router = Router.shared
|
||||||
@StateObject private var authState = AuthState.shared
|
@StateObject private var authState = AuthState.shared
|
||||||
@State private var showSplash = true
|
@State private var showSplash = true
|
||||||
|
|
||||||
@ -31,40 +32,47 @@ struct WakeApp: App {
|
|||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
ZStack {
|
NavigationStack(path: $router.path) {
|
||||||
if showSplash {
|
ZStack {
|
||||||
// 显示启动页
|
if showSplash {
|
||||||
SplashView()
|
// 显示启动页
|
||||||
.environmentObject(authState)
|
SplashView()
|
||||||
// .onAppear {
|
|
||||||
// // 启动页显示时检查token有效性
|
|
||||||
// checkTokenValidity()
|
|
||||||
// }
|
|
||||||
} else {
|
|
||||||
// 根据登录状态显示不同视图
|
|
||||||
if authState.isAuthenticated {
|
|
||||||
// 已登录:显示userInfo页面
|
|
||||||
UserInfo()
|
|
||||||
.environmentObject(authState)
|
.environmentObject(authState)
|
||||||
|
.onAppear {
|
||||||
|
// 启动页显示时检查token有效性
|
||||||
|
checkTokenValidity()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 未登录:显示登录界面
|
// 根据登录状态显示不同视图
|
||||||
// ContentView()
|
if authState.isAuthenticated {
|
||||||
// .environmentObject(authState)
|
// 已登录:显示userInfo页面
|
||||||
UserInfo()
|
UserInfo()
|
||||||
.environmentObject(authState)
|
.environmentObject(authState)
|
||||||
|
} else {
|
||||||
|
// 未登录:显示登录界面
|
||||||
|
// LoginView()
|
||||||
|
// .environmentObject(authState)
|
||||||
|
UserInfo()
|
||||||
|
.environmentObject(authState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationDestination(for: AppRoute.self) { route in
|
||||||
|
route.view
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.environmentObject(router)
|
||||||
|
.environmentObject(authState)
|
||||||
|
.onAppear {
|
||||||
|
//2秒后自动隐藏启动页
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||||
|
withAnimation {
|
||||||
|
showSplash = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// .onAppear {
|
.modelContainer(container)
|
||||||
// //3秒后自动隐藏启动页
|
|
||||||
// DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
|
|
||||||
// withAnimation {
|
|
||||||
// showSplash = false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
.modelContainer(container)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - 私有方法
|
// MARK: - 私有方法
|
||||||
@ -92,11 +100,11 @@ struct WakeApp: App {
|
|||||||
authState.isAuthenticated = true
|
authState.isAuthenticated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3秒后自动隐藏启动页
|
// 2秒后自动隐藏启动页
|
||||||
// DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||||
// withAnimation {
|
withAnimation {
|
||||||
// showSplash = false
|
showSplash = false
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user