feat: 更新动态点赞与加载状态管理以提升用户体验

- 在DetailFeature和FeedListFeature中增强点赞功能的状态管理,确保用户交互流畅。
- 新增API加载效果视图,提升用户在操作过程中的反馈体验。
- 更新视图组件以支持点赞加载状态,优化用户界面交互。
- 改进错误处理逻辑,确保在API请求失败时提供友好的错误提示。
This commit is contained in:
edwinQQQ
2025-07-28 16:05:22 +08:00
parent e286229f6f
commit d35071d3de
13 changed files with 389 additions and 332 deletions

View File

@@ -41,7 +41,7 @@ struct FeedListFeature {
case detailDismissed
// Action
case likeDynamic(Int, Int, Int, Int) // dynamicId, uid, likedUid, worldId
case likeResponse(TaskResult<LikeDynamicResponse>)
case likeResponse(TaskResult<LikeDynamicResponse>, dynamicId: Int)
// Action
}
@@ -149,15 +149,17 @@ struct FeedListFeature {
state.selectedMoment = nil
return .none
case let .likeDynamic(dynamicId, uid, likedUid, worldId):
//
guard let index = state.moments.firstIndex(where: { $0.dynamicId == dynamicId }) else {
return .none
}
// loading
state.likeLoadingDynamicIds.insert(dynamicId)
//
//
guard let index = state.moments.firstIndex(where: { $0.dynamicId == dynamicId }) else {
//
setAPILoadingErrorSync(UUID(), errorMessage: "找不到对应的动态")
state.likeLoadingDynamicIds.remove(dynamicId)
return .none
}
let currentMoment = state.moments[index]
let status = currentMoment.isLike ? 0 : 1 // 0: , 1:
@@ -170,71 +172,74 @@ struct FeedListFeature {
)
return .run { [apiService] send in
let result = await TaskResult {
try await apiService.request(request)
do {
let response: LikeDynamicResponse = try await apiService.request(request)
await send(.likeResponse(.success(response), dynamicId: dynamicId))
} catch {
await send(.likeResponse(.failure(error), dynamicId: dynamicId))
}
await send(.likeResponse(result))
}
case let .likeResponse(.success(response)):
// loading
case let .likeResponse(.success(response), dynamicId):
if let data = response.data, let success = data.success, success {
//
// loadingdynamicId
let loadingDynamicIds = state.likeLoadingDynamicIds
for dynamicId in loadingDynamicIds {
if let index = state.moments.firstIndex(where: { $0.dynamicId == dynamicId }) {
let currentMoment = state.moments[index]
let newLikeState = !currentMoment.isLike
let newLikeCount = data.likeCount ?? currentMoment.likeCount
//
let updatedMoment = MomentsInfo(
dynamicId: currentMoment.dynamicId,
uid: currentMoment.uid,
nick: currentMoment.nick,
avatar: currentMoment.avatar,
type: currentMoment.type,
content: currentMoment.content,
likeCount: newLikeCount,
isLike: newLikeState,
commentCount: currentMoment.commentCount,
publishTime: currentMoment.publishTime,
worldId: currentMoment.worldId,
status: currentMoment.status,
playCount: currentMoment.playCount,
dynamicResList: currentMoment.dynamicResList,
gender: currentMoment.gender,
squareTop: currentMoment.squareTop,
topicTop: currentMoment.topicTop,
newUser: currentMoment.newUser,
defUser: currentMoment.defUser,
scene: currentMoment.scene,
userVipInfoVO: currentMoment.userVipInfoVO,
headwearPic: currentMoment.headwearPic,
headwearEffect: currentMoment.headwearEffect,
headwearType: currentMoment.headwearType,
headwearName: currentMoment.headwearName,
headwearId: currentMoment.headwearId,
experLevelPic: currentMoment.experLevelPic,
charmLevelPic: currentMoment.charmLevelPic,
isCustomWord: currentMoment.isCustomWord,
labelList: currentMoment.labelList
)
state.moments[index] = updatedMoment
break // 退
}
// API
if let index = state.moments.firstIndex(where: { $0.dynamicId == dynamicId }) {
//
let currentMoment = state.moments[index]
let newLikeState = !currentMoment.isLike //
//
let updatedMoment = MomentsInfo(
dynamicId: currentMoment.dynamicId,
uid: currentMoment.uid,
nick: currentMoment.nick,
avatar: currentMoment.avatar,
type: currentMoment.type,
content: currentMoment.content,
likeCount: data.likeCount ?? currentMoment.likeCount,
isLike: newLikeState,
commentCount: currentMoment.commentCount,
publishTime: currentMoment.publishTime,
worldId: currentMoment.worldId,
status: currentMoment.status,
playCount: currentMoment.playCount,
dynamicResList: currentMoment.dynamicResList,
gender: currentMoment.gender,
squareTop: currentMoment.squareTop,
topicTop: currentMoment.topicTop,
newUser: currentMoment.newUser,
defUser: currentMoment.defUser,
scene: currentMoment.scene,
userVipInfoVO: currentMoment.userVipInfoVO,
headwearPic: currentMoment.headwearPic,
headwearEffect: currentMoment.headwearEffect,
headwearType: currentMoment.headwearType,
headwearName: currentMoment.headwearName,
headwearId: currentMoment.headwearId,
experLevelPic: currentMoment.experLevelPic,
charmLevelPic: currentMoment.charmLevelPic,
isCustomWord: currentMoment.isCustomWord,
labelList: currentMoment.labelList
)
state.moments[index] = updatedMoment
}
// loading
state.likeLoadingDynamicIds.removeAll()
} else {
// APIAPILoadingManager
let errorMessage = response.message.isEmpty ? "点赞失败,请重试" : response.message
setAPILoadingErrorSync(UUID(), errorMessage: errorMessage)
}
// loading
state.likeLoadingDynamicIds.removeAll()
return .none
case let .likeResponse(.failure(error)):
case let .likeResponse(.failure(error), dynamicId):
// loading
state.likeLoadingDynamicIds.removeAll()
// APILoadingManager
setAPILoadingErrorSync(UUID(), errorMessage: error.localizedDescription)
return .none
}
}