Files
e-party-iOS/yana/Features/MainFeature.swift
edwinQQQ 79fc03b52a feat: 优化视图组件与数据迁移逻辑
- 移除DataMigrationManager类,简化数据迁移逻辑。
- 在FeedListView和MeView中新增图片预览功能,提升用户体验。
- 更新OptimizedDynamicCardView以支持图片点击回调,增强交互性。
- 新增PreviewItem结构体以管理图片预览状态,提升代码可读性与维护性。
- 清理AppDelegate中的冗余代码,优化启动流程。
2025-07-25 16:22:38 +08:00

125 lines
4.6 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
import CasePaths
@Reducer
struct MainFeature {
enum Tab: Int, Equatable, CaseIterable {
case feed, other
}
@ObservableState
struct State: Equatable {
var selectedTab: Tab = .feed
var feedList: FeedListFeature.State = .init()
var me: MeFeature.State = .init()
var accountModel: AccountModel? = nil
// State
var navigationPath: [Destination] = []
var appSettingState: AppSettingFeature.State? = nil
//
var isLoggedOut: Bool = false
}
//
enum Destination: Hashable, Codable, CaseIterable {
case appSetting
case testView
}
@CasePathable
enum Action: Equatable {
case onAppear
case selectTab(Tab)
case feedList(FeedListFeature.Action)
case me(MeFeature.Action)
case accountModelLoaded(AccountModel?)
//
case navigationPathChanged([Destination])
case appSettingButtonTapped
case appSettingAction(AppSettingFeature.Action)
//
case logout
}
var body: some ReducerOf<Self> {
Scope(state: \ .feedList, action: \ .feedList) {
FeedListFeature()
}
Scope(state: \ .me, action: \ .me) {
MeFeature()
}
Reduce { state, action in
switch action {
case .onAppear:
return .run { send in
let accountModel = await UserInfoManager.getAccountModel()
await send(.accountModelLoaded(accountModel))
}
case .selectTab(let tab):
state.selectedTab = tab
state.navigationPath = []
if tab == .other, let uidStr = state.accountModel?.uid, let uid = Int(uidStr), uid > 0 {
if state.me.uid != uid {
state.me.uid = uid
state.me.isFirstLoad = true //
}
return .send(.me(.onAppear))
}
return .none
case .feedList(.testButtonTapped):
state.navigationPath.append(.testView)
return .none
case .feedList:
return .none
case let .accountModelLoaded(accountModel):
state.accountModel = accountModel
return .none
case .me(.settingButtonTapped):
// push
let userInfo = state.me.userInfo
let avatarURL = userInfo?.avatar
let nickname = userInfo?.nick ?? ""
state.appSettingState = AppSettingFeature.State(nickname: nickname, avatarURL: avatarURL, userInfo: userInfo)
state.navigationPath.append(.appSetting)
return .none
case .me:
return .none
case .navigationPathChanged(let newPath):
// pop settingState
state.navigationPath = newPath
return .none
case .appSettingButtonTapped:
let userInfo = state.me.userInfo
let avatarURL = userInfo?.avatar
let nickname = userInfo?.nick ?? ""
state.appSettingState = AppSettingFeature.State(nickname: nickname, avatarURL: avatarURL, userInfo: userInfo)
state.navigationPath.append(.appSetting)
return .none
case .appSettingAction(.logoutTapped):
//
state.isLoggedOut = true
return .none
case .appSettingAction(.dismissTapped):
// pop
if !state.navigationPath.isEmpty {
state.navigationPath.removeLast()
}
return .none
case .appSettingAction(.updateUser(.success)):
// Me
return .send(.me(.refresh))
case .appSettingAction:
return .none
case .logout:
// SplashView/SplashFeature
return .none
}
}
//
.ifLet(\ .appSettingState, action: \ .appSettingAction) {
AppSettingFeature()
}
}
}