feat: Implement chat list and search functionality

- Added ChatListViewModel to manage chat list state and server search.
- Created ChatRowView for displaying individual chat rows.
- Developed SearchView and SearchViewModel for user search functionality.
- Introduced MainTabView for tab-based navigation between chats and settings.
- Implemented OnboardingPager for onboarding experience.
- Created SettingsView and SettingsViewModel for user settings management.
- Added SplashView for initial app launch experience.
This commit is contained in:
2026-02-25 21:27:41 +05:00
parent 7fb57fffba
commit 99a35302fa
54 changed files with 5818 additions and 213 deletions

View File

@@ -0,0 +1,79 @@
import SwiftUI
/// UIPageViewController wrapper that handles paging entirely in UIKit.
/// SwiftUI state is only updated after a page fully settles zero overhead during swipe.
struct OnboardingPager<Page: View>: UIViewControllerRepresentable {
@Binding var currentIndex: Int
let count: Int
let buildPage: (Int) -> Page
func makeCoordinator() -> Coordinator { Coordinator(self) }
func makeUIViewController(context: Context) -> UIPageViewController {
let vc = UIPageViewController(
transitionStyle: .scroll,
navigationOrientation: .horizontal
)
vc.view.backgroundColor = .clear
vc.dataSource = context.coordinator
vc.delegate = context.coordinator
vc.setViewControllers(
[context.coordinator.controllers[currentIndex]],
direction: .forward,
animated: false
)
// Make the inner scroll view transparent
for sub in vc.view.subviews {
(sub as? UIScrollView)?.backgroundColor = .clear
}
return vc
}
func updateUIViewController(_ vc: UIPageViewController, context: Context) {
context.coordinator.parent = self
}
// MARK: - Coordinator
final class Coordinator: NSObject, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var parent: OnboardingPager
let controllers: [UIHostingController<Page>]
init(_ parent: OnboardingPager) {
self.parent = parent
// Create hosting controllers without triggering view loading
self.controllers = (0..<parent.count).map { i in
UIHostingController(rootView: parent.buildPage(i))
}
}
func pageViewController(
_ pvc: UIPageViewController,
viewControllerBefore vc: UIViewController
) -> UIViewController? {
guard let idx = controllers.firstIndex(where: { $0 === vc }), idx > 0 else { return nil }
return controllers[idx - 1]
}
func pageViewController(
_ pvc: UIPageViewController,
viewControllerAfter vc: UIViewController
) -> UIViewController? {
guard let idx = controllers.firstIndex(where: { $0 === vc }),
idx < parent.count - 1 else { return nil }
return controllers[idx + 1]
}
func pageViewController(
_ pvc: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers: [UIViewController],
transitionCompleted completed: Bool
) {
guard completed,
let current = pvc.viewControllers?.first,
let idx = controllers.firstIndex(where: { $0 === current }) else { return }
parent.currentIndex = idx
}
}
}