Make it obvious everywhere when you are looking at things you do not own #117

Merged
logan merged 6 commits from feat/38-ownership-visibility into main 2026-08-19 05:11:43 +00:00
2 changed files with 44 additions and 3 deletions
Showing only changes of commit 19c68d73a7 - Show all commits
@@ -297,9 +297,23 @@ export class LibraryStatusIndicator extends LitElement {
// row to one and nothing to the other, and "Add … to library"
// was the old button's promise written into the copy.
if (this.actionable) {
return this.status === 'queued'
? `Cancel the request for ${kind}${name}`
: `Request ${kind}${name}`;
if (this.status === 'queued') {
return `Cancel the request for ${kind}${name}`;
}
// A partly-held album is actionable *and* has a count, and
// the count does not survive being named after the action
// alone. The `partial` case below says why it matters — a
// ring says "some" to a sighted user and nothing to anyone
// else — and that argument does not stop applying because
// the badge became clickable. This branch used to say only
// "Request album X", so the one state the ring exists for
// was the one state whose name did not mention it.
if (this.status === 'partial') {
return `Request the rest of ${kind}${name}${this.owned} of ${this.expected} tracks are in your library`;
}
return `Request ${kind}${name}`;
}
switch (this.status) {
@@ -77,3 +77,30 @@ describe('the library status badge', () => {
expect(name).toContain('Glass Harbour');
});
});
/**
* A partly-held album is the one state that is *actionable and
* counted*: there are tracks left to ask for, so the badge is a button
* — and a control is named after what activating it does, which is how
* the count came to be dropped from exactly the state the ring exists
* for. Both, or the ring says "some" to an eye and nothing to anyone
* else.
*/
describe('a partial badge that can act', () => {
it('names the action and keeps the count', async () => {
const el = await fixture('library-status-indicator', {
status: 'partial',
owned: 9,
expected: 12,
entityType: 'album',
label: 'Glass Harbour',
requestMbid: 'rg-1',
});
const name = shadow(el, '.badge')?.getAttribute('aria-label') ?? '';
expect(shadow(el, 'button.badge')).not.toBeNull();
expect(name).toContain('Request the rest of');
expect(name).toContain('9 of 12');
});
});