add to top bar connect
This commit is contained in:
parent
4a2636879d
commit
7c1d46ab77
@ -27,6 +27,10 @@ struct TopBarView: View {
|
||||
return title == "Profile"
|
||||
}
|
||||
|
||||
private var shouldShowConnectionStatus: Bool {
|
||||
viewModel.socketState != .connected
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 0) {
|
||||
HStack {
|
||||
@ -43,7 +47,10 @@ struct TopBarView: View {
|
||||
|
||||
// Spacer()
|
||||
|
||||
if isHomeTab{
|
||||
if shouldShowConnectionStatus {
|
||||
connectionStatusView
|
||||
Spacer()
|
||||
} else if isHomeTab{
|
||||
Text("Yobble")
|
||||
.font(.largeTitle)
|
||||
.fontWeight(.bold)
|
||||
@ -129,6 +136,16 @@ struct TopBarView: View {
|
||||
}
|
||||
|
||||
private extension TopBarView {
|
||||
var connectionStatusView: some View {
|
||||
HStack(spacing: 8) {
|
||||
ProgressView()
|
||||
.progressViewStyle(.circular)
|
||||
Text(NSLocalizedString("Подключение", comment: ""))
|
||||
.font(.headline)
|
||||
.foregroundColor(.primary)
|
||||
}
|
||||
}
|
||||
|
||||
private var normalizedRevealProgress: CGFloat {
|
||||
guard isChatsTab else { return 0 }
|
||||
return max(0, min(chatSearchRevealProgress, 1))
|
||||
|
||||
@ -1473,6 +1473,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Подключение" : {
|
||||
|
||||
},
|
||||
"Подтверждение пароля" : {
|
||||
"comment" : "Подтверждение пароля",
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import Foundation
|
||||
import Combine
|
||||
#if canImport(SocketIO)
|
||||
import SocketIO
|
||||
#endif
|
||||
@ -6,10 +7,28 @@ import SocketIO
|
||||
final class SocketService {
|
||||
static let shared = SocketService()
|
||||
|
||||
enum ConnectionState: Equatable {
|
||||
case disconnected
|
||||
case connecting
|
||||
case connected
|
||||
}
|
||||
|
||||
private let syncQueue = DispatchQueue(label: "org.yobble.socket.service")
|
||||
private var currentToken: String?
|
||||
private var currentAuthPayload: [String: Any] = [:]
|
||||
|
||||
private let connectionStateSubject = CurrentValueSubject<ConnectionState, Never>(.disconnected)
|
||||
|
||||
var connectionStatePublisher: AnyPublisher<ConnectionState, Never> {
|
||||
connectionStateSubject
|
||||
.removeDuplicates()
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
var currentConnectionState: ConnectionState {
|
||||
connectionStateSubject.value
|
||||
}
|
||||
|
||||
#if canImport(SocketIO)
|
||||
private var manager: SocketManager?
|
||||
private var socket: SocketIOClient?
|
||||
@ -17,6 +36,19 @@ final class SocketService {
|
||||
|
||||
private init() {}
|
||||
|
||||
private func updateConnectionState(_ state: ConnectionState) {
|
||||
let sendState: () -> Void = { [weak self] in
|
||||
guard let self, self.connectionStateSubject.value != state else { return }
|
||||
self.connectionStateSubject.send(state)
|
||||
}
|
||||
|
||||
if Thread.isMainThread {
|
||||
sendState()
|
||||
} else {
|
||||
DispatchQueue.main.async(execute: sendState)
|
||||
}
|
||||
}
|
||||
|
||||
func connectForCurrentUser() {
|
||||
syncQueue.async { [weak self] in
|
||||
guard let self else { return }
|
||||
@ -68,8 +100,10 @@ final class SocketService {
|
||||
currentToken = token
|
||||
currentAuthPayload = ["token": token]
|
||||
setupSocket(with: token)
|
||||
updateConnectionState(.connecting)
|
||||
socket?.connect(withPayload: currentAuthPayload)
|
||||
#else
|
||||
updateConnectionState(.disconnected)
|
||||
if AppConfig.DEBUG {
|
||||
print("[SocketService] SocketIO framework not available; skipping connection")
|
||||
}
|
||||
@ -112,14 +146,17 @@ final class SocketService {
|
||||
|
||||
socket.on(clientEvent: .connect) { _, _ in
|
||||
if AppConfig.DEBUG { print("[SocketService] Connected") }
|
||||
self.updateConnectionState(.connected)
|
||||
}
|
||||
|
||||
socket.on(clientEvent: .disconnect) { data, _ in
|
||||
if AppConfig.DEBUG { print("[SocketService] Disconnected: \(data)") }
|
||||
self.updateConnectionState(.disconnected)
|
||||
}
|
||||
|
||||
socket.on(clientEvent: .error) { data, _ in
|
||||
if AppConfig.DEBUG { print("[SocketService] Error: \(data)") }
|
||||
self.updateConnectionState(.disconnected)
|
||||
}
|
||||
|
||||
self.manager = manager
|
||||
@ -131,6 +168,7 @@ final class SocketService {
|
||||
manager?.disconnect()
|
||||
socket = nil
|
||||
manager = nil
|
||||
updateConnectionState(.disconnected)
|
||||
}
|
||||
#else
|
||||
private func disconnectInternal() { }
|
||||
|
||||
@ -16,9 +16,11 @@ class LoginViewModel: ObservableObject {
|
||||
@Published var showError: Bool = false
|
||||
@Published var errorMessage: String = ""
|
||||
@Published var isLoggedIn: Bool = false
|
||||
@Published var socketState: SocketService.ConnectionState
|
||||
|
||||
private let authService = AuthService()
|
||||
private let socketService = SocketService.shared
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private enum DefaultsKeys {
|
||||
static let currentUser = "currentUser"
|
||||
@ -26,12 +28,23 @@ class LoginViewModel: ObservableObject {
|
||||
}
|
||||
|
||||
init() {
|
||||
socketState = socketService.currentConnectionState
|
||||
observeSocketState()
|
||||
// loadStoredUser()
|
||||
|
||||
// Запускаем автологин
|
||||
autoLogin()
|
||||
}
|
||||
|
||||
private func observeSocketState() {
|
||||
socketService.connectionStatePublisher
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] state in
|
||||
self?.socketState = state
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func autoLogin() {
|
||||
authService.autoLogin { [weak self] success, error in
|
||||
DispatchQueue.main.async {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user