Files
e-party-iOS/yana/Features/DetailFeature.swift
edwinQQQ fa544139c1 feat: 实现DetailView头像点击功能并优化MeView
- 在DetailView中添加头像点击功能,支持展示非当前用户的主页。
- 更新OptimizedDynamicCardView以支持头像点击回调。
- 修改DetailFeature以管理用户主页显示状态。
- 在MeView中添加关闭按钮支持,优化用户体验。
- 确保其他页面的兼容性,未影响现有功能。
2025-08-01 16:12:24 +08:00

214 lines
8.5 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Foundation
import ComposableArchitecture
@Reducer
struct DetailFeature {
@Dependency(\.apiService) var apiService
@Dependency(\.isPresented) var isPresented
@ObservableState
struct State: Equatable {
var moment: MomentsInfo
var isLikeLoading = false
var isDeleteLoading = false
var showImagePreview = false
var selectedImageIndex = 0
var selectedImages: [String] = []
// ID
var currentUserId: String?
var isLoadingCurrentUserId = false
// DetailView
var shouldDismiss = false
//
var showUserProfile = false
var targetUserId: Int = 0
init(moment: MomentsInfo) {
self.moment = moment
}
}
enum Action: Equatable {
case onAppear
case likeDynamic(Int, Int, Int, Int) // dynamicId, uid, likedUid, worldId
case likeResponse(TaskResult<LikeDynamicResponse>)
case deleteDynamic
case deleteResponse(TaskResult<DeleteDynamicResponse>)
case showImagePreview([String], Int)
case hideImagePreview
case imagePreviewDismissed
case dismissView
// IDactions
case loadCurrentUserId
case currentUserIdLoaded(String?)
// actions
case showUserProfile(Int)
case hideUserProfile
}
var body: some ReducerOf<Self> {
Reduce {
state,
action in
switch action {
case .onAppear:
// ID
if state.currentUserId == nil && !state.isLoadingCurrentUserId {
return .send(.loadCurrentUserId)
}
return .none
case .loadCurrentUserId:
state.isLoadingCurrentUserId = true
return .run { send in
let userId = await UserInfoManager.getCurrentUserId()
debugInfoSync("🔍 DetailFeature: 获取当前用户ID - \(userId ?? "nil")")
await send(.currentUserIdLoaded(userId))
}
case let .currentUserIdLoaded(userId):
state.currentUserId = userId
state.isLoadingCurrentUserId = false
debugInfoSync("✅ DetailFeature: 当前用户ID已加载 - \(userId ?? "nil")")
return .none
case let .likeDynamic(dynamicId, uid, likedUid, worldId):
// loading
state.isLikeLoading = true
let status = state.moment.isLike ? 0 : 1 // 0: , 1:
let request = LikeDynamicRequest(
dynamicId: dynamicId,
uid: uid,
status: status,
likedUid: likedUid,
worldId: worldId
)
return .run { [apiService] send in
do {
let response: LikeDynamicResponse = try await apiService.request(request)
await send(.likeResponse(.success(response)))
} catch {
await send(.likeResponse(.failure(error)))
}
}
case let .likeResponse(.success(response)):
if let data = response.data, let success = data.success, success {
// API
let newLikeState = !state.moment.isLike //
//
let updatedMoment = MomentsInfo(
dynamicId: state.moment.dynamicId,
uid: state.moment.uid,
nick: state.moment.nick,
avatar: state.moment.avatar,
type: state.moment.type,
content: state.moment.content,
likeCount: data.likeCount ?? state.moment.likeCount,
isLike: newLikeState,
commentCount: state.moment.commentCount,
publishTime: state.moment.publishTime,
worldId: state.moment.worldId,
status: state.moment.status,
playCount: state.moment.playCount,
dynamicResList: state.moment.dynamicResList,
gender: state.moment.gender,
squareTop: state.moment.squareTop,
topicTop: state.moment.topicTop,
newUser: state.moment.newUser,
defUser: state.moment.defUser,
scene: state.moment.scene,
userVipInfoVO: state.moment.userVipInfoVO,
headwearPic: state.moment.headwearPic,
headwearEffect: state.moment.headwearEffect,
headwearType: state.moment.headwearType,
headwearName: state.moment.headwearName,
headwearId: state.moment.headwearId,
experLevelPic: state.moment.experLevelPic,
charmLevelPic: state.moment.charmLevelPic,
isCustomWord: state.moment.isCustomWord,
labelList: state.moment.labelList
)
state.moment = updatedMoment
// loading
state.isLikeLoading = false
} else {
// APIAPILoadingManager
let errorMessage = response.message.isEmpty ? "点赞失败,请重试" : response.message
setAPILoadingErrorSync(UUID(), errorMessage: errorMessage)
}
// loading
state.isLikeLoading = false
return .none
case let .likeResponse(.failure(error)):
// loading
state.isLikeLoading = false
// APILoadingManager
setAPILoadingErrorSync(UUID(), errorMessage: error.localizedDescription)
return .none
case .deleteDynamic:
state.isDeleteLoading = true
let request = DeleteDynamicRequest(dynamicId: state.moment.dynamicId, uid: state.moment.uid)
return .run { send in
let result = await TaskResult {
try await apiService.request(request)
}
await send(.deleteResponse(result))
}
case let .deleteResponse(.success(response)):
state.isDeleteLoading = false
debugInfoSync("✅ DetailFeature: 动态删除成功")
//
return .send(.dismissView)
case let .deleteResponse(.failure(error)):
state.isDeleteLoading = false
//
return .none
case let .showImagePreview(images, index):
state.selectedImages = images
state.selectedImageIndex = index
state.showImagePreview = true
return .none
case .hideImagePreview:
state.showImagePreview = false
return .none
case .imagePreviewDismissed:
state.showImagePreview = false
return .none
case .dismissView:
debugInfoSync("🔍 DetailFeature: 请求关闭DetailView")
state.shouldDismiss = true
return .none
case let .showUserProfile(userId):
state.targetUserId = userId
state.showUserProfile = true
return .none
case .hideUserProfile:
state.showUserProfile = false
return .none
}
}
}
}