ios_app/Shared/Views/Tab/ProfileTab.swift
2025-07-24 22:49:42 +03:00

176 lines
6.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 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)
}
}