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

@@ -36,7 +36,6 @@ struct DetailFeature {
case showImagePreview([String], Int)
case hideImagePreview
case imagePreviewDismissed
case onLikeSuccess(Int, Bool) // dynamicId, newLikeState
case dismissView
// IDactions
@@ -45,7 +44,9 @@ struct DetailFeature {
}
var body: some ReducerOf<Self> {
Reduce { state, action in
Reduce {
state,
action in
switch action {
case .onAppear:
// ID
@@ -69,9 +70,10 @@ struct DetailFeature {
return .none
case let .likeDynamic(dynamicId, uid, likedUid, worldId):
// loading
state.isLikeLoading = true
let status = state.moment.isLike ? 0 : 1
let status = state.moment.isLike ? 0 : 1 // 0: , 1:
let request = LikeDynamicRequest(
dynamicId: dynamicId,
uid: uid,
@@ -80,59 +82,71 @@ struct DetailFeature {
worldId: worldId
)
return .run { send in
let result = await TaskResult {
try await apiService.request(request)
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)))
}
await send(.likeResponse(result))
}
case let .likeResponse(.success(response)):
state.isLikeLoading = false
//
return .send(.onLikeSuccess(state.moment.dynamicId, !state.moment.isLike))
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)
}
case let .onLikeSuccess(dynamicId, newLikeState):
//
// MomentsInfoisLikeletmoment
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: 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
return .none
case let .likeResponse(.failure(error)):
// loading
state.isLikeLoading = false
//
// APILoadingManager
setAPILoadingErrorSync(UUID(), errorMessage: error.localizedDescription)
return .none
case .deleteDynamic:
@@ -179,4 +193,4 @@ struct DetailFeature {
}
}
}
}
}