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 init() { // 默认初始化 } } // 新增:导航目标 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 { 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(.createFeedPublishSuccess): // CreateFeed发布成功,刷新FeedList和Me页数据 return .merge( .send(.feedList(.reload)), .send(.me(.refresh)) ) case .feedList: return .none case let .accountModelLoaded(accountModel): state.accountModel = accountModel // 如果当前选中的是 MeView 标签页,且有有效的 uid,则触发数据加载 if state.selectedTab == .other, let uidStr = 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 .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(.logoutConfirmed): // 监听到确认登出,设置登出标志 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() } } }