ReadKeep/readeck/UI/readeckApp.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

54 lines
1.4 KiB
Swift

//
// readeckApp.swift
// readeck
//
// Created by Ilyas Hallak on 10.06.25.
//
import SwiftUI
import netfox
@main
struct readeckApp: App {
@StateObject private var appViewModel = AppViewModel()
@StateObject private var appSettings = AppSettings()
var body: some Scene {
WindowGroup {
Group {
if appViewModel.hasFinishedSetup {
MainTabView()
} else {
SettingsServerView()
.padding()
}
}
.environmentObject(appSettings)
.preferredColorScheme(appSettings.theme.colorScheme)
.onAppear {
#if DEBUG
NFX.sharedInstance().start()
#endif
// Initialize server connectivity monitoring
_ = ServerConnectivity.shared
Task {
await loadAppSettings()
}
}
.onReceive(NotificationCenter.default.publisher(for: .settingsChanged)) { _ in
Task {
await loadAppSettings()
}
}
}
}
private func loadAppSettings() async {
let settingsRepository = SettingsRepository()
let settings = try? await settingsRepository.loadSettings()
await MainActor.run {
appSettings.settings = settings
}
}
}