Files
e-party-iOS/yana/Features/MainFeature.swift
edwinQQQ fb09ddb956 feat: 增强应用功能与用户体验
- 在Package.swift中更新依赖路径,确保项目结构清晰。
- 在AppSettingFeature中新增初始化方法,支持用户信息、头像和昵称的设置。
- 更新FeedListFeature和MainFeature,新增测试按钮和导航功能,提升用户交互体验。
- 在MeFeature中优化用户信息加载逻辑,增强错误处理能力。
- 新增TestView以支持测试功能,验证导航跳转的有效性。
- 更新多个视图以整合新功能,提升代码可读性与维护性。
2025-07-25 14:10:56 +08:00

122 lines
4.5 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
debugInfoSync("MainFeature action: \(action)")
debugInfoSync("MainFeature state: \(state)")
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)
debugInfoSync("\(state.navigationPath)")
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(.updateUser(.success)):
// Me
return .send(.me(.refresh))
case .appSettingAction:
return .none
case .logout:
// SplashView/SplashFeature
return .none
}
}
//
.ifLet(\ .appSettingState, action: \ .appSettingAction) {
AppSettingFeature()
}
}
}