ReadKeep/readeck/UI/AppViewModel.swift
Ilyas Hallak df8a7b64b2 feat: Add Kingfisher caching, card layouts, dynamic tag layout, and undo delete
- Integrate Kingfisher for image caching with CachedAsyncImage component
- Add CacheSettingsView for managing image cache size and clearing cache
- Implement three card layout styles: compact, magazine (default), natural
- Add AppearanceSettingsView with visual layout previews and theme settings
- Create Clean Architecture for card layout with domain models and use cases
- Implement FlowLayout for dynamic label width calculation
- Add skeleton loading animation for initial bookmark loads
- Replace delete confirmation dialogs with immediate delete + 3-second undo
- Support multiple simultaneous undo operations with individual progress bars
- Add grayed-out visual feedback for pending deletions
- Centralize notification names in dedicated NotificationNames file
- Remove pagination logic from label management (replaced with FlowLayout)
- Update AsyncImage usage across BookmarkCardView, BookmarkDetailView, ImageViewerView
- Improve UI consistency and spacing throughout the app
2025-09-04 10:43:27 +02:00

72 lines
1.8 KiB
Swift

//
// AppViewModel.swift
// readeck
//
// Created by Ilyas Hallak on 27.08.25.
//
import Foundation
import SwiftUI
class AppViewModel: ObservableObject {
private let settingsRepository = SettingsRepository()
private let logoutUseCase: LogoutUseCase
@Published var hasFinishedSetup: Bool = true
init(logoutUseCase: LogoutUseCase = LogoutUseCase()) {
self.logoutUseCase = logoutUseCase
setupNotificationObservers()
Task {
await loadSetupStatus()
}
}
private func setupNotificationObservers() {
NotificationCenter.default.addObserver(
forName: .unauthorizedAPIResponse,
object: nil,
queue: .main
) { [weak self] _ in
Task {
await self?.handleUnauthorizedResponse()
}
}
NotificationCenter.default.addObserver(
forName: .setupStatusChanged,
object: nil,
queue: .main
) { [weak self] _ in
self?.loadSetupStatus()
}
}
@MainActor
private func handleUnauthorizedResponse() async {
print("AppViewModel: Handling 401 Unauthorized - logging out user")
do {
// Führe den Logout durch
try await logoutUseCase.execute()
// Update UI state
loadSetupStatus()
print("AppViewModel: User successfully logged out due to 401 error")
} catch {
print("AppViewModel: Error during logout: \(error)")
}
}
@MainActor
private func loadSetupStatus() {
hasFinishedSetup = settingsRepository.hasFinishedSetup
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}