
- 在DetailView中添加头像点击功能,支持展示非当前用户的主页。 - 更新OptimizedDynamicCardView以支持头像点击回调。 - 修改DetailFeature以管理用户主页显示状态。 - 在MeView中添加关闭按钮支持,优化用户体验。 - 确保其他页面的兼容性,未影响现有功能。
141 lines
4.9 KiB
Swift
141 lines
4.9 KiB
Swift
import Foundation
|
||
import ComposableArchitecture
|
||
|
||
@Reducer
|
||
struct MeFeature {
|
||
@Dependency(\.apiService) var apiService
|
||
@ObservableState
|
||
struct State: Equatable {
|
||
var isFirstLoad: Bool = true
|
||
var userInfo: UserInfo?
|
||
var isLoadingUserInfo: Bool = false
|
||
var userInfoError: String?
|
||
var moments: [MomentsInfo] = []
|
||
var isLoadingMoments: Bool = false
|
||
var momentsError: String?
|
||
var hasMore: Bool = true
|
||
var isLoadingMore: Bool = false
|
||
var isRefreshing: Bool = false
|
||
var page: Int = 1
|
||
var pageSize: Int = 20
|
||
var uid: Int = 0
|
||
// 新增:显示指定用户ID,如果为nil则显示当前登录用户
|
||
var displayUID: Int?
|
||
// 新增:DetailView相关状态
|
||
var showDetail: Bool = false
|
||
var selectedMoment: MomentsInfo?
|
||
|
||
init(displayUID: Int? = nil) {
|
||
self.displayUID = displayUID
|
||
}
|
||
|
||
// 获取实际要显示的用户ID
|
||
var effectiveUID: Int {
|
||
return displayUID ?? uid
|
||
}
|
||
|
||
// 判断是否显示其他用户
|
||
var isDisplayingOtherUser: Bool {
|
||
return displayUID != nil && displayUID != uid
|
||
}
|
||
}
|
||
|
||
enum Action: Equatable {
|
||
case onAppear
|
||
case refresh
|
||
case loadMore
|
||
case userInfoResponse(Result<UserInfo, APIError>)
|
||
case momentsResponse(Result<MyMomentsResponse, APIError>)
|
||
// 设置按钮点击
|
||
case settingButtonTapped
|
||
// 新增:DetailView相关Action
|
||
case showDetail(MomentsInfo)
|
||
case detailDismissed
|
||
}
|
||
|
||
func reduce(into state: inout State, action: Action) -> Effect<Action> {
|
||
switch action {
|
||
case .onAppear:
|
||
guard state.isFirstLoad else { return .none }
|
||
state.isFirstLoad = false
|
||
return .send(.refresh)
|
||
case .refresh:
|
||
guard state.effectiveUID > 0 else { return .none }
|
||
state.isRefreshing = true
|
||
state.page = 1
|
||
state.hasMore = true
|
||
return .merge(
|
||
fetchUserInfo(uid: state.effectiveUID),
|
||
fetchMoments(uid: state.effectiveUID, page: 1, pageSize: state.pageSize)
|
||
)
|
||
case .loadMore:
|
||
guard state.effectiveUID > 0, state.hasMore, !state.isLoadingMore else { return .none }
|
||
state.isLoadingMore = true
|
||
return fetchMoments(uid: state.effectiveUID, page: state.page + 1, pageSize: state.pageSize)
|
||
case let .userInfoResponse(result):
|
||
state.isLoadingUserInfo = false
|
||
state.isRefreshing = false
|
||
switch result {
|
||
case let .success(userInfo):
|
||
state.userInfo = userInfo
|
||
state.userInfoError = nil
|
||
case let .failure(error):
|
||
state.userInfoError = error.localizedDescription
|
||
}
|
||
return .none
|
||
case let .momentsResponse(result):
|
||
state.isLoadingMoments = false
|
||
state.isLoadingMore = false
|
||
state.isRefreshing = false
|
||
switch result {
|
||
case let .success(resp):
|
||
let newMoments = resp.data ?? []
|
||
if state.page == 1 {
|
||
state.moments = newMoments
|
||
} else {
|
||
state.moments += newMoments
|
||
}
|
||
state.hasMore = newMoments.count == state.pageSize
|
||
if state.hasMore { state.page += 1 }
|
||
state.momentsError = nil
|
||
case let .failure(error):
|
||
state.momentsError = error.localizedDescription
|
||
}
|
||
return .none
|
||
case .settingButtonTapped:
|
||
// 交由 MainFeature 处理
|
||
return .none
|
||
case .showDetail(let moment):
|
||
state.selectedMoment = moment
|
||
state.showDetail = true
|
||
return .none
|
||
case .detailDismissed:
|
||
state.showDetail = false
|
||
state.selectedMoment = nil
|
||
return .none
|
||
}
|
||
}
|
||
|
||
private func fetchUserInfo(uid: Int) -> Effect<Action> {
|
||
.run { send in
|
||
if let userInfo = await UserInfoManager.fetchUserInfoFromServer(uid: String(uid), apiService: apiService) {
|
||
await send(.userInfoResponse(.success(userInfo)))
|
||
} else {
|
||
await send(.userInfoResponse(.failure(.noData)))
|
||
}
|
||
}
|
||
}
|
||
|
||
private func fetchMoments(uid: Int, page: Int, pageSize: Int) -> Effect<Action> {
|
||
.run { send in
|
||
do {
|
||
let req = GetMyDynamicRequest(fromUid: uid, uid: uid, page: page, pageSize: pageSize)
|
||
let resp = try await apiService.request(req)
|
||
await send(.momentsResponse(.success(resp)))
|
||
} catch {
|
||
await send(.momentsResponse(.failure(error as? APIError ?? .unknown(error.localizedDescription))))
|
||
}
|
||
}
|
||
}
|
||
}
|