import Foundation import ComposableArchitecture @Reducer struct MeDynamicFeature: Reducer { struct State: Equatable { var uid: Int var dynamics: [MomentsInfo] = [] var page: Int = 1 var pageSize: Int = 20 var isLoading: Bool = false var isRefreshing: Bool = false var isLoadingMore: Bool = false var hasMore: Bool = true var error: String? var isInitialized: Bool = false // 首次加载标记 init(uid: Int = 0) { self.uid = uid } } enum Action: Equatable { case onAppear case refresh case loadMore case fetchResponse(Result) } @Dependency(\.apiService) var apiService func reduce(into state: inout State, action: Action) async -> Effect { switch action { case .onAppear: guard !state.isInitialized else { return .none } state.isInitialized = true state.page = 1 state.dynamics = [] state.hasMore = true state.isLoading = true state.error = nil return fetchDynamics(uid: state.uid, page: 1, pageSize: state.pageSize) case .refresh: state.page = 1 state.hasMore = true state.isRefreshing = true state.error = nil state.isInitialized = false // 允许刷新后重新加载 return fetchDynamics( uid: state.uid, page: 1, pageSize: state.pageSize ) case .loadMore: guard !state.isLoadingMore, state.hasMore else { return .none } state.isLoadingMore = true return fetchDynamics(uid: state.uid, page: state.page + 1, pageSize: state.pageSize) case let .fetchResponse(result): state.isLoading = false state.isRefreshing = false state.isLoadingMore = false switch result { case let .success(resp): let newDynamics = resp.data ?? [] if state.page == 1 { state.dynamics = newDynamics } else { state.dynamics += newDynamics } state.hasMore = newDynamics.count == state.pageSize if state.hasMore { state.page += 1 } state.error = nil case let .failure(error): state.error = error.localizedDescription } return .none } } private func fetchDynamics(uid: Int, page: Int, pageSize: Int) -> Effect { let apiService = self.apiService return .run { send in do { let req = GetMyDynamicRequest(fromUid: uid, uid: uid, page: page, pageSize: pageSize) let resp = try await apiService.request(req) await send(.fetchResponse(.success(resp))) } catch { await send(.fetchResponse(.failure(error as? APIError ?? .unknown(error.localizedDescription)))) } } } }