import SwiftUI import ComposableArchitecture struct MeView: View { let store: StoreOf // 新增:图片预览状态 @State private var previewItem: PreviewItem? = nil @State private var previewCurrentIndex: Int = 0 // 新增:是否显示关闭按钮 let showCloseButton: Bool // 新增:dismiss环境变量 @Environment(\.dismiss) private var dismiss init(store: StoreOf, showCloseButton: Bool = false) { self.store = store self.showCloseButton = showCloseButton } var body: some View { WithPerceptionTracking { GeometryReader { geometry in ZStack { // 背景图片 Image("bg") .resizable() .aspectRatio(contentMode: .fill) .frame(maxWidth: .infinity, maxHeight: .infinity) .clipped() .ignoresSafeArea(.all) // 顶部栏,右上角设置按钮 VStack { HStack { // 新增:关闭按钮(仅在present时显示) if showCloseButton { Button(action: { dismiss() }) { Image(systemName: "xmark") .font(.system(size: 20, weight: .medium)) .foregroundColor(.white) .frame(width: 44, height: 44) .background(Color.black.opacity(0.3)) .clipShape(Circle()) } .padding(.leading, 16) .padding(.top, 8) } Spacer() if !store.isDisplayingOtherUser { Button(action: { store.send(.settingButtonTapped) }) { Image(systemName: "gearshape") .font(.system(size: 33, weight: .medium)) .foregroundColor(.white) } .padding(.trailing, 16) .padding(.top, 8) } } Spacer() } // 主要内容区域 VStack(spacing: 16) { // 用户信息区域 userInfoSection() // 动态内容区域 momentsSection() Spacer() } .frame(maxWidth: .infinity, alignment: .top) .padding(.top, 8) } } .onAppear { debugInfoSync("📱 MeView onAppear") debugInfoSync(" 用户信息: \(store.userInfo?.nick ?? "nil")") debugInfoSync(" 动态数量: \(store.moments.count)") debugInfoSync(" 用户信息错误: \(store.userInfoError ?? "nil")") debugInfoSync(" 动态错误: \(store.momentsError ?? "nil")") debugInfoSync(" 显示错误视图: \(store.showErrorView)") store.send(.onAppear) } // 新增:图片预览弹窗 .fullScreenCover(item: $previewItem) { item in ImagePreviewPager(images: item.images as [String], currentIndex: $previewCurrentIndex) { previewItem = nil } } // 新增:详情页导航 .navigationDestination(isPresented: Binding( get: { store.showDetail }, set: { _ in store.send(.detailDismissed) } )) { if let selectedMoment = store.selectedMoment { let detailStore = Store( initialState: DetailFeature.State(moment: selectedMoment) ) { DetailFeature() } DetailView(store: detailStore) .onChange(of: detailStore.shouldDismiss) { _, shouldDismiss in if shouldDismiss { store.send(.detailDismissed) } } } } } } // MARK: - 用户信息区域 @ViewBuilder private func userInfoSection() -> some View { WithPerceptionTracking { VStack(spacing: 16) { // 头像 AsyncImage(url: URL(string: store.userInfo?.avatar ?? "")) { image in image .resizable() .aspectRatio(contentMode: .fill) } placeholder: { Image(systemName: "person.circle.fill") .resizable() .aspectRatio(contentMode: .fill) .foregroundColor(.gray) } .frame(width: 130, height: 130) .clipShape(Circle()) .overlay( Circle() .stroke(Color.white, lineWidth: 2) ) // 用户昵称 Text(store.userInfo?.nick ?? "未知用户") .font(.system(size: 20, weight: .medium)) .foregroundColor(.white) // 用户ID UserIDDisplay(uid: store.userInfo?.uid ?? 0, isDisplayCopy: true) } .padding(.horizontal, 32) } } // MARK: - 动态内容区域 @ViewBuilder private func momentsSection() -> some View { WithPerceptionTracking { if store.isLoadingUserInfo || store.isLoadingMoments { VStack { ProgressView() .progressViewStyle(CircularProgressViewStyle(tint: .white)) .scaleEffect(1.2) Text("加载中...") .font(.system(size: 14)) .foregroundColor(.white.opacity(0.7)) .padding(.top, 8) } .frame(maxWidth: .infinity, maxHeight: .infinity) } else if let error = store.userInfoError { VStack(spacing: 12) { Image(systemName: "exclamationmark.triangle") .font(.system(size: 32)) .foregroundColor(.orange) Text("用户信息加载失败") .font(.system(size: 16, weight: .medium)) .foregroundColor(.white) Text(error) .font(.system(size: 14)) .foregroundColor(.white.opacity(0.7)) .multilineTextAlignment(.center) .padding(.horizontal, 32) Button("重试") { store.send(.loadUserInfo) } .font(.system(size: 14, weight: .medium)) .foregroundColor(.white) .padding(.horizontal, 24) .padding(.vertical, 8) .background(Color.blue.opacity(0.8)) .cornerRadius(8) } .frame(maxWidth: .infinity, maxHeight: .infinity) } else if store.showErrorView { // 显示错误视图组件 EmptyStateView { store.send(.retryMoments) } .frame(maxWidth: .infinity, maxHeight: .infinity) } else if store.moments.isEmpty { VStack(spacing: 12) { Image(systemName: "doc.text") .font(.system(size: 32)) .foregroundColor(.white.opacity(0.5)) Text("暂无动态") .font(.system(size: 16, weight: .medium)) .foregroundColor(.white.opacity(0.7)) // 添加调试信息 Text("调试: moments.count = \(store.moments.count)") .font(.system(size: 12)) .foregroundColor(.yellow) Text("调试: isLoadingUserInfo = \(store.isLoadingUserInfo)") .font(.system(size: 12)) .foregroundColor(.yellow) Text("调试: isLoadingMoments = \(store.isLoadingMoments)") .font(.system(size: 12)) .foregroundColor(.yellow) Text("调试: userInfoError = \(store.userInfoError ?? "nil")") .font(.system(size: 12)) .foregroundColor(.yellow) Text("调试: momentsError = \(store.momentsError ?? "nil")") .font(.system(size: 12)) .foregroundColor(.yellow) Text("调试: showErrorView = \(store.showErrorView)") .font(.system(size: 12)) .foregroundColor(.yellow) } .frame(maxWidth: .infinity, maxHeight: .infinity) } else { ScrollView { WithPerceptionTracking { LazyVStack(spacing: 12) { ForEach(Array(store.moments.enumerated()), id: \.element.dynamicId) { index, moment in OptimizedDynamicCardView( moment: moment, allMoments: store.moments, currentIndex: index, onImageTap: { images, tappedIndex in previewCurrentIndex = tappedIndex previewItem = PreviewItem(images: images, index: tappedIndex) }, onLikeTap: { _, _, _, _ in // 暂时不处理点赞,后续可以添加点赞功能 }, onCardTap: { store.send(.showDetail(moment)) }, onAvatarTap: nil // MeView中不需要头像点击功能 ) .padding(.horizontal, 12) } if store.hasMore { ProgressView() .onAppear { store.send(.loadMore) } } // 新增底部间距 Color.clear.frame(height: 120) } .padding(.top, 8) } } .refreshable { store.send(.refresh) } } } } }