diff --git a/wake/Assets/Svg/IP1.svg b/wake/Assets/Svg/IP1.svg
new file mode 100644
index 0000000..256a92a
--- /dev/null
+++ b/wake/Assets/Svg/IP1.svg
@@ -0,0 +1,9 @@
+
diff --git a/wake/Assets/Svg/JoinList.svg b/wake/Assets/Svg/JoinList.svg
new file mode 100644
index 0000000..9893af9
--- /dev/null
+++ b/wake/Assets/Svg/JoinList.svg
@@ -0,0 +1,11 @@
+
diff --git a/wake/Typography.swift b/wake/Typography.swift
index c9cab9e..e625504 100644
--- a/wake/Typography.swift
+++ b/wake/Typography.swift
@@ -26,6 +26,7 @@ enum TypographyStyle {
case largeTitle // 大标题
case smallLargeTitle // 小大标题
case headline // 大标题
+ case headline1 // 大标题1
case title // 标题
case title2 // 标题
case title3 // 标题
@@ -54,6 +55,7 @@ struct Typography {
private static let styleConfig: [TypographyStyle: TypographyConfig] = [
.largeTitle: TypographyConfig(size: 32, weight: .heavy, textStyle: .largeTitle),
.smallLargeTitle: TypographyConfig(size: 30, weight: .heavy, textStyle: .largeTitle),
+ .headline1: TypographyConfig(size: 26, weight: .bold, textStyle: .headline),
.headline: TypographyConfig(size: 24, weight: .bold, textStyle: .headline),
.title3: TypographyConfig(size: 22, weight: .semibold, textStyle: .title2),
.title: TypographyConfig(size: 20, weight: .semibold, textStyle: .title2),
diff --git a/wake/View/Blind/Apng.swift b/wake/View/Blind/Apng.swift
deleted file mode 100644
index 3b6a755..0000000
--- a/wake/View/Blind/Apng.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-import SwiftUI
-import UIKit
-
-// 包装UIImageView以支持APNG动画
-struct APNGView: UIViewRepresentable {
- let imageName: String
- @Binding var isAnimating: Bool
-
- func makeUIView(context: Context) -> UIImageView {
- let imageView = UIImageView()
-
- // 从资源加载APNG
- if let image = UIImage(named: imageName) {
- imageView.image = image
- // 启用动画
- imageView.animationImages = image.images
- // 设置动画时长(根据实际帧数调整)
- imageView.animationDuration = image.duration
- // 根据isAnimating状态决定是否开始动画
- if isAnimating {
- imageView.startAnimating()
- }
- }
-
- return imageView
- }
-
- func updateUIView(_ uiView: UIImageView, context: Context) {
- // 根据isAnimating状态控制动画
- if isAnimating {
- if !uiView.isAnimating {
- uiView.startAnimating()
- }
- } else {
- uiView.stopAnimating()
- }
- }
-}
\ No newline at end of file
diff --git a/wake/View/Blind/BlindOutCome.swift b/wake/View/Blind/BlindOutCome.swift
index b30d28b..50c3f04 100644
--- a/wake/View/Blind/BlindOutCome.swift
+++ b/wake/View/Blind/BlindOutCome.swift
@@ -8,6 +8,7 @@ struct BlindOutcomeView: View {
@Environment(\.presentationMode) var presentationMode
@State private var isFullscreen = false
@State private var isPlaying = false
+ @State private var showIPListModal = false
var body: some View {
NavigationView {
@@ -99,9 +100,11 @@ struct BlindOutcomeView: View {
// Button below media
VStack(spacing: 16) {
Button(action: {
- // 如果携带的类型是video跳转到contentview
+ // 如果携带的类型是video显示弹窗
if case .video = media {
- // Router.shared.navigate(to: .mediaUpload)
+ withAnimation {
+ showIPListModal = true
+ }
} else {
Router.shared.navigate(to: .mediaUpload)
}
@@ -130,6 +133,9 @@ struct BlindOutcomeView: View {
FullscreenMediaView(media: media, isPresented: $isFullscreen, isPlaying: $isPlaying, player: nil)
}
}
+ .overlay(
+ JoinModal(isPresented: $showIPListModal)
+ )
}
.navigationViewStyle(StackNavigationViewStyle()) // 确保在iPad上也能正确显示
.navigationBarHidden(true) // 额外确保隐藏导航栏
diff --git a/wake/View/Blind/JoinModal.swift b/wake/View/Blind/JoinModal.swift
new file mode 100644
index 0000000..e215707
--- /dev/null
+++ b/wake/View/Blind/JoinModal.swift
@@ -0,0 +1,220 @@
+import SwiftUI
+
+struct JoinModal: View {
+ @Binding var isPresented: Bool
+
+ var body: some View {
+ ZStack(alignment: .bottom) {
+ // Semi-transparent background
+ if isPresented {
+ Color.black.opacity(0.4)
+ .edgesIgnoringSafeArea(.all)
+ .onTapGesture {
+ withAnimation {
+ isPresented = false
+ }
+ }
+ }
+
+ // Modal content
+ if isPresented {
+ VStack(spacing: 0) {
+ // IP Image peeking from top
+ HStack {
+ // Make sure you have an image named "IP" in your assets
+ SVGImage(svgName: "IP1")
+ .frame(width: 116, height: 65)
+ .offset(x: 30)
+ Spacer()
+ }
+ .frame(height: 65)
+
+ VStack(spacing: 0) {
+ // Close button on the right
+ HStack {
+ Spacer()
+ Button(action: {
+ withAnimation {
+ isPresented = false
+ }
+ }) {
+ Image(systemName: "xmark")
+ .font(.system(size: 20, weight: .medium))
+ .foregroundColor(.themeTextMessageMain)
+ .padding(12)
+ }
+ .padding(.trailing, 16)
+ }
+
+ // 文本
+ VStack(spacing: 8) {
+ Text("Join us!")
+ .font(Typography.font(for: .headline1, family: .quicksandBold))
+ .foregroundColor(.themeTextMessageMain)
+ Text("Join us to get more exclusive benefits.")
+ .font(.system(size: 14, weight: .regular))
+ .foregroundColor(.themeTextMessageMain)
+ }
+ .padding(.vertical, 12)
+ // List content
+ VStack (alignment: .leading) {
+ HStack {
+ SVGImage(svgName: "JoinList")
+ .frame(width: 32, height: 32)
+ HStack (alignment: .top){
+ Text("Unlimited")
+ .font(.system(size: 16, weight: .bold))
+ .foregroundColor(.themeTextMessageMain)
+ Text(" blind box purchases.")
+ .font(.system(size: 16, weight: .regular))
+ .foregroundColor(.themeTextMessageMain)
+ }
+ }
+ .padding(.vertical, 12)
+ .padding(.leading,12)
+ HStack (alignment: .center) {
+ SVGImage(svgName: "JoinList")
+ .frame(width: 32, height: 32)
+ VStack (alignment: .leading,spacing: 4) {
+ HStack {
+ Text("Freely")
+ .font(.system(size: 16, weight: .bold))
+ .foregroundColor(.themeTextMessageMain)
+ Text(" upload image and video")
+ .font(.system(size: 16, weight: .regular))
+ .foregroundColor(.themeTextMessageMain)
+ }
+ Text(" materials.")
+ .font(.system(size: 16, weight: .regular))
+ .foregroundColor(.themeTextMessageMain)
+ }
+ }
+ .padding(.vertical, 12)
+ .padding(.leading,12)
+
+ HStack(alignment: .top) {
+ SVGImage(svgName: "JoinList")
+ .frame(width: 32, height: 32)
+ VStack (alignment: .leading,spacing: 4) {
+ HStack {
+ Text("500")
+ .font(.system(size: 16, weight: .bold))
+ .foregroundColor(.themeTextMessageMain)
+ Text(" credits daily,")
+ .font(.system(size: 16, weight: .regular))
+ .foregroundColor(.themeTextMessageMain)
+ }
+ HStack(alignment: .top) {
+ VStack (alignment: .leading, spacing: 4) {
+ HStack {
+ Text("5000")
+ .font(.system(size: 16, weight: .bold))
+ .foregroundColor(.themeTextMessageMain)
+ Text(" permanent credits on your first")
+ .font(.system(size: 16, weight: .regular))
+ .foregroundColor(.themeTextMessageMain)
+ }
+ Text(" purchase!")
+ .font(.system(size: 16, weight: .regular))
+ .foregroundColor(.themeTextMessageMain)
+ }
+ }
+ }
+ }
+ .padding(.top, 12)
+ .padding(.leading,12)
+ HStack {
+ Spacer() // This will push the button to the right
+ Button(action: {
+ // 点击跳转到会员页面
+ Router.shared.navigate(to: .subscribe)
+ }) {
+ HStack {
+ Text("See More")
+ .font(.system(size: 16))
+ Image(systemName: "chevron.right")
+ .font(.system(size: 14))
+ }
+ .foregroundColor(.themeTextMessageMain)
+ .padding(.vertical, 12)
+ .padding(.horizontal, 24)
+ .cornerRadius(20)
+ }
+ }
+ .padding(.trailing, 16) // Add some right padding to match the design
+ Button(action: {
+ // 点击跳转到会员页面
+ Router.shared.navigate(to: .subscribe)
+ }) {
+ HStack {
+ Text("Subscribe")
+ .font(Typography.font(for: .body, family: .quicksandBold))
+ Spacer()
+ Text("$1.00/Mon")
+ .font(Typography.font(for: .body, family: .quicksandBold))
+ }
+ .foregroundColor(.themeTextMessageMain)
+ .padding(.vertical, 12)
+ .padding(.horizontal, 30)
+ .background(Color.themePrimary)
+ .cornerRadius(20)
+ }
+ .padding(.top, 16)
+ // 协议条款
+ HStack(alignment: .center) {
+ Button(action: {
+ // Action for Terms of Service
+ }) {
+ Text("Terms of Service")
+ .font(.system(size: 12, weight: .regular))
+ .foregroundColor(.themeTextMessage)
+ .underline() // Add underline
+ }
+ Rectangle()
+ .fill(Color.gray.opacity(0.5))
+ .frame(width: 1, height: 16)
+ .padding(.vertical, 4)
+ Button(action: {
+ // Action for Privacy Policy
+ }) {
+ Text("Privacy Policy")
+ .font(.system(size: 12, weight: .regular))
+ .foregroundColor(.themeTextMessage)
+ .underline() // Add underline
+ }
+ Rectangle()
+ .fill(Color.gray.opacity(0.5))
+ .frame(width: 1, height: 16)
+ .padding(.vertical, 4)
+ Button(action: {
+ // Action for Restore Purchase
+ }) {
+ Text("Restore Purchase")
+ .font(.system(size: 12, weight: .regular))
+ .foregroundColor(.themeTextMessage)
+ .underline() // Add underline
+ }
+ }
+ .padding(.bottom, 24)
+ .frame(maxWidth: .infinity, alignment: .center)
+ }
+ .padding(.horizontal, 16)
+ }
+ .background(Color.white)
+ .cornerRadius(20, corners: [.topLeft, .topRight])
+ }
+ .frame(height: nil)
+ .transition(.move(edge: .bottom))
+ }
+ }
+ .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
+ .edgesIgnoringSafeArea(.all)
+ .animation(.easeInOut, value: isPresented)
+ }
+}
+
+struct JoinModal_Previews: PreviewProvider {
+ static var previews: some View {
+ JoinModal(isPresented: .constant(true))
+ }
+}
diff --git a/wake/View/Upload/MediaUploadView.swift b/wake/View/Upload/MediaUploadView.swift
index 633e2e5..5ef72a4 100644
--- a/wake/View/Upload/MediaUploadView.swift
+++ b/wake/View/Upload/MediaUploadView.swift
@@ -167,7 +167,7 @@ struct MediaUploadView: View {
}
// 开始上传
- uploadManager.startUpload()
+ // uploadManager.startUpload()
} else {
print("ℹ️ 没有新文件需要添加,所有选择的文件都已存在")
}
@@ -249,7 +249,7 @@ struct MediaUploadView: View {
}
// 开始上传新添加的媒体
- uploadManager.startUpload()
+ // uploadManager.startUpload()
print("媒体添加完成,总数量: \(uploadManager.selectedMedia.count)")
}
}
diff --git a/wake/WakeApp.swift b/wake/WakeApp.swift
index 894aea3..ec8f291 100644
--- a/wake/WakeApp.swift
+++ b/wake/WakeApp.swift
@@ -46,7 +46,7 @@ struct WakeApp: App {
// 根据登录状态显示不同视图
if authState.isAuthenticated {
// 已登录:显示userInfo页面
- LoginView()
+ MediaUploadView()
.environmentObject(authState)
// ContentView()
// .environmentObject(authState)