104 lines
2.8 KiB
Swift
104 lines
2.8 KiB
Swift
|
|
import SwiftUI
|
||
|
|
|
||
|
|
@main
|
||
|
|
struct MontanaApp: App {
|
||
|
|
@StateObject private var appState = AppState()
|
||
|
|
|
||
|
|
var body: some Scene {
|
||
|
|
WindowGroup {
|
||
|
|
ContentView()
|
||
|
|
.environmentObject(appState)
|
||
|
|
.preferredColorScheme(.dark)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// MARK: - App State
|
||
|
|
class AppState: ObservableObject {
|
||
|
|
@Published var isLoggedIn: Bool = false
|
||
|
|
@Published var user: User?
|
||
|
|
@Published var balance: Int = 0
|
||
|
|
@Published var presenceSeconds: Int = 0
|
||
|
|
@Published var contacts: [Contact] = []
|
||
|
|
|
||
|
|
var deviceId: String? {
|
||
|
|
UserDefaults.standard.string(forKey: "deviceId")
|
||
|
|
}
|
||
|
|
|
||
|
|
var userPhone: String? {
|
||
|
|
user?.phone
|
||
|
|
}
|
||
|
|
|
||
|
|
private var presenceTimer: Timer?
|
||
|
|
|
||
|
|
init() {
|
||
|
|
// Check existing login
|
||
|
|
if let deviceId = UserDefaults.standard.string(forKey: "deviceId") {
|
||
|
|
loadUser(deviceId: deviceId)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func startPresence() {
|
||
|
|
presenceTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
|
||
|
|
self?.presenceSeconds += 1
|
||
|
|
|
||
|
|
// Sync every 60 seconds
|
||
|
|
if self?.presenceSeconds ?? 0 % 60 == 0 {
|
||
|
|
self?.syncPresence()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func stopPresence() {
|
||
|
|
presenceTimer?.invalidate()
|
||
|
|
syncPresence()
|
||
|
|
}
|
||
|
|
|
||
|
|
private func syncPresence() {
|
||
|
|
guard let deviceId = UserDefaults.standard.string(forKey: "deviceId") else { return }
|
||
|
|
let seconds = presenceSeconds % 60
|
||
|
|
if seconds > 0 {
|
||
|
|
API.shared.syncPresence(deviceId: deviceId, seconds: seconds)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func loadUser(deviceId: String) {
|
||
|
|
API.shared.getUser(deviceId: deviceId) { [weak self] result in
|
||
|
|
DispatchQueue.main.async {
|
||
|
|
switch result {
|
||
|
|
case .success(let user):
|
||
|
|
self?.user = user
|
||
|
|
self?.balance = user.balance
|
||
|
|
self?.isLoggedIn = true
|
||
|
|
self?.startPresence()
|
||
|
|
self?.loadContacts()
|
||
|
|
case .failure:
|
||
|
|
UserDefaults.standard.removeObject(forKey: "deviceId")
|
||
|
|
self?.isLoggedIn = false
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func loadContacts() {
|
||
|
|
guard let deviceId = UserDefaults.standard.string(forKey: "deviceId") else { return }
|
||
|
|
API.shared.getContacts(deviceId: deviceId) { [weak self] result in
|
||
|
|
DispatchQueue.main.async {
|
||
|
|
if case .success(let contacts) = result {
|
||
|
|
self?.contacts = contacts
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func logout() {
|
||
|
|
stopPresence()
|
||
|
|
UserDefaults.standard.removeObject(forKey: "deviceId")
|
||
|
|
isLoggedIn = false
|
||
|
|
user = nil
|
||
|
|
balance = 0
|
||
|
|
presenceSeconds = 0
|
||
|
|
contacts = []
|
||
|
|
}
|
||
|
|
}
|