Files
e-party-iOS/yana/Views/MainView.swift
edwinQQQ fa544139c1 feat: 实现DetailView头像点击功能并优化MeView
- 在DetailView中添加头像点击功能,支持展示非当前用户的主页。
- 更新OptimizedDynamicCardView以支持头像点击回调。
- 修改DetailFeature以管理用户主页显示状态。
- 在MeView中添加关闭按钮支持,优化用户体验。
- 确保其他页面的兼容性,未影响现有功能。
2025-08-01 16:12:24 +08:00

136 lines
4.5 KiB
Swift

import SwiftUI
import ComposableArchitecture
struct MainView: View {
let store: StoreOf<MainFeature>
var onLogout: (() -> Void)? = nil
var body: some View {
WithPerceptionTracking {
InternalMainView(store: store)
.onChange(of: store.isLoggedOut) { _, isLoggedOut in
if isLoggedOut {
onLogout?()
}
}
}
}
}
struct InternalMainView: View {
let store: StoreOf<MainFeature>
@State private var path: [MainFeature.Destination] = []
init(store: StoreOf<MainFeature>) {
self.store = store
_path = State(initialValue: store.withState { $0.navigationPath })
}
var body: some View {
WithPerceptionTracking {
NavigationStack(path: $path) {
GeometryReader { geometry in
contentView(geometry: geometry)
.navigationDestination(for: MainFeature.Destination.self) { destination in
DestinationView(destination: destination, store: self.store)
}
.onChange(of: path) { _, path in
store.send(.navigationPathChanged(path))
}
.onChange(of: store.navigationPath) { _, navigationPath in
if path != navigationPath {
path = navigationPath
}
}
.onAppear {
store.send(.onAppear)
}
}
}
}
}
struct DestinationView: View {
let destination: MainFeature.Destination
let store: StoreOf<MainFeature>
var body: some View {
switch destination {
case .appSetting:
IfLetStore(
store.scope(state: \.appSettingState, action: \.appSettingAction),
then: { store in
WithPerceptionTracking {
AppSettingView(store: store)
}
},
else: { Text("appSettingState is nil") }
)
case .testView:
TestView()
}
}
}
private func contentView(geometry: GeometryProxy) -> some View {
WithPerceptionTracking {
ZStack {
//
Image("bg")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.clipped()
.ignoresSafeArea(.all)
//
MainContentView(
store: store,
selectedTab: store.selectedTab
)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(.bottom, 80) //
// -
VStack {
Spacer()
BottomTabView(selectedTab: Binding(
get: { Tab(rawValue: store.selectedTab.rawValue) ?? .feed },
set: { newTab in
store.send(.selectTab(MainFeature.Tab(rawValue: newTab.rawValue) ?? .feed))
}
))
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
.padding(.bottom, 100)
.ignoresSafeArea(.keyboard, edges: .bottom)
// API Loading
APILoadingEffectView()
}
}
}
}
struct MainContentView: View {
let store: StoreOf<MainFeature>
let selectedTab: MainFeature.Tab
var body: some View {
Group {
if selectedTab == .feed {
FeedListView(store: store.scope(
state: \.feedList,
action: \.feedList
))
} else if selectedTab == .other {
MeView(
store: store.scope(
state: \.me,
action: \.me
),
showCloseButton: false // MainView
)
} else {
EmptyView()
}
}
}
}