feat: 主页面轮询
This commit is contained in:
parent
4cbfaefb49
commit
aa954ddfb9
@ -2,17 +2,16 @@ import SwiftUI
|
|||||||
import SwiftData
|
import SwiftData
|
||||||
import AVKit
|
import AVKit
|
||||||
|
|
||||||
// MARK: - Constants
|
// 添加通知名称
|
||||||
private enum MediaURLs {
|
extension Notification.Name {
|
||||||
static let videoURL = "https://cdn.memorywake.com/users/7363409620351717377/files/7366657553935241216/39C069E1-7C3E-4261-8486-12058F855B38.mov"
|
static let blindBoxStatusChanged = Notification.Name("blindBoxStatusChanged")
|
||||||
static let imageURL = "https://cdn.fairclip.cn/files/7343228671693557760/20250604-164000.jpg"
|
|
||||||
static let VideoBlindURL = "https://cdn.memorywake.com/users/7363409620351717377/files/7366658779259211776/AD970D28-9D1E-4817-A245-F11967441B8F.mp4"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum BlindBoxAnimationPhase {
|
private enum BlindBoxAnimationPhase {
|
||||||
case loading
|
case loading
|
||||||
case ready
|
case ready
|
||||||
case opening
|
case opening
|
||||||
|
case none
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Notification.Name {
|
extension Notification.Name {
|
||||||
@ -198,6 +197,70 @@ struct BlindBoxView: View {
|
|||||||
let url: String
|
let url: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - BlindBox Response Model
|
||||||
|
|
||||||
|
struct BlindBoxData: Codable {
|
||||||
|
let id: Int64
|
||||||
|
let boxCode: String
|
||||||
|
let userId: Int64
|
||||||
|
let name: String
|
||||||
|
let boxType: String
|
||||||
|
let features: String?
|
||||||
|
let url: String?
|
||||||
|
let status: String
|
||||||
|
let workflowInstanceId: String?
|
||||||
|
// 视频生成时间
|
||||||
|
let videoGenerateTime: String?
|
||||||
|
let createTime: String
|
||||||
|
let description: String?
|
||||||
|
|
||||||
|
enum CodingKeys: String, CodingKey {
|
||||||
|
case id
|
||||||
|
case boxCode = "box_code"
|
||||||
|
case userId = "user_id"
|
||||||
|
case name
|
||||||
|
case boxType = "box_type"
|
||||||
|
case features
|
||||||
|
case url
|
||||||
|
case status
|
||||||
|
case workflowInstanceId = "workflow_instance_id"
|
||||||
|
case videoGenerateTime = "video_generate_time"
|
||||||
|
case createTime = "create_time"
|
||||||
|
case description
|
||||||
|
}
|
||||||
|
|
||||||
|
init(id: Int64, boxCode: String, userId: Int64, name: String, boxType: String, features: String?, url: String?, status: String, workflowInstanceId: String?, videoGenerateTime: String?, createTime: String, description: String?) {
|
||||||
|
self.id = id
|
||||||
|
self.boxCode = boxCode
|
||||||
|
self.userId = userId
|
||||||
|
self.name = name
|
||||||
|
self.boxType = boxType
|
||||||
|
self.features = features
|
||||||
|
self.url = url
|
||||||
|
self.status = status
|
||||||
|
self.workflowInstanceId = workflowInstanceId
|
||||||
|
self.videoGenerateTime = videoGenerateTime
|
||||||
|
self.createTime = createTime
|
||||||
|
self.description = description
|
||||||
|
}
|
||||||
|
|
||||||
|
init(from listItem: BlindList) {
|
||||||
|
self.init(
|
||||||
|
id: listItem.id,
|
||||||
|
boxCode: listItem.boxCode,
|
||||||
|
userId: listItem.userId,
|
||||||
|
name: listItem.name,
|
||||||
|
boxType: listItem.boxType,
|
||||||
|
features: listItem.features,
|
||||||
|
url: nil,
|
||||||
|
status: listItem.status,
|
||||||
|
workflowInstanceId: listItem.workflowInstanceId,
|
||||||
|
videoGenerateTime: listItem.videoGenerateTime,
|
||||||
|
createTime: listItem.createTime,
|
||||||
|
description: listItem.description
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mediaType: BlindBoxMediaType
|
let mediaType: BlindBoxMediaType
|
||||||
@State private var showModal = false // 控制用户资料弹窗显示
|
@State private var showModal = false // 控制用户资料弹窗显示
|
||||||
@ -206,7 +269,21 @@ struct BlindBoxView: View {
|
|||||||
@State private var memberProfile: MemberProfile? = nil
|
@State private var memberProfile: MemberProfile? = nil
|
||||||
@State private var blindCount: BlindCount? = nil
|
@State private var blindCount: BlindCount? = nil
|
||||||
@State private var blindList: [BlindList] = [] // Changed to array
|
@State private var blindList: [BlindList] = [] // Changed to array
|
||||||
|
// 生成盲盒
|
||||||
|
@State private var blindGenerate : BlindBoxData?
|
||||||
@State private var showLottieAnimation = true
|
@State private var showLottieAnimation = true
|
||||||
|
// 轮询接口
|
||||||
|
@State private var isPolling = false
|
||||||
|
@State private var pollingTimer: Timer?
|
||||||
|
@State private var currentBoxType: String = ""
|
||||||
|
// 盲盒链接
|
||||||
|
@State private var videoURL: String = ""
|
||||||
|
@State private var imageURL: String = ""
|
||||||
|
// 按钮状态 倒计时
|
||||||
|
@State private var countdown: (minutes: Int, seconds: Int, milliseconds: Int) = (36, 50, 20)
|
||||||
|
@State private var countdownTimer: Timer?
|
||||||
|
// 盲盒数据
|
||||||
|
@State private var displayData: BlindBoxData? = nil
|
||||||
@State private var showScalingOverlay = false
|
@State private var showScalingOverlay = false
|
||||||
@State private var animationPhase: BlindBoxAnimationPhase = .loading
|
@State private var animationPhase: BlindBoxAnimationPhase = .loading
|
||||||
@State private var scale: CGFloat = 0.1
|
@State private var scale: CGFloat = 0.1
|
||||||
@ -224,16 +301,51 @@ struct BlindBoxView: View {
|
|||||||
self.mediaType = mediaType
|
self.mediaType = mediaType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 倒计时
|
||||||
|
private func startCountdown() {
|
||||||
|
// 重置为36:50:20
|
||||||
|
countdown = (36, 50, 20)
|
||||||
|
|
||||||
|
countdownTimer?.invalidate()
|
||||||
|
countdownTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
|
||||||
|
var (minutes, seconds, milliseconds) = countdown
|
||||||
|
|
||||||
|
// 更新毫秒
|
||||||
|
milliseconds -= 10
|
||||||
|
if milliseconds < 0 {
|
||||||
|
milliseconds = 90
|
||||||
|
seconds -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新秒
|
||||||
|
if seconds < 0 {
|
||||||
|
seconds = 59
|
||||||
|
minutes -= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果倒计时结束,停止计时器
|
||||||
|
if minutes <= 0 && seconds <= 0 && milliseconds <= 0 {
|
||||||
|
countdownTimer?.invalidate()
|
||||||
|
countdownTimer = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
countdown = (minutes, seconds, milliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func loadMedia() {
|
private func loadMedia() {
|
||||||
print("loadMedia called with mediaType: \(mediaType)")
|
print("loadMedia called with mediaType: \(mediaType)")
|
||||||
|
|
||||||
switch mediaType {
|
switch mediaType {
|
||||||
case .video:
|
case .video:
|
||||||
loadVideo()
|
loadVideo()
|
||||||
print("Loading video...")
|
currentBoxType = "Video"
|
||||||
|
startPolling()
|
||||||
case .image:
|
case .image:
|
||||||
loadImage()
|
loadImage()
|
||||||
print("Loading image...")
|
currentBoxType = "Image"
|
||||||
|
startPolling()
|
||||||
case .all:
|
case .all:
|
||||||
print("Loading all content...")
|
print("Loading all content...")
|
||||||
// 会员信息
|
// 会员信息
|
||||||
@ -278,28 +390,82 @@ struct BlindBoxView: View {
|
|||||||
switch result {
|
switch result {
|
||||||
case .success(let response):
|
case .success(let response):
|
||||||
self.blindList = response.data ?? []
|
self.blindList = response.data ?? []
|
||||||
|
// 如果列表为空数组 设置盲盒状态为none
|
||||||
|
if self.blindList.isEmpty {
|
||||||
|
self.animationPhase = .none
|
||||||
|
}
|
||||||
print("✅ 成功获取 \(self.blindList.count) 个盲盒")
|
print("✅ 成功获取 \(self.blindList.count) 个盲盒")
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
self.blindList = []
|
self.blindList = []
|
||||||
|
self.animationPhase = .none
|
||||||
print("❌ 获取盲盒列表失败:", error.localizedDescription)
|
print("❌ 获取盲盒列表失败:", error.localizedDescription)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 轮询接口
|
||||||
|
private func startPolling() {
|
||||||
|
stopPolling()
|
||||||
|
isPolling = true
|
||||||
|
checkBlindBoxStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func stopPolling() {
|
||||||
|
pollingTimer?.invalidate()
|
||||||
|
pollingTimer = nil
|
||||||
|
isPolling = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func checkBlindBoxStatus() {
|
||||||
|
guard !currentBoxType.isEmpty else {
|
||||||
|
stopPolling()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 盲盒列表
|
|
||||||
NetworkService.shared.postWithToken(
|
NetworkService.shared.postWithToken(
|
||||||
path: "/blind_box/generate/mock",
|
path: "/blind_box/generate/mock",
|
||||||
parameters: ["box_type": "Image"]
|
parameters: ["box_type": currentBoxType]
|
||||||
) { (result: Result<APIResponse<[BlindList]>, NetworkError>) in
|
) { (result: Result<APIResponse<BlindBoxData>, NetworkError>) in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let response):
|
case .success(let response):
|
||||||
self.blindList = response.data ?? []
|
let data = response.data
|
||||||
print("✅✅✅✅✅✅✅✅✅ 成功获取 \(self.blindList.count) 个盲盒")
|
self.blindGenerate = data
|
||||||
case .failure(let error):
|
print("当前盲盒状态: \(data.status)")
|
||||||
self.blindList = []
|
// 更新显示数据
|
||||||
print("❌❌ ❌ ❌ ❌ ❌ ❌ 获取盲盒列表失败:", error.localizedDescription)
|
if self.mediaType == .all, let firstItem = self.blindList.first {
|
||||||
|
self.displayData = BlindBoxData(from: firstItem)
|
||||||
|
} else {
|
||||||
|
self.displayData = data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发送状态变更通知
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: .blindBoxStatusChanged,
|
||||||
|
object: nil,
|
||||||
|
userInfo: ["status": data.status]
|
||||||
|
)
|
||||||
|
|
||||||
|
if data.status != "Preparing" {
|
||||||
|
self.stopPolling()
|
||||||
|
print("✅ 盲盒准备就绪,状态: \(data.status)")
|
||||||
|
if self.mediaType == .video {
|
||||||
|
self.videoURL = data.url ?? ""
|
||||||
|
} else if self.mediaType == .image {
|
||||||
|
self.imageURL = data.url ?? ""
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.pollingTimer = Timer.scheduledTimer(
|
||||||
|
withTimeInterval: 2.0,
|
||||||
|
repeats: false
|
||||||
|
) { _ in
|
||||||
|
self.checkBlindBoxStatus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case .failure(let error):
|
||||||
|
print("❌ 获取盲盒状态失败: \(error.localizedDescription)")
|
||||||
|
self.stopPolling()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,7 +490,11 @@ struct BlindBoxView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func loadImage() {
|
private func loadImage() {
|
||||||
guard let url = URL(string: MediaURLs.imageURL) else { return }
|
guard !imageURL.isEmpty, let url = URL(string: imageURL) else {
|
||||||
|
print("⚠️ 图片URL无效或为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
URLSession.shared.dataTask(with: url) { data, _, _ in
|
URLSession.shared.dataTask(with: url) { data, _, _ in
|
||||||
if let data = data, let image = UIImage(data: data) {
|
if let data = data, let image = UIImage(data: data) {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
@ -337,7 +507,11 @@ struct BlindBoxView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func loadVideo() {
|
private func loadVideo() {
|
||||||
guard let url = URL(string: MediaURLs.videoURL) else { return }
|
guard !videoURL.isEmpty, let url = URL(string: videoURL) else {
|
||||||
|
print("⚠️ 视频URL无效或为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let asset = AVAsset(url: url)
|
let asset = AVAsset(url: url)
|
||||||
let playerItem = AVPlayerItem(asset: asset)
|
let playerItem = AVPlayerItem(asset: asset)
|
||||||
let player = AVPlayer(playerItem: playerItem)
|
let player = AVPlayer(playerItem: playerItem)
|
||||||
@ -352,8 +526,9 @@ struct BlindBoxView: View {
|
|||||||
isPortrait = height > width
|
isPortrait = height > width
|
||||||
}
|
}
|
||||||
|
|
||||||
player.isMuted = true
|
// Update the video player
|
||||||
self.videoPlayer = player
|
videoPlayer = player
|
||||||
|
videoPlayer?.play()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func startScalingAnimation() {
|
private func startScalingAnimation() {
|
||||||
@ -388,8 +563,51 @@ struct BlindBoxView: View {
|
|||||||
.onAppear {
|
.onAppear {
|
||||||
print("🎯 BlindBoxView appeared with mediaType: \(mediaType)")
|
print("🎯 BlindBoxView appeared with mediaType: \(mediaType)")
|
||||||
print("🎯 Current thread: \(Thread.current)")
|
print("🎯 Current thread: \(Thread.current)")
|
||||||
|
// 初始化显示数据
|
||||||
|
if mediaType == .all, let firstItem = blindList.first {
|
||||||
|
displayData = BlindBoxData(from: firstItem)
|
||||||
|
} else {
|
||||||
|
displayData = blindGenerate
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加盲盒状态变化监听
|
||||||
|
NotificationCenter.default.addObserver(
|
||||||
|
forName: .blindBoxStatusChanged,
|
||||||
|
object: nil,
|
||||||
|
queue: .main
|
||||||
|
) { notification in
|
||||||
|
if let status = notification.userInfo?["status"] as? String {
|
||||||
|
switch status {
|
||||||
|
case "Preparing":
|
||||||
|
withAnimation {
|
||||||
|
self.animationPhase = .loading
|
||||||
|
}
|
||||||
|
case "Unopened":
|
||||||
|
withAnimation {
|
||||||
|
self.animationPhase = .ready
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// 其他状态不处理
|
||||||
|
withAnimation {
|
||||||
|
self.animationPhase = .ready
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 调用接口
|
||||||
loadMedia()
|
loadMedia()
|
||||||
}
|
}
|
||||||
|
.onDisappear {
|
||||||
|
stopPolling()
|
||||||
|
countdownTimer?.invalidate()
|
||||||
|
countdownTimer = nil
|
||||||
|
NotificationCenter.default.removeObserver(
|
||||||
|
self,
|
||||||
|
name: .blindBoxStatusChanged,
|
||||||
|
object: nil
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if showScalingOverlay {
|
if showScalingOverlay {
|
||||||
ZStack {
|
ZStack {
|
||||||
@ -426,8 +644,8 @@ struct BlindBoxView: View {
|
|||||||
HStack {
|
HStack {
|
||||||
Button(action: {
|
Button(action: {
|
||||||
// 导航到BlindOutcomeView
|
// 导航到BlindOutcomeView
|
||||||
if mediaType == .video, let videoURL = URL(string: MediaURLs.videoURL) {
|
if mediaType == .video, !videoURL.isEmpty, let url = URL(string: videoURL) {
|
||||||
Router.shared.navigate(to: .blindOutcome(media: .video(videoURL, nil)))
|
Router.shared.navigate(to: .blindOutcome(media: .video(url, nil)))
|
||||||
} else if mediaType == .image, let image = displayImage {
|
} else if mediaType == .image, let image = displayImage {
|
||||||
Router.shared.navigate(to: .blindOutcome(media: .image(image)))
|
Router.shared.navigate(to: .blindOutcome(media: .image(image)))
|
||||||
}
|
}
|
||||||
@ -471,6 +689,7 @@ struct BlindBoxView: View {
|
|||||||
// Original content
|
// Original content
|
||||||
VStack {
|
VStack {
|
||||||
VStack(spacing: 20) {
|
VStack(spacing: 20) {
|
||||||
|
if mediaType == .all {
|
||||||
// 顶部导航栏
|
// 顶部导航栏
|
||||||
HStack {
|
HStack {
|
||||||
// 设置按钮
|
// 设置按钮
|
||||||
@ -522,6 +741,7 @@ struct BlindBoxView: View {
|
|||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
.padding(.top, 20)
|
.padding(.top, 20)
|
||||||
|
}
|
||||||
// 标题
|
// 标题
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
Text("Hi! Click And")
|
Text("Hi! Click And")
|
||||||
@ -550,19 +770,34 @@ struct BlindBoxView: View {
|
|||||||
.opacity(showScalingOverlay ? 0 : 1)
|
.opacity(showScalingOverlay ? 0 : 1)
|
||||||
.animation(.easeOut(duration: 1.5), value: showScalingOverlay)
|
.animation(.easeOut(duration: 1.5), value: showScalingOverlay)
|
||||||
}
|
}
|
||||||
|
if mediaType == .all && !showScalingOverlay {
|
||||||
|
ZStack {
|
||||||
|
SVGImage(svgName: "BlindCount")
|
||||||
|
.frame(width: 100, height: 60)
|
||||||
|
|
||||||
|
Text("\(blindCount?.availableQuantity ?? 0) Boxes")
|
||||||
|
.font(Typography.font(for: .body, family: .quicksandBold))
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.offset(x: 6, y: -18)
|
||||||
|
}
|
||||||
|
.position(x: UIScreen.main.bounds.width * 0.7,
|
||||||
|
y: UIScreen.main.bounds.height * 0.18)
|
||||||
|
.opacity(showScalingOverlay ? 0 : 1)
|
||||||
|
.animation(.easeOut(duration: 1.5), value: showScalingOverlay)
|
||||||
|
}
|
||||||
if !showScalingOverlay {
|
if !showScalingOverlay {
|
||||||
VStack(spacing: 20) {
|
VStack(spacing: 20) {
|
||||||
switch animationPhase {
|
switch animationPhase {
|
||||||
case .loading:
|
case .loading:
|
||||||
GIFView(name: "BlindLoading")
|
GIFView(name: "BlindLoading")
|
||||||
.frame(width: 300, height: 300)
|
.frame(width: 300, height: 300)
|
||||||
.onAppear {
|
// .onAppear {
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 6) {
|
// DispatchQueue.main.asyncAfter(deadline: .now() + 6) {
|
||||||
withAnimation {
|
// withAnimation {
|
||||||
animationPhase = .ready
|
// animationPhase = .ready
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
case .ready:
|
case .ready:
|
||||||
ZStack {
|
ZStack {
|
||||||
@ -592,33 +827,23 @@ struct BlindBoxView: View {
|
|||||||
self.startScalingAnimation()
|
self.startScalingAnimation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case .none:
|
||||||
|
SVGImage(svgName: "BlindNone")
|
||||||
|
.frame(width: 300, height: 300)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.offset(y: -50)
|
.offset(y: -50)
|
||||||
.compositingGroup()
|
.compositingGroup()
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
if !showScalingOverlay {
|
|
||||||
ZStack {
|
|
||||||
SVGImage(svgName: "BlindCount")
|
|
||||||
.frame(width: 100, height: 60)
|
|
||||||
|
|
||||||
Text("\(blindCount?.availableQuantity ?? 0) Boxes")
|
|
||||||
.font(Typography.font(for: .body, family: .quicksandBold))
|
|
||||||
.foregroundColor(.white)
|
|
||||||
.offset(x: 6, y: -18)
|
|
||||||
}
|
|
||||||
.position(x: UIScreen.main.bounds.width * 0.7,
|
|
||||||
y: UIScreen.main.bounds.height * 0.18)
|
|
||||||
.opacity(showScalingOverlay ? 0 : 1)
|
|
||||||
.animation(.easeOut(duration: 1.5), value: showScalingOverlay)
|
|
||||||
}
|
|
||||||
if !showScalingOverlay {
|
if !showScalingOverlay {
|
||||||
VStack(alignment: .leading, spacing: 8) {
|
VStack(alignment: .leading, spacing: 8) {
|
||||||
Text("hhsdshjsjdhn")
|
// 从变量blindGenerate中获取description
|
||||||
|
Text(blindGenerate?.videoGenerateTime ?? "hhsdshjsjdhn")
|
||||||
.font(Typography.font(for: .body, family: .quicksandBold))
|
.font(Typography.font(for: .body, family: .quicksandBold))
|
||||||
.foregroundColor(Color.themeTextMessageMain)
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
Text("informationinformationinformationinformationinformationinformation")
|
Text(blindGenerate?.description ?? "informationinformationinformationinformationinformationinformation")
|
||||||
.font(.system(size: 14))
|
.font(.system(size: 14))
|
||||||
.foregroundColor(Color.themeTextMessageMain)
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
}
|
}
|
||||||
@ -636,7 +861,38 @@ struct BlindBoxView: View {
|
|||||||
.offset(y: showScalingOverlay ? -100 : 0)
|
.offset(y: showScalingOverlay ? -100 : 0)
|
||||||
.animation(.easeInOut(duration: 1.5), value: showScalingOverlay)
|
.animation(.easeInOut(duration: 1.5), value: showScalingOverlay)
|
||||||
// 打开
|
// 打开
|
||||||
Button(action: showUserProfile) {
|
if mediaType == .all {
|
||||||
|
Button(action: {
|
||||||
|
if animationPhase == .ready {
|
||||||
|
// 处理准备就绪状态的操作
|
||||||
|
// 导航到订阅页面
|
||||||
|
Router.shared.navigate(to: .subscribe)
|
||||||
|
} else {
|
||||||
|
showUserProfile()
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
if animationPhase == .loading {
|
||||||
|
Text("Next: \(countdown.minutes):\(String(format: "%02d", countdown.seconds)).\(String(format: "%02d", countdown.milliseconds))")
|
||||||
|
.font(Typography.font(for: .body))
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding()
|
||||||
|
.background(Color.white)
|
||||||
|
.foregroundColor(.black)
|
||||||
|
.cornerRadius(32)
|
||||||
|
.onAppear {
|
||||||
|
startCountdown()
|
||||||
|
}
|
||||||
|
} else if animationPhase == .ready {
|
||||||
|
Text("Ready")
|
||||||
|
.font(Typography.font(for: .body))
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding()
|
||||||
|
.background(Color.themePrimary)
|
||||||
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
|
.cornerRadius(32)
|
||||||
|
} else {
|
||||||
Text("Go to Buy")
|
Text("Go to Buy")
|
||||||
.font(Typography.font(for: .body))
|
.font(Typography.font(for: .body))
|
||||||
.fontWeight(.bold)
|
.fontWeight(.bold)
|
||||||
@ -646,8 +902,10 @@ struct BlindBoxView: View {
|
|||||||
.foregroundColor(Color.themeTextMessageMain)
|
.foregroundColor(Color.themeTextMessageMain)
|
||||||
.cornerRadius(32)
|
.cornerRadius(32)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
.background(Color.themeTextWhiteSecondary)
|
.background(Color.themeTextWhiteSecondary)
|
||||||
.offset(x: showModal ? UIScreen.main.bounds.width * 0.8 : 0)
|
.offset(x: showModal ? UIScreen.main.bounds.width * 0.8 : 0)
|
||||||
|
|||||||
@ -46,17 +46,19 @@ struct WakeApp: App {
|
|||||||
if authState.isAuthenticated {
|
if authState.isAuthenticated {
|
||||||
// 已登录:显示主页面
|
// 已登录:显示主页面
|
||||||
NavigationStack(path: $router.path) {
|
NavigationStack(path: $router.path) {
|
||||||
BlindBoxView(mediaType: .all)
|
// BlindBoxView(mediaType: .all)
|
||||||
|
// .navigationDestination(for: AppRoute.self) { route in
|
||||||
|
// route.view
|
||||||
|
// }
|
||||||
|
LoginView()
|
||||||
.navigationDestination(for: AppRoute.self) { route in
|
.navigationDestination(for: AppRoute.self) { route in
|
||||||
route.view
|
route.view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 未登录:显示登录界面
|
// 未登录:显示登录界面
|
||||||
// LoginView()
|
|
||||||
// .environmentObject(authState)
|
|
||||||
NavigationStack(path: $router.path) {
|
NavigationStack(path: $router.path) {
|
||||||
BlindBoxView(mediaType: .all)
|
LoginView()
|
||||||
.navigationDestination(for: AppRoute.self) { route in
|
.navigationDestination(for: AppRoute.self) { route in
|
||||||
route.view
|
route.view
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user