Compare commits

...

2 Commits

Author SHA1 Message Date
40a5f4c628 edit login screen 2025-10-23 21:05:18 +03:00
d692c7c984 add messenger mod 2025-10-23 20:50:44 +03:00
5 changed files with 140 additions and 58 deletions

View File

@ -3,6 +3,7 @@ import SwiftUI
struct TopBarView: View { struct TopBarView: View {
var title: String var title: String
let isMessengerModeEnabled: Bool
// Состояния для ProfileTab // Состояния для ProfileTab
@Binding var selectedAccount: String @Binding var selectedAccount: String
// @Binding var sheetType: ProfileTab.SheetType? // @Binding var sheetType: ProfileTab.SheetType?
@ -41,17 +42,19 @@ struct TopBarView: View {
var body: some View { var body: some View {
VStack(spacing: 0) { VStack(spacing: 0) {
HStack { HStack {
// Кнопка "Гамбургер" для открытия меню
Button(action: {
withAnimation {
isSideMenuPresented.toggle()
}
}) {
Image(systemName: "line.horizontal.3")
.imageScale(.large)
.foregroundColor(.primary)
}
if !isMessengerModeEnabled{
// Кнопка "Гамбургер" для открытия меню
Button(action: {
withAnimation {
isSideMenuPresented.toggle()
}
}) {
Image(systemName: "line.horizontal.3")
.imageScale(.large)
.foregroundColor(.primary)
}
}
// Spacer() // Spacer()
if let statusMessage { if let statusMessage {
@ -221,13 +224,14 @@ struct TopBarView_Previews: PreviewProvider {
var body: some View { var body: some View {
TopBarView( TopBarView(
title: "Chats", title: "Chats",
isMessengerModeEnabled: false,
selectedAccount: $selectedAccount, selectedAccount: $selectedAccount,
accounts: [selectedAccount], accounts: [selectedAccount],
viewModel: viewModel, viewModel: viewModel,
isSettingsPresented: $isSettingsPresented, isSettingsPresented: $isSettingsPresented,
isSideMenuPresented: $isSideMenuPresented, isSideMenuPresented: $isSideMenuPresented,
chatSearchRevealProgress: $revealProgress, chatSearchRevealProgress: $revealProgress,
chatSearchText: $searchText chatSearchText: $searchText,
) )
} }
} }

View File

@ -12,6 +12,7 @@ struct LoginView: View {
@EnvironmentObject private var themeManager: ThemeManager @EnvironmentObject private var themeManager: ThemeManager
@Environment(\.colorScheme) private var colorScheme @Environment(\.colorScheme) private var colorScheme
private let themeOptions = ThemeOption.ordered private let themeOptions = ThemeOption.ordered
@AppStorage("messengerModeEnabled") private var isMessengerModeEnabled: Bool = false
@State private var isShowingRegistration = false @State private var isShowingRegistration = false
@State private var showLegacySupportNotice = false @State private var showLegacySupportNotice = false
@ -34,7 +35,8 @@ struct LoginView: View {
} }
private var isLoginButtonEnabled: Bool { private var isLoginButtonEnabled: Bool {
!viewModel.isLoading && isUsernameValid && isPasswordValid && viewModel.hasAcceptedTerms // !viewModel.isLoading && isUsernameValid && isPasswordValid && viewModel.hasAcceptedTerms
!viewModel.isLoading && isUsernameValid && isPasswordValid
} }
var body: some View { var body: some View {
@ -113,14 +115,17 @@ struct LoginView: View {
.font(.caption) .font(.caption)
} }
TermsAgreementCard( // TermsAgreementCard(
isAccepted: $viewModel.hasAcceptedTerms, // isAccepted: $viewModel.hasAcceptedTerms,
openTerms: { // openTerms: {
viewModel.loadTermsIfNeeded() // viewModel.loadTermsIfNeeded()
isShowingTerms = true // isShowingTerms = true
} // }
) // )
.padding(.vertical, 12) // .padding(.vertical, 12)
Toggle(NSLocalizedString("Режим мессенжера", comment: ""), isOn: $isMessengerModeEnabled)
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Button(action: { Button(action: {
viewModel.login() viewModel.login()

View File

@ -0,0 +1,24 @@
//
// ContactsTab.swift
// yobble
//
// Created by cheykrym on 23.10.2025.
//
import SwiftUI
struct ContactsTab: View {
var body: some View {
VStack {
VStack {
Text("Здесь не будут чаты")
.font(.title)
.foregroundColor(.gray)
Spacer()
}
}
// .background(Color(.secondarySystemBackground)) // Фон для всей вкладки
}
}

View File

@ -2,33 +2,44 @@ import SwiftUI
struct CustomTabBar: View { struct CustomTabBar: View {
@Binding var selectedTab: Int @Binding var selectedTab: Int
let isMessengerModeEnabled: Bool
var onCreate: () -> Void var onCreate: () -> Void
var body: some View { var body: some View {
HStack { HStack {
// Tab 1: Feed if isMessengerModeEnabled {
TabBarButton(systemName: "list.bullet.rectangle", text: NSLocalizedString("Лента", comment: ""), isSelected: selectedTab == 0) {
selectedTab = 0
}
// Tab 2: Search TabBarButton(systemName: "person.2.fill", text: NSLocalizedString("Контакты", comment: ""), isSelected: selectedTab == 4) {
TabBarButton(systemName: "gamecontroller.fill", text: NSLocalizedString("Концепт", comment: "Tab bar: concept clicker"), isSelected: selectedTab == 1) { selectedTab = 4
selectedTab = 1 }
}
// Create Button TabBarButton(systemName: "bubble.left.and.bubble.right.fill", text: NSLocalizedString("Чаты", comment: ""), isSelected: selectedTab == 2) {
CreateButton { selectedTab = 2
onCreate() }
}
// Tab 3: Chats TabBarButton(systemName: "gearshape.fill", text: NSLocalizedString("Настройки", comment: ""), isSelected: selectedTab == 5) {
TabBarButton(systemName: "bubble.left.and.bubble.right.fill", text: NSLocalizedString("Чаты", comment: ""), isSelected: selectedTab == 2) { selectedTab = 5
selectedTab = 2 }
} } else {
TabBarButton(systemName: "list.bullet.rectangle", text: NSLocalizedString("Лента", comment: ""), isSelected: selectedTab == 0) {
selectedTab = 0
}
// Tab 4: Profile TabBarButton(systemName: "gamecontroller.fill", text: NSLocalizedString("Концепт", comment: "Tab bar: concept clicker"), isSelected: selectedTab == 1) {
TabBarButton(systemName: "person.crop.square", text: NSLocalizedString("Лицо", comment: ""), isSelected: selectedTab == 3) { selectedTab = 1
selectedTab = 3 }
CreateButton {
onCreate()
}
TabBarButton(systemName: "bubble.left.and.bubble.right.fill", text: NSLocalizedString("Чаты", comment: ""), isSelected: selectedTab == 2) {
selectedTab = 2
}
TabBarButton(systemName: "person.crop.square", text: NSLocalizedString("Лицо", comment: ""), isSelected: selectedTab == 3) {
selectedTab = 3
}
} }
} }
.padding(.horizontal) .padding(.horizontal)

View File

@ -4,6 +4,7 @@ struct MainView: View {
@ObservedObject var viewModel: LoginViewModel @ObservedObject var viewModel: LoginViewModel
@EnvironmentObject private var messageCenter: IncomingMessageCenter @EnvironmentObject private var messageCenter: IncomingMessageCenter
@State private var selectedTab: Int = 0 @State private var selectedTab: Int = 0
@AppStorage("messengerModeEnabled") private var isMessengerModeEnabled: Bool = false
// @StateObject private var newHomeTabViewModel = NewHomeTabViewModel() // @StateObject private var newHomeTabViewModel = NewHomeTabViewModel()
// Состояния для TopBarView // Состояния для TopBarView
@ -26,6 +27,8 @@ struct MainView: View {
case 1: return "Concept" case 1: return "Concept"
case 2: return "Chats" case 2: return "Chats"
case 3: return "Profile" case 3: return "Profile"
case 4: return "Contacts"
case 5: return "Settings"
default: return "Home" default: return "Home"
} }
} }
@ -42,6 +45,7 @@ struct MainView: View {
VStack(spacing: 0) { VStack(spacing: 0) {
TopBarView( TopBarView(
title: tabTitle, title: tabTitle,
isMessengerModeEnabled: isMessengerModeEnabled,
selectedAccount: $selectedAccount, selectedAccount: $selectedAccount,
accounts: accounts, accounts: accounts,
viewModel: viewModel, viewModel: viewModel,
@ -52,26 +56,42 @@ struct MainView: View {
) )
ZStack { ZStack {
NewHomeTab() if isMessengerModeEnabled {
.opacity(selectedTab == 0 ? 1 : 0) ChatsTab(
loginViewModel: viewModel,
ConceptTab() searchRevealProgress: $chatSearchRevealProgress,
.opacity(selectedTab == 1 ? 1 : 0) searchText: $chatSearchText
)
ChatsTab(
loginViewModel: viewModel,
searchRevealProgress: $chatSearchRevealProgress,
searchText: $chatSearchText
)
.opacity(selectedTab == 2 ? 1 : 0) .opacity(selectedTab == 2 ? 1 : 0)
.allowsHitTesting(selectedTab == 2) .allowsHitTesting(selectedTab == 2)
ProfileTab() ContactsTab()
.opacity(selectedTab == 3 ? 1 : 0) .opacity(selectedTab == 4 ? 1 : 0)
SettingsView(viewModel: viewModel)
.opacity(selectedTab == 5 ? 1 : 0)
} else {
NewHomeTab()
.opacity(selectedTab == 0 ? 1 : 0)
ConceptTab()
.opacity(selectedTab == 1 ? 1 : 0)
ChatsTab(
loginViewModel: viewModel,
searchRevealProgress: $chatSearchRevealProgress,
searchText: $chatSearchText
)
.opacity(selectedTab == 2 ? 1 : 0)
.allowsHitTesting(selectedTab == 2)
ProfileTab()
.opacity(selectedTab == 3 ? 1 : 0)
}
} }
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
CustomTabBar(selectedTab: $selectedTab) { CustomTabBar(selectedTab: $selectedTab, isMessengerModeEnabled: isMessengerModeEnabled) {
print("Create button tapped") print("Create button tapped")
} }
} }
@ -94,10 +114,12 @@ struct MainView: View {
.allowsHitTesting(menuOffset > 0) .allowsHitTesting(menuOffset > 0)
// Боковое меню // Боковое меню
SideMenuView(viewModel: viewModel, isPresented: $isSideMenuPresented) if !isMessengerModeEnabled {
.frame(width: menuWidth) SideMenuView(viewModel: viewModel, isPresented: $isSideMenuPresented)
.offset(x: -menuWidth + menuOffset) // Новая логика смещения .frame(width: menuWidth)
.ignoresSafeArea(edges: .vertical) .offset(x: -menuWidth + menuOffset) // Новая логика смещения
.ignoresSafeArea(edges: .vertical)
}
} }
deepLinkNavigationLink deepLinkNavigationLink
@ -142,6 +164,12 @@ struct MainView: View {
menuOffset = presented ? menuWidth : 0 menuOffset = presented ? menuWidth : 0
} }
} }
.onAppear {
enforceTabSelectionForMessengerMode()
}
.onChange(of: isMessengerModeEnabled) { _ in
enforceTabSelectionForMessengerMode()
}
.onChange(of: messageCenter.pendingNavigation?.id) { _ in .onChange(of: messageCenter.pendingNavigation?.id) { _ in
guard !AppConfig.PRESENT_CHAT_AS_SHEET, guard !AppConfig.PRESENT_CHAT_AS_SHEET,
let target = messageCenter.pendingNavigation else { return } let target = messageCenter.pendingNavigation else { return }
@ -173,6 +201,16 @@ struct MainView: View {
} }
private extension MainView { private extension MainView {
func enforceTabSelectionForMessengerMode() {
if isMessengerModeEnabled {
if selectedTab < 2 {
selectedTab = 2
}
} else if selectedTab > 3 {
selectedTab = 0
}
}
var deepLinkNavigationLink: some View { var deepLinkNavigationLink: some View {
NavigationLink( NavigationLink(
destination: deepLinkChatDestination, destination: deepLinkChatDestination,