Files
e-party-iOS/yana/Features/FeedFeature.swift
edwinQQQ fb7ae9e0ad feat: 更新.gitignore,删除需求文档,优化API调试信息
- 在.gitignore中添加忽略项以排除不必要的文件。
- 删除架构分析需求文档以简化项目文档。
- 在APIEndpoints.swift和LoginModels.swift中移除调试信息的异步调用,提升代码简洁性。
- 在EMailLoginFeature.swift和HomeFeature.swift中新增登录流程状态管理,优化用户体验。
- 在多个视图中调整状态管理和导航逻辑,确保一致性和可维护性。
- 更新Xcode项目配置以增强调试信息的输出格式。
2025-07-18 15:57:54 +08:00

175 lines
6.7 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 isShowingCreateFeed = false
var createFeedState: CreateFeedFeature.State? = nil
}
enum Action {
case onAppear
case loadLatestMoments
case loadMoreMoments
case momentsResponse(TaskResult<MomentsLatestResponse>)
case clearError
case retryLoad
// CreateFeedView Action
case showCreateFeed
case dismissCreateFeed
case createFeedCompleted
indirect case createFeed(CreateFeedFeature.Action)
}
@Dependency(\.apiService) var apiService
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .onAppear:
#if DEBUG
return .none
#endif
//
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: 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
//
debugInfoSync("📱 FeedFeature: API 响应成功")
debugInfoSync("📱 FeedFeature: response.code = \(response.code)")
debugInfoSync("📱 FeedFeature: response.message = \(response.message)")
debugInfoSync("📱 FeedFeature: response.data = \(response.data != nil ? "有数据" : "无数据")")
//
guard response.code == 200, let data = response.data else {
let errorMsg = response.message.isEmpty ? "获取动态失败" : response.message
state.error = errorMsg
debugErrorSync("❌ FeedFeature: API 响应失败 - code: \(response.code), message: \(errorMsg)")
return .none
}
//
debugInfoSync("📱 FeedFeature: data.dynamicList.count = \(data.dynamicList.count)")
debugInfoSync("📱 FeedFeature: data.nextDynamicId = \(data.nextDynamicId)")
//
let isRefresh = state.nextDynamicId == 0
debugInfoSync("📱 FeedFeature: isRefresh = \(isRefresh)")
if isRefresh {
//
state.moments = data.dynamicList
debugInfoSync(" FeedFeature: 刷新数据moments.count = \(state.moments.count)")
} else {
//
let oldCount = state.moments.count
state.moments.append(contentsOf: data.dynamicList)
debugInfoSync(" FeedFeature: 加载更多moments.count: \(oldCount) -> \(state.moments.count)")
}
//
state.nextDynamicId = data.nextDynamicId
state.hasMoreData = !data.dynamicList.isEmpty
debugInfoSync("📱 FeedFeature: 更新完成 - nextDynamicId: \(state.nextDynamicId), hasMoreData: \(state.hasMoreData)")
return .none
case let .momentsResponse(.failure(error)):
state.isLoading = false
state.error = error.localizedDescription
debugErrorSync("❌ FeedFeature: API 请求失败 - \(error.localizedDescription)")
return .none
case .clearError:
state.error = nil
return .none
case .retryLoad:
//
if state.moments.isEmpty {
return .send(.loadLatestMoments)
} else {
return .send(.loadMoreMoments)
}
case .showCreateFeed:
state.isShowingCreateFeed = true
// createFeedState
state.createFeedState = CreateFeedFeature.State()
return .none
case .dismissCreateFeed:
state.isShowingCreateFeed = false
state.createFeedState = nil
return .none
case .createFeedCompleted:
state.isShowingCreateFeed = false
state.createFeedState = nil
//
return .send(.loadLatestMoments)
case .createFeed:
// Action reducer
return .none
}
}
// reducer
self.ifLet(\.createFeedState, action: \.createFeed) {
CreateFeedFeature()
}
}
}