ReadKeep/readeck/UI/Settings/FontSettingsViewModel.swift
Ilyas Hallak f3719fa9d4 Refactor tag management to use Core Data with configurable sorting
This commit introduces a comprehensive refactoring of the tag management
system, replacing the previous API-based approach with a Core Data-first
strategy for improved performance and offline support.

Major Changes:

Tag Management Architecture:
- Add CoreDataTagManagementView using @FetchRequest for reactive updates
- Implement cache-first sync strategy in LabelsRepository
- Create SyncTagsUseCase following Clean Architecture principles
- Add TagSortOrder enum for configurable tag sorting (by count/alphabetically)
- Mark LegacyTagManagementView as deprecated

Share Extension Improvements:
- Replace API-based tag loading with Core Data queries
- Display top 150 tags sorted by usage count
- Remove unnecessary label fetching logic
- Add "Most used tags" localized title
- Improve offline bookmark tag management

Main App Enhancements:
- Add tag sync triggers in AddBookmarkView and BookmarkLabelsView
- Implement user-configurable tag sorting in settings
- Add sort order indicator labels with localization
- Automatic UI updates via SwiftUI @FetchRequest reactivity

Settings & Configuration:
- Add TagSortOrder setting with persistence
- Refactor Settings model structure
- Add FontFamily and FontSize domain models
- Improve settings repository with tag sort order support

Use Case Layer:
- Add SyncTagsUseCase for background tag synchronization
- Update UseCaseFactory with tag sync support
- Add mock implementations for testing

Localization:
- Add German and English translations for:
  - "Most used tags"
  - "Sorted by usage count"
  - "Sorted alphabetically"

Technical Improvements:
- Batch tag updates with conflict detection
- Background sync with silent failure handling
- Reduced server load through local caching
- Better separation of concerns following Clean Architecture
2025-11-08 13:46:40 +01:00

105 lines
3.0 KiB
Swift

//
// FontSettingsViewModel.swift
// readeck
//
// Created by Ilyas Hallak on 29.06.25.
//
import Foundation
import Observation
import SwiftUI
@Observable
class FontSettingsViewModel {
private let saveSettingsUseCase: PSaveSettingsUseCase
private let loadSettingsUseCase: PLoadSettingsUseCase
// MARK: - Font Settings
var selectedFontFamily: FontFamily = .system
var selectedFontSize: FontSize = .medium
// MARK: - Messages
var errorMessage: String?
var successMessage: String?
// MARK: - Computed Font Properties for Preview
var previewTitleFont: Font {
switch selectedFontFamily {
case .system:
return selectedFontSize.systemFont.weight(.semibold)
case .serif:
return Font.custom("Times New Roman", size: selectedFontSize.size).weight(.semibold)
case .sansSerif:
return Font.custom("Helvetica Neue", size: selectedFontSize.size).weight(.semibold)
case .monospace:
return Font.custom("Menlo", size: selectedFontSize.size).weight(.semibold)
}
}
var previewBodyFont: Font {
switch selectedFontFamily {
case .system:
return selectedFontSize.systemFont
case .serif:
return Font.custom("Times New Roman", size: selectedFontSize.size)
case .sansSerif:
return Font.custom("Helvetica Neue", size: selectedFontSize.size)
case .monospace:
return Font.custom("Menlo", size: selectedFontSize.size)
}
}
var previewCaptionFont: Font {
let captionSize = selectedFontSize.size * 0.85
switch selectedFontFamily {
case .system:
return Font.system(size: captionSize)
case .serif:
return Font.custom("Times New Roman", size: captionSize)
case .sansSerif:
return Font.custom("Helvetica Neue", size: captionSize)
case .monospace:
return Font.custom("Menlo", size: captionSize)
}
}
init(factory: UseCaseFactory = DefaultUseCaseFactory.shared) {
self.saveSettingsUseCase = factory.makeSaveSettingsUseCase()
self.loadSettingsUseCase = factory.makeLoadSettingsUseCase()
}
@MainActor
func loadFontSettings() async {
do {
if let settings = try await loadSettingsUseCase.execute() {
selectedFontFamily = settings.fontFamily ?? .system
selectedFontSize = settings.fontSize ?? .medium
}
} catch {
errorMessage = "Error loading font settings"
}
}
@MainActor
func saveFontSettings() async {
do {
try await saveSettingsUseCase.execute(
selectedFontFamily: selectedFontFamily,
selectedFontSize: selectedFontSize
)
successMessage = "Font settings saved"
} catch {
errorMessage = "Error saving font settings"
}
}
func clearMessages() {
errorMessage = nil
successMessage = nil
}
}