ReadKeep/readeck/UI/BookmarkDetail/BookmarkDetailViewModel.swift
Ilyas Hallak 7861368196 chore: project setup, navigation improvements, and various fixes
- Add Ruby version and Fastlane setup (Gemfile, fastlane/, .ruby-version) for iOS automation and CI/CD
- Add and update Xcode schemes and project configuration
- Update entitlements and Info.plist for app and extension
- Refactor PhoneTabView: improve navigation in 'More' tab, prevent unwanted jumps, preserve deep navigation for Tags/Search
- Update KeychainHelper, BookmarkDetail model, and related ViewModels for bugfixes or enhancements
- Various UI and logic improvements in BookmarkDetail and Search views
2025-07-17 23:45:24 +02:00

103 lines
3.3 KiB
Swift

import Foundation
@Observable
class BookmarkDetailViewModel {
private let getBookmarkUseCase: GetBookmarkUseCase
private let getBookmarkArticleUseCase: GetBookmarkArticleUseCase
private let loadSettingsUseCase: LoadSettingsUseCase
private let updateBookmarkUseCase: UpdateBookmarkUseCase
private let addTextToSpeechQueueUseCase: AddTextToSpeechQueueUseCase
var bookmarkDetail: BookmarkDetail = BookmarkDetail.empty
var articleContent: String = ""
var articleParagraphs: [String] = []
var bookmark: Bookmark? = nil
var isLoading = false
var isLoadingArticle = true
var errorMessage: String?
var settings: Settings?
init() {
let factory = DefaultUseCaseFactory.shared
self.getBookmarkUseCase = factory.makeGetBookmarkUseCase()
self.getBookmarkArticleUseCase = factory.makeGetBookmarkArticleUseCase()
self.loadSettingsUseCase = factory.makeLoadSettingsUseCase()
self.updateBookmarkUseCase = factory.makeUpdateBookmarkUseCase()
self.addTextToSpeechQueueUseCase = factory.makeAddTextToSpeechQueueUseCase()
}
@MainActor
func loadBookmarkDetail(id: String) async {
isLoading = true
errorMessage = nil
do {
settings = try await loadSettingsUseCase.execute()
bookmarkDetail = try await getBookmarkUseCase.execute(id: id)
} catch {
errorMessage = "Fehler beim Laden des Bookmarks"
}
isLoading = false
}
@MainActor
func loadArticleContent(id: String) async {
isLoadingArticle = true
do {
articleContent = try await getBookmarkArticleUseCase.execute(id: id)
processArticleContent()
} catch {
errorMessage = "Fehler beim Laden des Artikels"
}
isLoadingArticle = false
}
private func processArticleContent() {
let paragraphs = articleContent
.components(separatedBy: .newlines)
.filter { !$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty }
articleParagraphs = paragraphs
}
@MainActor
func archiveBookmark(id: String) async {
isLoading = true
errorMessage = nil
do {
try await updateBookmarkUseCase.toggleArchive(bookmarkId: id, isArchived: true)
bookmarkDetail.isArchived = true
} catch {
errorMessage = "Fehler beim Archivieren des Bookmarks"
}
isLoading = false
}
@MainActor
func refreshBookmarkDetail(id: String) async {
await loadBookmarkDetail(id: id)
}
func addBookmarkToSpeechQueue() {
bookmarkDetail.content = articleContent
addTextToSpeechQueueUseCase.execute(bookmarkDetail: bookmarkDetail)
}
@MainActor
func toggleFavorite(id: String) async {
isLoading = true
errorMessage = nil
do {
let newValue = !bookmarkDetail.isMarked
try await updateBookmarkUseCase.toggleFavorite(bookmarkId: id, isMarked: newValue)
bookmarkDetail.isMarked = newValue
} catch {
errorMessage = "Fehler beim Aktualisieren des Favoriten-Status"
}
isLoading = false
}
}