feat: 更新Podfile和Podfile.lock,添加最新动态API文档和相关功能
- 在Podfile中添加Alamofire依赖,并更新Podfile.lock以反映更改。 - 新增动态内容API文档,详细描述`dynamic/square/latestDynamics`接口的请求参数、响应数据结构及示例。 - 实现动态内容的模型和API请求结构,支持获取最新动态列表。 - 更新FeedView和HomeView以集成动态内容展示,增强用户体验。 - 添加动态卡片组件,展示用户动态信息及互动功能。
This commit is contained in:
119
yana/Features/FeedFeature.swift
Normal file
119
yana/Features/FeedFeature.swift
Normal file
@@ -0,0 +1,119 @@
|
||||
import Foundation
|
||||
import ComposableArchitecture
|
||||
|
||||
@Reducer
|
||||
struct FeedFeature {
|
||||
@ObservableState
|
||||
struct State: Equatable {
|
||||
var moments: [MomentsInfo] = []
|
||||
var isLoading = false
|
||||
var hasMoreData = true
|
||||
var error: String?
|
||||
var nextDynamicId: Int = 0
|
||||
|
||||
// 是否已初始化
|
||||
var isInitialized = false
|
||||
}
|
||||
|
||||
enum Action: Equatable {
|
||||
case onAppear
|
||||
case loadLatestMoments
|
||||
case loadMoreMoments
|
||||
case momentsResponse(TaskResult<MomentsLatestResponse>)
|
||||
case clearError
|
||||
case retryLoad
|
||||
}
|
||||
|
||||
@Dependency(\.apiService) var apiService
|
||||
|
||||
var body: some ReducerOf<Self> {
|
||||
Reduce { state, action in
|
||||
switch action {
|
||||
case .onAppear:
|
||||
// 只在首次出现时触发加载
|
||||
guard !state.isInitialized else { return .none }
|
||||
state.isInitialized = true
|
||||
return .send(.loadLatestMoments)
|
||||
|
||||
case .loadLatestMoments:
|
||||
// 加载最新数据(下拉刷新)
|
||||
state.isLoading = true
|
||||
state.error = nil
|
||||
|
||||
let request = LatestDynamicsRequest(
|
||||
dynamicId: "", // 首次加载传空字符串
|
||||
pageSize: 2,
|
||||
types: [.text, .picture]
|
||||
)
|
||||
|
||||
return .run { send in
|
||||
await send(.momentsResponse(TaskResult {
|
||||
try await apiService.request(request)
|
||||
}))
|
||||
}
|
||||
|
||||
case .loadMoreMoments:
|
||||
// 加载更多数据(分页加载)
|
||||
guard !state.isLoading && state.hasMoreData else { return .none }
|
||||
|
||||
state.isLoading = true
|
||||
state.error = nil
|
||||
|
||||
let request = LatestDynamicsRequest(
|
||||
dynamicId: state.nextDynamicId == 0 ? "" : String(state.nextDynamicId),
|
||||
pageSize: 20,
|
||||
types: [.text, .picture]
|
||||
)
|
||||
|
||||
return .run { send in
|
||||
await send(.momentsResponse(TaskResult {
|
||||
try await apiService.request(request)
|
||||
}))
|
||||
}
|
||||
|
||||
case let .momentsResponse(.success(response)):
|
||||
state.isLoading = false
|
||||
|
||||
// 检查响应状态
|
||||
guard response.code == 200, let data = response.data else {
|
||||
state.error = response.message.isEmpty ? "获取动态失败" : response.message
|
||||
return .none
|
||||
}
|
||||
|
||||
// 判断是刷新还是加载更多
|
||||
let isRefresh = state.nextDynamicId == 0
|
||||
|
||||
if isRefresh {
|
||||
// 刷新:替换所有数据
|
||||
state.moments = data.dynamicList
|
||||
} else {
|
||||
// 加载更多:追加到现有数据
|
||||
state.moments.append(contentsOf: data.dynamicList)
|
||||
}
|
||||
|
||||
// 更新分页状态
|
||||
state.nextDynamicId = data.nextDynamicId
|
||||
state.hasMoreData = !data.dynamicList.isEmpty
|
||||
|
||||
return .none
|
||||
|
||||
case let .momentsResponse(.failure(error)):
|
||||
state.isLoading = false
|
||||
state.error = error.localizedDescription
|
||||
return .none
|
||||
|
||||
case .clearError:
|
||||
state.error = nil
|
||||
return .none
|
||||
|
||||
case .retryLoad:
|
||||
// 重试加载
|
||||
if state.moments.isEmpty {
|
||||
return .send(.loadLatestMoments)
|
||||
} else {
|
||||
return .send(.loadMoreMoments)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user