
- 在FeedListFeature和MeFeature中新增isFirstLoad状态,确保仅在首次加载时请求数据。 - 更新MainView以简化视图切换逻辑,使用isHidden修饰符控制视图显示。 - 新增View+isHidden扩展,提供视图隐藏功能,提升代码可读性和复用性。
113 lines
4.1 KiB
Swift
113 lines
4.1 KiB
Swift
import Foundation
|
|
import ComposableArchitecture
|
|
|
|
@Reducer
|
|
struct MeFeature {
|
|
@Dependency(\.apiService) var apiService
|
|
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
|
|
}
|
|
|
|
enum Action: Equatable {
|
|
case onAppear
|
|
case refresh
|
|
case loadMore
|
|
case userInfoResponse(Result<UserInfo, APIError>)
|
|
case momentsResponse(Result<MyMomentsResponse, APIError>)
|
|
// 设置按钮点击
|
|
case settingButtonTapped
|
|
}
|
|
|
|
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.uid > 0 else { return .none }
|
|
state.isRefreshing = true
|
|
state.page = 1
|
|
state.hasMore = true
|
|
return .merge(
|
|
fetchUserInfo(uid: state.uid),
|
|
fetchMoments(uid: state.uid, page: 1, pageSize: state.pageSize)
|
|
)
|
|
case .loadMore:
|
|
guard state.uid > 0, state.hasMore, !state.isLoadingMore else { return .none }
|
|
state.isLoadingMore = true
|
|
return fetchMoments(uid: state.uid, 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
|
|
}
|
|
}
|
|
|
|
private func fetchUserInfo(uid: Int) -> Effect<Action> {
|
|
.run { send in
|
|
do {
|
|
if let userInfo = try await UserInfoManager.fetchUserInfoFromServer(uid: String(uid), apiService: apiService) {
|
|
await send(.userInfoResponse(.success(userInfo)))
|
|
} else {
|
|
await send(.userInfoResponse(.failure(.noData)))
|
|
}
|
|
} catch {
|
|
await send(.userInfoResponse(.failure(error as? APIError ?? .unknown(error.localizedDescription))))
|
|
}
|
|
}
|
|
}
|
|
|
|
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))))
|
|
}
|
|
}
|
|
}
|
|
} |