Desktop: make it obvious everywhere when I am looking at things I do not own #38
Closed
opened 2026-08-18 05:56:10 +00:00 by logan
·
3 comments
No Branch/Tag Specified
main
fix/146-stub-etxtbsy
fix/175-wizard-follows-the-library
fix/231-setter-rollback
fix/197-duplicate-column-label
docs/225-fixtures-wav-tags
docs/220-skill-check-scope
test/217-fixture-names-in-queue-selection
fix/216-riff-parse-allocation
fix/170-queue-header-action-names
fix/210-nav-sheet-scroll-affordance
docs/50-readme-landing-page
feat/65-art-prefetch-ahead
feat/71-more-as-a-bottom-sheet
feat/54-native-touch-feel
feat/67-entity-links-into-menus
test/196-visual-tier-gates
fix/138-ui-test-storage-leak
fix/104-wav-tags-read
fix/207-sheet-scroll-affordance
fix/204-ui-visual-update-filter
pi-agent-backlog-automation
63-touch-model-phase-2
63-android-touch-model
186-touch-targets-settings
186-touch-targets-page-header
187-seek-bar-hit-area
189-190-explore-correctness
135-android-underrun-instrumentation
51-android-small-screens
fix/171-phone-queue-scrim
fix/137-touch-only-affordances
fix/154-nested-css-check
feat/58-mini-player-progress-line
fix/66-album-page-scrolls-as-one
60-context-menu-action-sheet
64-android-system-volume
59-slim-the-mini-player
55-queue-as-a-screen
feat/57-drop-the-android-top-bar
feat/62-jobs-as-a-notification
fix/53-seek-bar-never-moves
fix/159-android-task-app-id
fix/52-android-activity-recreation-restarts-the-process
fix/150-expand-button-under-the-art
feat/42-inline-volume-and-centred-transport
fix/156-queue-selection-fixture-order
fix/151-fuse-the-scroll-guard-and-the-write
fix/43-queue-panel-selection
fix/143-top-bar-fits-its-window
feat/27-jobs-into-settings
feat/25-configurable-sidebar-tabs
feat/6-global-back-forward
fix/72-active-view-broadcast
fix/69-page-header-action-overflow
fix/quick-wins-batch
fix/118-in-library-clear
fix/61-mini-player-plain-text
fix/68-hover-affordances-pointer
fix/119-dev-headless-port
fix/130-issue-claim-user
fix/131-codegen-check-scope
feat/28-autotag-match-on-album
feat/17-demote-version-selector
feat/38-ownership-visibility
ci/115-manual-release
feat/34-icon-language
feat/7-full-tracklist-toggle
fix/16-tagwriter-totals
fix/unclaim-ca-certs
fix/unclaim-shell
ci/unclaim-on-close
docs/closing-keyword
docs/retire-stale-planning-docs
docs/issue-driven-workflow
integration/small-fixes
fix/small-issue-batch
fix/queue-toggle-state
fix/drag-count-badge
fix/album-card-year
fix/album-tracklist-heading
fix/seek-bar-clock-width
fix/explore-art-scanner-requests
chore/workflow-guardrails
v0.7.0
v0.6.0
v0.5.0
v0.4.0
v0.3.1
v0.3.0
v0.2.3
v0.2.2
v0.2.1
v0.2.0
v0.1.0
v0.0.1
v0.0.0
Labels
Clear labels
Area/Design
Area/Downloads
Area/Explore
Area/Library-UI
Area/Metadata
Area/Packaging
Area/Player
Area/Queue
Area/Settings
Area/Shell-Nav
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Platform/Android
Platform/Desktop
Breaking change that won't be backward compatible
Something is not working
Documentation changes
Improve existing functionality
New functionality
This is security issue
Issue or pull request related to testing
Priority
Critical
1
The priority is critical
Priority
High
2
The priority is high
Priority
Medium
3
The priority is medium
Priority
Low
4
The priority is low
Reviewed
Confirmed
1
Issue has been confirmed
Reviewed
Duplicate
2
This issue or pull request already exists
Reviewed
Invalid
3
Invalid issue
Reviewed
Won't Fix
3
This issue won't be fixed
Status
Blocked
1
Something is blocking this issue or pull request
Status
Need More Info
2
Feedback is required to reproduce issue or to continue work
Status
Abandoned
3
Somebody has started to work on this but abandoned work
Status
In Progress
Somebody is actively working on this right now
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Depends on
Reference: yonlu/yellowjacket#38
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Report
Anywhere the UI shows tracks (or albums, or anything else) I do not have, that should be immediately obvious. The inverse should be mild: owned content is the default, normal, unadorned presentation; unowned content is what gets marked. It is confusing that stuff I am exploring looks the same as stuff I have.
Findings
The rule is already stated and partially implemented —
explore-album-detailsdims unowned rows in place and marks nothing on owned ones (the previous green-tick-per-owned-row was the opposite treatment), and the dimmed rows carryaria-disabledbecause dimming is a colour and cannot be the only signal.What is inconsistent is everywhere else: Explore's cards,
top-results-row, artist detail's top tracks and discography cards, and the search results all mix owned and unowned with a small badge as the only difference — and the badge itself has known accuracy problems (see the "2 of 10" issue).Direction
Write the rule down once and apply it as a pass:
aria-disabled, or a consistent marker) + a request affordance where one is possible.Then audit every surface that can show catalog content: album detail, artist detail, explore search/browse/shelves, top results, home shelves, downloads. This is the umbrella for the badge-accuracy and icon-language issues.
Both blockers are closed, so dropping
Status/Blocked. This is next in the roadmap's (#73) Phase 1.What the three merged issues leave for it:
tagwriterwrites the per-disc track and disc totals, so autotagging no longer erases the evidence behind "9 of 12". The badge'spartialstate has a real input now for anything tagged from here on.utils/icon-language.tsis the vocabulary, and the request toggle is one glyph in two weights everywhere. The half of this issue that is "the icons are half of the signal" is done; what is left is where the signal is drawn.So the remaining work is the audit the Direction describes: Explore's cards,
top-results-row, artist detail's top tracks and discography cards, search results, home shelves, downloads.explore-album-details's tracklist is the reference implementation — dimmed in place,aria-disabledbecause dimming is a colour and cannot be the only signal, and nothing at all on the owned rows.One thing worth deciding before the sweep rather than during it: the album page answers ownership with
filePaths, a map from a displayed track to a real file, filled once by a batchedGetFilePathsByRecordingMBIDs— deliberately not the catalog'sinLibraryflag, which is set by MBID and can be true for something with no file behind it. A card grid cannot afford that call per card, so either the grids accept the weaker flag and say so, or something batches it per screenful the waycredit-store.tscoalesces.Not claiming it — flagging that it is ready to be picked up.
Claiming this. Branch:
feat/38-ownership-visibility.The decision, before the sweep
The question was whether the grids accept the catalog's
inLibraryflag and say so in the copy, or whether something batches a real file
lookup per screenful the way
credit-store.tscoalesces.Neither. The grids take
localId, which is the file-backed answerand is already on every model at no cost. Measured in the code:
collectLibraryEntitiesbuilds everylocal_artist_id/local_release_group_id/local_recording_idfrom a query thatjoins
audio_files— the same "ownership is a file" rule the albumpage's
filePathsimplements — andpruneStaleLocalCrossReferencesclears them with an
existstest that is a file test in all threecases, with the comment saying why: the version that tested the
metadata table left 129 rows in a real catalog claiming to be owned
by files that were gone.
in_libraryis written by the same pass, so in the database todaythe two agree. What differs is that
in_libraryis a one-way ratchet(
in_library = MAX(in_library, excluded.in_library)inupsertIndexConflictSQL) whose only clearing pass is gated onlocal_*_id IS NOT NULL. It cannot be un-set on its own. One of thetwo is a fact with an owner; the other is a flag that happens to
agree with it.
So a batched call buys nothing the models do not already carry. It
would also only reach half the problem:
GetFilePathsByRecordingMBIDsanswers for recordings, and most of the cards on the surfaces this
issue names are release groups, for which there is no batch — the
equivalent is
GetAlbumCompleteness, per album. Batching would maketrack rows strong and leave album cards exactly where they are, at the
price of a new coalescing store.
Where they diverge today, which is the client
Both
explore-viewandexplore-artist-detailskeep alibraryMBIDsSetthat accumulates every MBID ever seen withinLibraryand isnever cleared.
explore-viewis a cached primary view — it neverunmounts — so a rescan that removes files leaves its cards claiming
ownership for the life of the session. Those sets go.
The bug that makes this concrete
On
explore-artist-details, one card answers "do I own this" twice andgets two answers.
renderReleaseMenuItemsgates playback onrelease.localId > 0, per the rule already written above it; the badgeand
albumTarget.ownedusethis.libraryMBIDs.has(mbid) || rg.inLibrary || localId > 0. An album withinLibraryand no local idtherefore draws a green tick saying it is in your library, offers
no Play, and — because the request item is gated on
!release.owned—offers no way to ask for it either. A card that claims to be owned and
can do nothing at all.
What the pass does
utils/ownership.ts:isOwned()(alocal id, nothing else), the sentence unowned things say, and the
dimming as a shared
cssfragment so eight surfaces cannot drift.which is what
explore-album-detailsalready does with itstracklist and what the green ticks were removed for.
aria-disabledand a name thatsays so — dimming is a colour and cannot be the only signal. Text
dims to
--yj-text-secondaryrather thanopacity, because thecontrast table is what guarantees it still clears 4.5:1.
third bullet and #16's deferred step 3. This is the one part that
needs a batch, and it is a different one: a new
GetAlbumsCompleteness(albumIDs)— one query for a screenful,asked only for cards that have a local album id, coalesced per frame
in a store shaped like
credit-store. Without it an album you hold2 of 10 tracks of wears a bare tick on the cards page, which is #16's
original complaint one surface over.
home-view,downloads-view,cover-grid,artist-detailsandgenre-detailsare audited and unchanged: none of them can showcatalog content, so everything on them is owned and "owned = plain" is
already what they do. That is a finding, not an omission.
PR #117 is up. CI was green on both jobs (
check3m,e2e6mincluding WebKit) at
10eca35; the docs commitc4e055cis queuedbehind it.
The decision, as implemented: the grids take
localId— set andcleared by a file test — and never
inLibrary. The full argument is inthe claim comment above and is now written down in CLAUDE.md and
.planning/NOTES.md, since every future catalog surface has to makethe same choice.
Two things found on the way and fixed here: a card on
explore-artist-detailsthat answered ownership twice and got twoanswers (green tick, no Play, and no way to request it either), and an
actionable
partialbadge whose name dropped the count — the one statethe ring exists for.
One filed rather than fixed: #118,
in_librarycan never becleared on a row with no local id. Routing the UI around the flag is
not a fix, because it still drives search scoring, the popularity-floor
bypass and two Explore shelves.
Not done here: #17 ("demote the release-version selector"), which
#73 pairs with this as "same page, same pass". It is a different page —
explore-album-detailsrather than the card surfaces — so it is leftfor its own change rather than folded in.