Replace the Tags tab with a tag picker sheet
The tab bar drops from five to four; Tags now opens as a sheet from the + in the library's filter strip, which is the control that was already about adding a tag. Picking a tag pins it as a filter tab rather than pushing to a separate per-tag list. That made TagBookmarksView redundant — the filter tab shows the same thing, in whichever layout you're already using — so it's gone. This also fixes what the + could reach. The old inline menu listed tags found on the loaded page, so it offered 21 of 96 tags, and once a tag filter was active it collapsed to just the tags co-occurring with that one — pinning a second unrelated tag was impossible. The sheet sources names from the tags endpoint via a new BookmarksViewModel.loadAllTags(), and counts still come from loaded bookmarks, so a tag we haven't paged in shows no number rather than a wrong one. The sheet is searchable, marks already-pinned tags with a check, and picking a pinned tag selects that tab instead of duplicating it. Verified by driving the UI: the tab bar is now Bookmarks/Sources/ Podcasts/Search, + opens the sheet with 42 rows where the old menu had 21, and picking "ai" pinned an "ai" tab. Suite passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JgLHztZGaEHvS3KNeGQmRM
This commit is contained in:
co-authored by
Claude Opus 5
parent
69c2bc7514
commit
8a777ffc83
@@ -277,9 +277,11 @@ struct LibraryCard: View {
|
||||
struct LibraryTagStrip: View {
|
||||
@Binding var filters: [LibraryFilter]
|
||||
@Binding var selection: LibraryFilter.ID?
|
||||
/// Tags available to pin that aren't already open.
|
||||
let available: [String]
|
||||
var onChange: () -> Void = {}
|
||||
/// Opens the tag picker. It replaced an inline Menu, which could only list
|
||||
/// tags found on the loaded page — and once a tag filter was active, that
|
||||
/// collapsed to the handful of tags co-occurring with it.
|
||||
var onBrowseTags: () -> Void = {}
|
||||
|
||||
@Namespace private var strip
|
||||
|
||||
@@ -294,20 +296,13 @@ struct LibraryTagStrip: View {
|
||||
ForEach(filters) { filter in
|
||||
tab(filter)
|
||||
}
|
||||
Menu {
|
||||
ForEach(available, id: \.self) { tag in
|
||||
Button(tag) { add(tag: tag) }
|
||||
}
|
||||
if !filters.contains(where: { $0.tag == nil }) {
|
||||
Divider()
|
||||
Button("Everything") { add(tag: nil) }
|
||||
}
|
||||
} label: {
|
||||
Button { onBrowseTags() } label: {
|
||||
Image(systemName: "plus")
|
||||
.font(.system(size: 18, weight: .light))
|
||||
.foregroundStyle(Paper.ink.opacity(0.6))
|
||||
.frame(width: 50, height: 42)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.accessibilityLabel("Pin a tag")
|
||||
Spacer(minLength: 0)
|
||||
}
|
||||
@@ -359,15 +354,6 @@ struct LibraryTagStrip: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func add(tag: String?) {
|
||||
let new = LibraryFilter(name: tag ?? "Everything", tag: tag)
|
||||
withAnimation(.spring(duration: 0.35, bounce: 0.1)) {
|
||||
filters.append(new)
|
||||
selection = new.id
|
||||
}
|
||||
onChange()
|
||||
}
|
||||
|
||||
private func close(_ filter: LibraryFilter) {
|
||||
filters.removeAll { $0.id == filter.id }
|
||||
if selection == filter.id {
|
||||
|
||||
Reference in New Issue
Block a user