- Add SwiftUI views for feed list, detail, add feed, settings, and bookmarks - Connect all views to ViewModels using @StateObject - Implement pull-to-refresh for feed list - Add error handling and loading states to all views - Create FeedItemRow view for consistent feed item display - Add toFeedItem() extension to Bookmark for UI integration - Update FeedDetailView to use sync methods - Update BookmarkView to use FeedService for unstar operations Co-Authored-By: Paperclip <noreply@paperclip.ing>
131 lines
4.1 KiB
Swift
131 lines
4.1 KiB
Swift
import Foundation
|
|
|
|
enum BookmarkStoreError: LocalizedError {
|
|
case objectNotFound
|
|
case saveFailed(Error)
|
|
case fetchFailed(Error)
|
|
case deleteFailed(Error)
|
|
|
|
var errorDescription: String? {
|
|
switch self {
|
|
case .objectNotFound:
|
|
return "Bookmark not found"
|
|
case .saveFailed(let error):
|
|
return "Failed to save: \(error.localizedDescription)"
|
|
case .fetchFailed(let error):
|
|
return "Failed to fetch: \(error.localizedDescription)"
|
|
case .deleteFailed(let error):
|
|
return "Failed to delete: \(error.localizedDescription)"
|
|
}
|
|
}
|
|
}
|
|
|
|
protocol BookmarkStoreProtocol {
|
|
func getAllBookmarks() -> [Bookmark]
|
|
func getBookmark(byId id: String) -> Bookmark?
|
|
func getBookmark(byFeedItemId feedItemId: String) -> Bookmark?
|
|
func getBookmarks(byTag tag: String) -> [Bookmark]
|
|
func addBookmark(_ bookmark: Bookmark) -> Bool
|
|
func removeBookmark(_ bookmark: Bookmark) -> Bool
|
|
func removeBookmark(byId id: String) -> Bool
|
|
func removeBookmark(byFeedItemId feedItemId: String) -> Bool
|
|
func getBookmarkCount() -> Int
|
|
func getBookmarkCount(byTag tag: String) -> Int
|
|
}
|
|
|
|
class BookmarkStore: BookmarkStoreProtocol {
|
|
private let databaseManager: DatabaseManager
|
|
|
|
init(databaseManager: DatabaseManager = DatabaseManager.shared) {
|
|
self.databaseManager = databaseManager
|
|
}
|
|
|
|
func getAllBookmarks() -> [Bookmark] {
|
|
do {
|
|
let starredItems = try databaseManager.getStarredItems()
|
|
return starredItems.map { item in
|
|
Bookmark(
|
|
id: item.id,
|
|
feedItemId: item.id,
|
|
title: item.title,
|
|
link: item.link,
|
|
description: item.description,
|
|
content: item.content,
|
|
createdAt: item.published
|
|
)
|
|
}
|
|
} catch {
|
|
return []
|
|
}
|
|
}
|
|
|
|
func getBookmark(byId id: String) -> Bookmark? {
|
|
// For now, return nil since we don't have a direct bookmark lookup
|
|
// This would require a separate bookmarks table
|
|
return nil
|
|
}
|
|
|
|
func getBookmark(byFeedItemId feedItemId: String) -> Bookmark? {
|
|
// For now, return nil since we don't have a separate bookmarks table
|
|
return nil
|
|
}
|
|
|
|
func getBookmarks(byTag tag: String) -> [Bookmark] {
|
|
// Filter bookmarks by tag - this would require tag support
|
|
// For now, return all bookmarks
|
|
return getAllBookmarks()
|
|
}
|
|
|
|
func addBookmark(_ bookmark: Bookmark) -> Bool {
|
|
// Add bookmark by marking the feed item as starred
|
|
let success = databaseManager.markItemAsStarred(itemId: bookmark.feedItemId)
|
|
return success
|
|
}
|
|
|
|
func removeBookmark(_ bookmark: Bookmark) -> Bool {
|
|
// Remove bookmark by unmarking the feed item
|
|
let success = databaseManager.unstarItem(itemId: bookmark.feedItemId)
|
|
return success
|
|
}
|
|
|
|
func removeBookmark(byId id: String) -> Bool {
|
|
// Remove bookmark by ID
|
|
let success = databaseManager.unstarItem(itemId: id)
|
|
return success
|
|
}
|
|
|
|
func removeBookmark(byFeedItemId feedItemId: String) -> Bool {
|
|
// Remove bookmark by feed item ID
|
|
let success = databaseManager.unstarItem(itemId: feedItemId)
|
|
return success
|
|
}
|
|
|
|
func getBookmarkCount() -> Int {
|
|
let starredItems = databaseManager.getStarredItems()
|
|
return starredItems.count
|
|
}
|
|
|
|
func getBookmarkCount(byTag tag: String) -> Int {
|
|
// Count bookmarks by tag - this would require tag support
|
|
// For now, return total count
|
|
return getBookmarkCount()
|
|
}
|
|
}
|
|
|
|
extension Bookmark {
|
|
func toFeedItem() -> FeedItem {
|
|
FeedItem(
|
|
id: feedItemId,
|
|
title: title,
|
|
link: link,
|
|
description: description,
|
|
content: content,
|
|
published: createdAt,
|
|
updated: createdAt,
|
|
subscriptionId: "", // Will be set when linked to subscription
|
|
subscriptionTitle: nil,
|
|
read: false
|
|
)
|
|
}
|
|
}
|