Add edit bookmark, offline cache, and unread filter
- Edit bookmark: full PATCH via swipe action or long-press context menu; EditBookmarkView covers URL, title, description, tags, and unread toggle - Offline cache: bookmarks persisted to ApplicationSupport JSON and shown instantly on launch; cache is per-server, skipped when unread filter is on - Unread filter: toolbar toggle sends ?unread=true to the API; title updates to "Unread"; no stale-cache flash when toggling - Extract normalizedURL and parsedTags into String+Helpers, removing three copies of URL normalization and two of tag parsing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ struct BookmarksView: View {
|
||||
@State private var showSettings = false
|
||||
@State private var showCollections = false
|
||||
@State private var showAddBookmark = false
|
||||
@State private var editingBookmark: Bookmark?
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
@@ -34,6 +35,35 @@ struct BookmarksView: View {
|
||||
Label("Archive", systemImage: "archivebox")
|
||||
}
|
||||
.tint(.orange)
|
||||
Button {
|
||||
editingBookmark = bookmark
|
||||
} label: {
|
||||
Label("Edit", systemImage: "pencil")
|
||||
}
|
||||
.tint(.blue)
|
||||
}
|
||||
.contextMenu {
|
||||
Button {
|
||||
editingBookmark = bookmark
|
||||
} label: {
|
||||
Label("Edit", systemImage: "pencil")
|
||||
}
|
||||
Button {
|
||||
if let url = URL(string: bookmark.url) { openURL(url) }
|
||||
} label: {
|
||||
Label("Open", systemImage: "safari")
|
||||
}
|
||||
Divider()
|
||||
Button {
|
||||
Task { await viewModel.archive(bookmark) }
|
||||
} label: {
|
||||
Label("Archive", systemImage: "archivebox")
|
||||
}
|
||||
Button(role: .destructive) {
|
||||
Task { await viewModel.delete(bookmark) }
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +73,7 @@ struct BookmarksView: View {
|
||||
}
|
||||
}
|
||||
.listStyle(.plain)
|
||||
.navigationTitle("Bookmarks")
|
||||
.navigationTitle(viewModel.unreadFilter ? "Unread" : "Bookmarks")
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .topBarLeading) {
|
||||
@@ -70,6 +100,13 @@ struct BookmarksView: View {
|
||||
Button { showAddBookmark = true } label: {
|
||||
Image(systemName: "plus")
|
||||
}
|
||||
Button {
|
||||
Task { await viewModel.toggleUnreadFilter() }
|
||||
} label: {
|
||||
Image(systemName: viewModel.unreadFilter
|
||||
? "line.3.horizontal.decrease.circle.fill"
|
||||
: "line.3.horizontal.decrease.circle")
|
||||
}
|
||||
Button { showSettings = true } label: {
|
||||
Image(systemName: "gearshape")
|
||||
}
|
||||
@@ -99,6 +136,9 @@ struct BookmarksView: View {
|
||||
.sheet(isPresented: $showAddBookmark) {
|
||||
AddBookmarkView(viewModel: viewModel)
|
||||
}
|
||||
.sheet(item: $editingBookmark) { bookmark in
|
||||
EditBookmarkView(viewModel: viewModel, bookmark: bookmark)
|
||||
}
|
||||
.refreshable {
|
||||
await viewModel.load()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user