feat: 首次登录

This commit is contained in:
jinyaqiu 2025-08-29 13:29:17 +08:00
parent 5080b104a4
commit 8044927b51
12 changed files with 86 additions and 57 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

11
wake/Assets/Svg/Tips.svg Normal file
View File

@ -0,0 +1,11 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_7357_2809)">
<path d="M3.33325 12.6668V6.00016C3.33325 3.42283 5.42259 1.3335 7.99992 1.3335C10.5773 1.3335 12.6666 3.42283 12.6666 6.00016V12.6668M1.33325 12.6668H14.6666" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.99992 14.6665C8.92039 14.6665 9.66659 13.9203 9.66659 12.9998V12.6665H6.33325V12.9998C6.33325 13.9203 7.07945 14.6665 7.99992 14.6665Z" stroke="black" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_7357_2809">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 731 B

View File

@ -169,7 +169,7 @@ struct ContentView: View {
LoginView()
}
}
.padding()
.padding(.horizontal)
.padding(.top, 20)
//
VStack(alignment: .leading, spacing: 4) {

View File

@ -11,6 +11,7 @@ enum AppRoute: Hashable {
case blindOutcome(media: MediaType)
case memories
case subscribe
case userInfo
@ViewBuilder
var view: some View {
@ -33,6 +34,8 @@ enum AppRoute: Hashable {
MemoriesView()
case .subscribe:
SubscribeView()
case .userInfo:
UserInfo()
}
}
}

View File

@ -9,6 +9,12 @@ private enum MediaURLs {
static let VideoBlindURL = "https://cdn.memorywake.com/users/7363409620351717377/files/7366658779259211776/AD970D28-9D1E-4817-A245-F11967441B8F.mp4"
}
private enum BlindBoxAnimationPhase {
case loading
case ready
case opening
}
extension Notification.Name {
static let navigateToMediaViewer = Notification.Name("navigateToMediaViewer")
}
@ -71,6 +77,7 @@ struct BlindBoxView: View {
let mediaType: BlindBoxMediaType
@State private var showLottieAnimation = true
@State private var showScalingOverlay = false
@State private var animationPhase: BlindBoxAnimationPhase = .loading
@State private var scale: CGFloat = 0.1
@State private var videoPlayer: AVPlayer?
@State private var showControls = false
@ -263,20 +270,49 @@ struct BlindBoxView: View {
.opacity(showScalingOverlay ? 0 : 1)
.animation(.easeOut(duration: 1.5), value: showScalingOverlay)
}
if !showScalingOverlay {
VStack(spacing: 20) {
let player = AVPlayer(url: URL(string: MediaURLs.VideoBlindURL)!)
VideoPlayer(player: player)
.background(TransparentVideoPlayer())
switch animationPhase {
case .loading:
GIFView(name: "BlindLoading")
.frame(width: 300, height: 300)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 6) {
withAnimation {
animationPhase = .ready
}
}
}
case .ready:
ZStack {
GIFView(name: "BlindReady")
.frame(width: 300, height: 300)
// Add a transparent overlay to capture taps
Color.clear
.contentShape(Rectangle()) // Make the entire area tappable
.frame(width: 300, height: 300)
.onTapGesture {
print("点击了盲盒")
withAnimation {
animationPhase = .opening
}
}
}
.frame(width: 300, height: 300)
.onAppear {
player.play()
player.isMuted = true
}
.onDisappear {
player.pause()
}
case .opening:
GIFView(name: "BlindOpen")
.frame(width: 300, height: 300)
.onAppear {
self.loadMedia()
// Start animation after media is loaded
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.startScalingAnimation()
}
}
}
}
.compositingGroup()
.padding()
@ -298,13 +334,6 @@ struct BlindBoxView: View {
}
}
.navigationBarBackButtonHidden(true)
.onAppear {
self.loadMedia()
// Start animation after media is loaded
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.startScalingAnimation()
}
}
}
}

View File

@ -61,11 +61,6 @@ struct LoginView: View {
}
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
.fullScreenCover(isPresented: $isLoggedIn) {
NavigationStack {
UserInfo()
}
}
}
// MARK: - Views
@ -264,6 +259,8 @@ struct LoginView: View {
self.errorMessage = "登录信息不完整,请重试"
self.showError = true
}
// userinfo
Router.shared.navigate(to: .userInfo)
case .failure(let error):
print("❌ [15] 后端认证失败")

View File

@ -61,28 +61,23 @@ struct UserInfo: View {
.background(Color.themeTextWhiteSecondary)
.zIndex(1) //
// Dynamic text that changes based on keyboard state
HStack(spacing: 20) {
HStack(spacing: 6) {
SVGImage(svgName: "Tips")
.frame(width: 16, height: 16)
.padding(.leading,6)
Text("Choose a photo as your avatar, and we'll generate a video mystery box for you.")
.font(Typography.font(for: .caption))
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(isKeyboardVisible ? 1 : 2)
.padding(6)
.background(
LinearGradient(
gradient: Gradient(colors: [
Color(red: 1.0, green: 0.97, blue: 0.87),
.white,
Color(red: 1.0, green: 0.97, blue: 0.84)
]),
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.padding(3)
}
.padding(10)
.animation(.easeInOut(duration: 0.3), value: isKeyboardVisible)
.transition(.opacity)
.background(
Color.themeTextWhite
.cornerRadius(12)
)
.padding(10)
//
GeometryReader { geometry in
@ -141,7 +136,6 @@ struct UserInfo: View {
// Continue Button
Button(action: {
Router.shared.navigate(to: .blindBox(mediaType: .image))
if showUsername {
let parameters: [String: Any] = [
"username": userName,

View File

@ -82,33 +82,28 @@ struct MediaUploadView: View {
.padding(.trailing, 16)
}
.background(Color.themeTextWhiteSecondary)
.padding(.horizontal)
// .padding(.horizontal)
.zIndex(1) //
}
///
private var uploadHintView: some View {
HStack {
HStack (spacing: 6) {
SVGImage(svgName: "Tips")
.frame(width: 16, height: 16)
.padding(.leading,6)
Text("The upload process will take approximately 2 minutes. Thank you for your patience.")
.font(.caption)
.foregroundColor(.black)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(3)
.background(
LinearGradient(
gradient: Gradient(colors: [
Color(red: 1.0, green: 0.97, blue: 0.87),
.white,
Color(red: 1.0, green: 0.97, blue: 0.84)
]),
startPoint: .topLeading,
endPoint: .bottomTrailing
)
.cornerRadius(8)
)
.padding(.horizontal)
}
.background(
Color.themeTextWhite
.cornerRadius(6)
)
.padding(.vertical, 8)
.padding(.horizontal)
}
///

View File

@ -46,10 +46,10 @@ struct WakeApp: App {
//
if authState.isAuthenticated {
// userInfo
LoginView()
.environmentObject(authState)
// ContentView()
// .environmentObject(authState)
ContentView()
.environmentObject(authState)
} else {
//
LoginView()