import SwiftUI import ComposableArchitecture struct DetailView: View { @State var store: StoreOf let onLikeSuccess: ((Int, Bool) -> Void)? init(store: StoreOf, onLikeSuccess: ((Int, Bool) -> Void)? = nil) { self.store = store self.onLikeSuccess = onLikeSuccess } var body: some View { ZStack { // 背景图片 Image("bg") .resizable() .aspectRatio(contentMode: .fill) .ignoresSafeArea() VStack(spacing: 0) { // 自定义导航栏 WithPerceptionTracking { CustomNavigationBar( title: LocalizedString("detail.title", comment: "Detail page title"), showDeleteButton: isCurrentUserDynamic, isDeleteLoading: store.isDeleteLoading, onBack: { // 移除 onDismiss?() 调用,因为现在使用 dismiss() }, onDelete: { store.send(.deleteDynamic) } ) } .padding(.top, 24) // 内容区域 ScrollView { VStack(spacing: 0) { // 使用OptimizedDynamicCardView显示动态内容 WithPerceptionTracking { OptimizedDynamicCardView( moment: store.moment, allMoments: [store.moment], // 详情页只有一个动态 currentIndex: 0, onImageTap: { images, index in store.send(.showImagePreview(images, index)) }, onLikeTap: { dynamicId, uid, likedUid, worldId in store.send(.likeDynamic(dynamicId, uid, likedUid, worldId)) }, onCardTap: nil, // 详情页不需要卡片点击 isDetailMode: true, // 详情页模式,点击卡片不跳转 isLikeLoading: store.isLikeLoading ) .padding(.horizontal, 16) .padding(.top, 16) .padding(.bottom, 116) } } } } } .navigationBarHidden(true) .onAppear { debugInfoSync("🔍 DetailView: onAppear - moment.uid: \(store.moment.uid)") store.send(.onAppear) } .onChange(of: store.shouldDismiss) { shouldDismiss in if shouldDismiss { debugInfoSync("🔍 DetailView: shouldDismiss = true, 调用onDismiss") // 移除 onDismiss?() 移除此行,因为我们现在使用 dismiss } } .fullScreenCover(isPresented: Binding( get: { store.showImagePreview }, set: { _ in store.send(.hideImagePreview) } )) { WithPerceptionTracking { ImagePreviewPager( images: store.selectedImages, currentIndex: Binding( get: { store.selectedImageIndex }, set: { newIndex in store.send(.showImagePreview(store.selectedImages, newIndex)) } ), onClose: { store.send(.imagePreviewDismissed) } ) } } } // 判断是否为当前用户的动态 private var isCurrentUserDynamic: Bool { // 使用store中的当前用户ID进行判断 guard let currentUserId = store.currentUserId, let currentUserIdInt = Int(currentUserId) else { debugInfoSync("🔍 DetailView: 无法获取当前用户ID - currentUserId: \(store.currentUserId ?? "nil")") return false } let isCurrentUser = store.moment.uid == currentUserIdInt debugInfoSync("🔍 DetailView: 动态用户判断 - moment.uid: \(store.moment.uid), currentUserId: \(currentUserIdInt), isCurrentUser: \(isCurrentUser)") return isCurrentUser } } // MARK: - CustomNavigationBar struct CustomNavigationBar: View { let title: String let showDeleteButton: Bool let isDeleteLoading: Bool let onBack: () -> Void let onDelete: () -> Void init(title: String, showDeleteButton: Bool, isDeleteLoading: Bool, onBack: @escaping () -> Void, onDelete: @escaping () -> Void) { self.title = title self.showDeleteButton = showDeleteButton self.isDeleteLoading = isDeleteLoading self.onBack = onBack self.onDelete = onDelete } @SwiftUI.Environment(\.dismiss) private var dismiss: SwiftUI.DismissAction var body: some View { HStack { // 返回按钮 Button(action: { onBack() dismiss() // 使用 dismiss 关闭视图 }) { Image(systemName: "chevron.left") .font(.system(size: 20, weight: .medium)) .foregroundColor(.white) .frame(width: 44, height: 44) .background(Color.black.opacity(0.3)) .clipShape(Circle()) } Spacer() // 标题 Text(title) .font(.system(size: 18, weight: .semibold)) .foregroundColor(.white) .shadow(color: .black.opacity(0.5), radius: 2, x: 0, y: 1) Spacer() // 删除按钮(仅在需要时显示) WithPerceptionTracking { if showDeleteButton { Button(action: onDelete) { if isDeleteLoading { ProgressView() .progressViewStyle(CircularProgressViewStyle(tint: .white)) .scaleEffect(0.8) .frame(width: 44, height: 44) .background(Color.red.opacity(0.8)) .clipShape(Circle()) } else { Image(systemName: "trash") .font(.system(size: 16, weight: .medium)) .foregroundColor(.white) .frame(width: 44, height: 44) .background(Color.red.opacity(0.8)) .clipShape(Circle()) } } .disabled(isDeleteLoading) } else { // 占位,保持标题居中 Color.clear .frame(width: 44, height: 44) } } } .padding(.horizontal, 16) .padding(.top, 8) .padding(.bottom, 12) .background( LinearGradient( gradient: Gradient(colors: [ Color.black.opacity(0.4), Color.black.opacity(0.2), Color.clear ]), startPoint: .top, endPoint: .bottom ) ) } } //#Preview { // DetailView( // store: Store( // initialState: DetailFeature.State( // moment: MomentsInfo( // dynamicId: 1, // uid: 123, // nick: "Test User", // avatar: "https://example.com/avatar.jpg", // type: 1, // content: "This is a test dynamic content", // publishTime: Int(Date().timeIntervalSince1970 * 1000), // likeCount: 10, // isLike: false, // worldId: 1, // dynamicResList: [ // MomentsPicture( // id: 1, // resUrl: "https://example.com/image1.jpg", // format: "jpg", // width: 800, // height: 600, // resDuration: nil // ) // ] // ) // ) // ) { // DetailFeature() // } // ) //}