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