176 lines
6.5 KiB
Swift
176 lines
6.5 KiB
Swift
import SwiftUI
|
||
|
||
struct ProfileTab: View {
|
||
@ObservedObject var viewModel: LoginViewModel
|
||
@State private var isContentLoaded = true
|
||
|
||
@State private var accounts = ["@user1", "@user2", "@user3"]
|
||
@State private var selectedAccount = "@user1"
|
||
|
||
let followers = ["@alice", "@bob", "@charlie"]
|
||
let following = ["@dev", "@design", "@ios"]
|
||
|
||
@State private var sheetType: SheetType? = nil
|
||
enum SheetType: Identifiable {
|
||
case accountShare
|
||
var id: Int { self.hashValue }
|
||
}
|
||
|
||
@State private var allPosts: [Post] = []
|
||
@State private var isLoading = true
|
||
@State private var isRefreshing = false
|
||
|
||
@State private var selectedPostData: (Post, [Post])?
|
||
|
||
@State private var isShowingFollowers = false
|
||
@State private var isShowingFollowing = false
|
||
|
||
var body: some View {
|
||
NavigationView {
|
||
if !isContentLoaded {
|
||
SplashScreenView()
|
||
} else {
|
||
VStack(spacing: 0) {
|
||
// Скрытые NavigationLink для программного перехода
|
||
NavigationLink(destination: FollowersView(followers: followers), isActive: $isShowingFollowers) { EmptyView() }
|
||
NavigationLink(destination: FollowingView(following: following), isActive: $isShowingFollowing) { EmptyView() }
|
||
|
||
if let (post, posts) = selectedPostData {
|
||
NavigationLink(
|
||
destination: PostFeedView(posts: posts, selectedPostID: post.id),
|
||
isActive: Binding(
|
||
get: { selectedPostData != nil },
|
||
set: { if !$0 { selectedPostData = nil } }
|
||
),
|
||
label: { EmptyView() }
|
||
)
|
||
}
|
||
|
||
RefreshableScrollView(isRefreshing: $isRefreshing, onRefresh: {
|
||
fetchData()
|
||
}) {
|
||
VStack(spacing: 12) {
|
||
header
|
||
// .frame(minHeight: 300)
|
||
.frame(maxWidth: .infinity)
|
||
.background(Color(.systemBackground))
|
||
|
||
ProfileContentTabbedGrid(
|
||
isContentLoaded: isContentLoaded,
|
||
allPosts: $allPosts,
|
||
isLoading: $isLoading,
|
||
onPostTapped: { post, posts in
|
||
self.selectedPostData = (post, posts)
|
||
}
|
||
)
|
||
}
|
||
}
|
||
}
|
||
.navigationBarTitleDisplayMode(.inline)
|
||
.toolbar {
|
||
ToolbarItem(placement: .principal) {
|
||
Button(action: { sheetType = .accountShare }) {
|
||
HStack(spacing: 4) {
|
||
Text(selectedAccount)
|
||
.font(.headline)
|
||
.foregroundColor(.primary)
|
||
Image(systemName: "chevron.down")
|
||
.font(.subheadline)
|
||
.foregroundColor(.gray)
|
||
}
|
||
}
|
||
}
|
||
ToolbarItem(placement: .navigationBarTrailing) {
|
||
NavigationLink(destination: SettingsView(viewModel: viewModel)) {
|
||
Image(systemName: "wrench")
|
||
.imageScale(.large)
|
||
}
|
||
}
|
||
}
|
||
.sheet(item: $sheetType) { type in
|
||
switch type {
|
||
case .accountShare:
|
||
AccountShareSheet(
|
||
isPresented: Binding(
|
||
get: { sheetType != nil },
|
||
set: { if !$0 { sheetType = nil } }
|
||
),
|
||
selectedAccount: $selectedAccount,
|
||
accounts: accounts
|
||
)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.navigationViewStyle(StackNavigationViewStyle())
|
||
.onAppear {
|
||
if allPosts.isEmpty {
|
||
fetchData(isInitialLoad: true)
|
||
}
|
||
}
|
||
}
|
||
|
||
private func fetchData(isInitialLoad: Bool = false) {
|
||
if isInitialLoad {
|
||
isLoading = true
|
||
} else {
|
||
isRefreshing = true
|
||
}
|
||
|
||
PostService.shared.fetchAllPosts { fetchedPosts in
|
||
self.allPosts = fetchedPosts
|
||
|
||
if isInitialLoad {
|
||
self.isLoading = false
|
||
}
|
||
self.isRefreshing = false
|
||
}
|
||
}
|
||
|
||
// MARK: - Шапка профиля
|
||
private var header: some View {
|
||
VStack(spacing: 12) {
|
||
// Аватар и имя
|
||
VStack(spacing: 6) {
|
||
Image(systemName: "person.crop.circle.fill")
|
||
.resizable()
|
||
.frame(width: 72, height: 72)
|
||
.foregroundColor(.gray)
|
||
|
||
Text("custom_user_name")
|
||
.font(.headline)
|
||
}
|
||
.padding(.top, 16)
|
||
|
||
Text("iOS разработчик, делаю интерфейсы, иногда снимаю блоги и делюсь кодом. Всегда рад новым подписчикам и интересным проектам.")
|
||
.font(.subheadline)
|
||
.foregroundColor(.secondary)
|
||
.multilineTextAlignment(.center)
|
||
.padding(.horizontal)
|
||
|
||
// Статистика
|
||
HStack(spacing: 32) {
|
||
statView("24", "Посты")
|
||
Button(action: { isShowingFollowers = true }) {
|
||
statView("1.2k", "Подписчики")
|
||
}
|
||
Button(action: { isShowingFollowing = true }) {
|
||
statView("156", "Подписки")
|
||
}
|
||
}
|
||
}
|
||
.padding(.horizontal)
|
||
}
|
||
|
||
// MARK: - Статистика
|
||
func statView(_ value: String, _ label: String) -> some View {
|
||
VStack {
|
||
Text(value)
|
||
.font(.headline)
|
||
Text(label)
|
||
.font(.caption)
|
||
}
|
||
.foregroundColor(.primary)
|
||
}
|
||
}
|