Files
e-party-iOS/yana/Features/FeedFeature.swift
edwinQQQ 9a49d591c3 feat: 添加腾讯云COS Token管理功能及相关视图更新
- 在APIEndpoints.swift中新增tcToken端点以支持腾讯云COS Token获取。
- 在APIModels.swift中新增TcTokenRequest和TcTokenResponse模型,处理Token请求和响应。
- 在COSManager.swift中实现Token的获取、缓存和过期管理逻辑,提升API请求的安全性。
- 在LanguageSettingsView中添加调试功能,允许测试COS Token获取。
- 在多个视图中更新状态管理和导航逻辑,确保用户体验一致性。
- 在FeedFeature和HomeFeature中优化状态管理,简化视图逻辑。
2025-07-18 20:50:25 +08:00

154 lines
5.2 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
// CreateFeedView -
var isCreateFeedPresented = false
}
enum Action {
case onAppear
case loadLatestMoments
case loadMoreMoments
case momentsResponse(TaskResult<MomentsLatestResponse>)
case clearError
case retryLoad
// CreateFeedView Action -
case showCreateFeed
case createFeedCompleted
case createFeedDismissed
}
@Dependency(\.apiService) var apiService
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .onAppear:
//
guard !state.isInitialized else {
return .none
}
return .send(.loadLatestMoments)
case .loadLatestMoments:
//
guard !state.isLoading else {
return .none
}
//
state.isLoading = true
state.error = nil
let request = LatestDynamicsRequest(
dynamicId: "", //
pageSize: 20,
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
//
if !state.isInitialized {
state.isInitialized = true
}
//
guard response.code == 200, let data = response.data else {
let errorMsg = response.message.isEmpty ? "获取动态失败" : response.message
state.error = errorMsg
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)
}
// CreateFeedView Action -
case .showCreateFeed:
state.isCreateFeedPresented = true
return .none
case .createFeedCompleted:
//
state.isCreateFeedPresented = false
return .send(.loadLatestMoments)
case .createFeedDismissed:
state.isCreateFeedPresented = false
return .none
}
}
}
}