1eb21c71ce
- Swift 6, SwiftUI, MVVM + async/await architecture - iOS 17.0 minimum deployment target - Two targets: Mayday app + MaydayLiveActivity widget extension - Models: UserResponse, TokenPair, AppNotification, SessionResponse, AlertAttributes - Services: HTTPClient (actor), AuthService, KeychainService, NotificationsAPIService, PushNotificationService - ViewModels: AuthViewModel, NotificationsViewModel, SettingsViewModel - Views: Login/Register/VerifyEmail, NotificationsList/Detail, Settings/ChangePassword/Sessions - APNs push notifications with UIApplicationDelegate - ActivityKit Live Activities for Dynamic Island + Lock Screen - Keychain (Security framework) token storage - 30-second polling with pagination for notifications - Xcode project file (project.pbxproj) with correct build phases for both targets Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
46 lines
1.3 KiB
Swift
46 lines
1.3 KiB
Swift
import Foundation
|
|
import SwiftUI
|
|
|
|
@MainActor
|
|
class SettingsViewModel: ObservableObject {
|
|
@Published var sessions: [SessionResponse] = []
|
|
@Published var isLoading = false
|
|
@Published var error: String?
|
|
@Published var successMessage: String?
|
|
|
|
private let service = NotificationsAPIService.shared
|
|
|
|
func loadSessions() async {
|
|
isLoading = true
|
|
defer { isLoading = false }
|
|
do {
|
|
sessions = try await service.getSessions()
|
|
} catch {
|
|
self.error = error.localizedDescription
|
|
}
|
|
}
|
|
|
|
func deleteSession(_ session: SessionResponse) async {
|
|
do {
|
|
try await service.deleteSession(id: session.id)
|
|
sessions.removeAll { $0.id == session.id }
|
|
} catch {
|
|
self.error = error.localizedDescription
|
|
}
|
|
}
|
|
|
|
func changePassword(current: String, new: String) async -> Bool {
|
|
isLoading = true
|
|
error = nil
|
|
defer { isLoading = false }
|
|
do {
|
|
_ = try await service.changePassword(current: current, new: new)
|
|
successMessage = "Пароль успешно изменён"
|
|
return true
|
|
} catch {
|
|
self.error = error.localizedDescription
|
|
return false
|
|
}
|
|
}
|
|
}
|