Restore the feed bar container and name a single active filter - #575
Merged
Merged
Conversation
The feed bar lost two things in separate changes: - #555 removed its container (Color.primary.opacity(0.05) + RoundedRectangle) on the grounds that the controls should sit on the content like a system bottom bar. But a system bar carries a material and this one got nothing, so the grid scrolled under the status label with no separation. - #499 replaced the localized "N tag filters" prose with a bare numeric badge, orphaning filteringByTagsDescription and its string key. Restore separation with a material rather than the old hand-rolled fill, and name the active tag when exactly one is applied — the pill row scrolls, so an active tag can sit off-screen. Two names already truncate mid-word beside Clear/Edit, so past one this falls back to the revived pluralized count. The material is wrapped in a Rectangle rather than applied as .background(.bar) directly: the latter puts the label in a vibrancy context, which rendered the key and tag icons invisible and forced the secondary text to black. Item counts now use the existing feedViewModel.searching.title plural instead of a hardcoded English "item"/"items". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The material was applied to the whole safeAreaInset stack, which pulled the tag pills inside the band. They belong above it, sitting directly on the content, with only the status row carrying a surface. Put the container back where it was — Color.primary.opacity(0.05) + RoundedRectangle(12) around the status row alone — and drop the material. Its horizontal inset leaves no room for "N tag filters", so multiple filters show the bare count as they did originally; a single filter still shows its name, which fits. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bordered button style fills the capsule in both states and signals selection only through tint, which reads as near-identical either way. TagPillView fills a selected pill and leaves an unselected one outlined, which is unambiguous. Keep the Toggle and .toggleStyle(.button) so the pills retain the button trait and selected state that #555 added; only the visual style reverts, via .buttonStyle(.plain) letting TagPillView draw its own capsule. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The feed's bottom bar (tag pills + item count + Clear/Edit) lost its container and its descriptive filter text. These were two separate changes, months apart — and neither was #551, which only touched the backup screens:
510bfeaa(Rebuild the feed bottom bar on standard SwiftUI controls #555) deleted.background(Color.primary.opacity(0.05))+.clipShape(RoundedRectangle(cornerRadius: 12))from the status row, on the stated grounds that "the controls sit on the content the way a system bottom bar does". The controls were left with no surface at all, so theLazyVGridscrolled directly under the status label.315486f5(Fix edit mode access during search #499, January) replaced the localized prose "2 tag filters" with a bare• 🏷 2badge.For the record: there is no sort control in the app and never has been (
git log --all -i -S "sort" -- Sources/VaultiOSis empty). Order is fixed to.relativeOrderat the store layer and rearranged by drag in edit mode.What changed
Color.primary.opacity(0.05)+RoundedRectangle(cornerRadius: 12)around the status row only, inset by 12pt. The tag pills stay above it, sitting directly on the content — that is the original arrangement and it is the one restored here.• 🏷 work). The pill row scrolls horizontally, so an active tag can sit off-screen; the name is information the bare count never carried. With more than one filter there is no room for names inside the container, so it shows the bare count exactly as before (• 🏷 2).statusLabelhardcoded Englishcount == 1 ? "item" : "items". It now uses the existingfeedViewModel.searching.title.%lldplural via a newVaultDataModel.itemsCountDescription, mirroringfilteringByTagsDescription. (That plural lives in VaultFeed's bundle, so it cannot be read from VaultiOS'slocalized(), which resolves against the "Feed" table.)The button styles introduced by #555 (
.bordered/.borderedProminentcapsules,Toggle-based tag pills) are left alone — those were an accessibility fix, not part of the regression.A material was tried and rejected
The first attempt replaced the container with a full-width
.barmaterial across the wholesafeAreaInset. Two problems, both visible in the history of this branch:.background(.bar)applied directly puts the label in a vibrancy context. That is not cosmetic — it rendered thekey.horizontalandtag.fillicons completely invisible and forced the secondary text to black. (.background { Rectangle().fill(.bar) }avoids the vibrancy, if a material is ever wanted here.)Manifesto
Reviewed against
MANIFESTO.md. C5 / C2 are the live ones and drove an explicit non-goal: no "matched of total" count. The feed query filters onvisibility == alwaysand unions search-passphrase matches only when the query matches (PersistedLocalVaultStore.swift:42-49, 102-106), soitems.countdeliberately excludes passphrase-hidden items. Surfacing an unfiltered total would disclose that hidden items exist and let a coercer diff the two numbers. The status label still counts only what the feed already displays, anditemsCountDescriptioncarries a doc comment saying so. Nothing else is touched: no bulk operation (C1), no telemetry (C3), no auth change (C4), no undo or audit surface (C6), no default flipped (C7), no step removed from a sensitive flow (C8), no duress feature advertised (C9), no payload change (C10).Testing
iOSAllTestsplan passes locally on iPhone 18 Pro Max / iOS 27.0.git show 510bfeaa^:…/unifiedBar_multipleTagsFiltered.1.pngto confirm the layout matches the original. Two added —unifiedBar_singleFilterIsNamedandunifiedBar_multipleFiltersFallBackToCount— pinning both sides of the naming threshold.🤖 Generated with Claude Code