173 lines
5.8 KiB
Swift
173 lines
5.8 KiB
Swift
//
|
||
// LoginViewModel.swift
|
||
// VolnahubApp
|
||
//
|
||
// Created by cheykrym on 09/06/2025.
|
||
//
|
||
|
||
import Foundation
|
||
import Combine
|
||
|
||
class LoginViewModel: ObservableObject {
|
||
@Published var username: String = ""
|
||
@Published var userId: String = ""
|
||
@Published var password: String = ""
|
||
@Published var isLoading: Bool = true // сразу true, чтобы показать спиннер при автологине
|
||
@Published var showError: Bool = false
|
||
@Published var errorMessage: String = ""
|
||
@Published var isLoggedIn: Bool = false
|
||
@Published var socketState: SocketService.ConnectionState
|
||
@Published var chatLoadingState: ChatLoadingState = .idle
|
||
|
||
private let authService = AuthService()
|
||
private let socketService = SocketService.shared
|
||
private var cancellables = Set<AnyCancellable>()
|
||
|
||
enum ChatLoadingState: Equatable {
|
||
case idle
|
||
case loading
|
||
}
|
||
|
||
private enum DefaultsKeys {
|
||
static let currentUser = "currentUser"
|
||
static let userId = "userId"
|
||
}
|
||
|
||
init() {
|
||
socketState = socketService.currentConnectionState
|
||
observeSocketState()
|
||
observeChatsReload()
|
||
// loadStoredUser()
|
||
|
||
// Запускаем автологин
|
||
autoLogin()
|
||
}
|
||
|
||
private func observeSocketState() {
|
||
socketService.connectionStatePublisher
|
||
.receive(on: DispatchQueue.main)
|
||
.sink { [weak self] state in
|
||
self?.handleSocketStateChange(state)
|
||
}
|
||
.store(in: &cancellables)
|
||
}
|
||
|
||
private func observeChatsReload() {
|
||
NotificationCenter.default.publisher(for: .chatsReloadCompleted)
|
||
.receive(on: DispatchQueue.main)
|
||
.sink { [weak self] _ in
|
||
self?.chatLoadingState = .idle
|
||
}
|
||
.store(in: &cancellables)
|
||
}
|
||
|
||
private func handleSocketStateChange(_ state: SocketService.ConnectionState) {
|
||
socketState = state
|
||
if state == .connected {
|
||
triggerChatsReloadIfNeeded()
|
||
} else {
|
||
chatLoadingState = .idle
|
||
}
|
||
}
|
||
|
||
private func triggerChatsReloadIfNeeded() {
|
||
guard chatLoadingState != .loading else { return }
|
||
chatLoadingState = .loading
|
||
NotificationCenter.default.post(name: .chatsShouldRefresh, object: nil)
|
||
}
|
||
|
||
func autoLogin() {
|
||
authService.autoLogin { [weak self] success, error in
|
||
DispatchQueue.main.async {
|
||
// self?.isLoading = false
|
||
if success {
|
||
self?.loadStoredUser()
|
||
self?.isLoggedIn = true
|
||
self?.socketService.connectForCurrentUser()
|
||
} else {
|
||
self?.isLoggedIn = false
|
||
self?.errorMessage = error ?? NSLocalizedString("Произошла ошибка.", comment: "")
|
||
self?.showError = false
|
||
self?.socketService.disconnect()
|
||
}
|
||
self?.isLoading = false
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
func login() {
|
||
isLoading = true
|
||
showError = false
|
||
|
||
authService.login(username: username, password: password) { [weak self] success, error in
|
||
DispatchQueue.main.async {
|
||
self?.isLoading = false
|
||
if success {
|
||
self?.loadStoredUser()
|
||
self?.isLoggedIn = true
|
||
self?.socketService.connectForCurrentUser()
|
||
} else {
|
||
self?.errorMessage = error ?? NSLocalizedString("Неизвестная ошибка", comment: "")
|
||
self?.showError = true
|
||
self?.socketService.disconnect()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func registerUser(username: String, password: String, invite: String?, completion: @escaping (Bool, String?) -> Void) {
|
||
authService.register(username: username, password: password, invite: invite) { [weak self] success, message in
|
||
DispatchQueue.main.async {
|
||
if success {
|
||
self?.isLoggedIn = true // 👈 переключаем на главный экран после автологина
|
||
self?.loadStoredUser()
|
||
self?.socketService.connectForCurrentUser()
|
||
} else {
|
||
self?.socketService.disconnect()
|
||
}
|
||
completion(success, message)
|
||
}
|
||
}
|
||
}
|
||
|
||
func logoutCurrentUser() {
|
||
authService.logoutCurrentUser { [weak self] success, error in
|
||
DispatchQueue.main.async {
|
||
if success {
|
||
self?.loadStoredUser()
|
||
self?.password = ""
|
||
self?.isLoggedIn = true
|
||
self?.showError = false
|
||
self?.socketService.connectForCurrentUser()
|
||
} else {
|
||
self?.username = ""
|
||
self?.userId = ""
|
||
self?.password = ""
|
||
self?.isLoggedIn = false
|
||
self?.errorMessage = error ?? NSLocalizedString("Ошибка при деавторизации.", comment: "")
|
||
self?.showError = false
|
||
self?.socketService.disconnect()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// func logout() {
|
||
// username = ""
|
||
// password = ""
|
||
// isLoggedIn = false
|
||
// showError = false
|
||
// errorMessage = ""
|
||
// }
|
||
|
||
private func loadStoredUser() {
|
||
let defaults = UserDefaults.standard
|
||
username = defaults.string(forKey: DefaultsKeys.currentUser) ?? ""
|
||
userId = KeychainService.shared.get(forKey: DefaultsKeys.userId, service: username) ?? ""
|
||
|
||
if AppConfig.DEBUG{ print("username: \(username) | userId: \(userId)")}
|
||
}
|
||
}
|