5.9 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | |
|---|---|---|---|---|---|---|---|---|
| quick-12 | 12 | execute | 1 |
|
true |
Purpose: Users can see at a glance which tracks are favorited and toggle favorites directly from the album dropdown, consistent with the track list view.
Output: Updated album-dropdown.ts with per-track favorite icon.
<execution_context> @/home/caleb/.config/opencode/get-shit-done/workflows/execute-plan.md @/home/caleb/.config/opencode/get-shit-done/templates/summary.md </execution_context>
@.planning/STATE.md @frontend/src/components/cover-grid/album-dropdown.ts @frontend/src/store/controllers/favorites-controller.tsFrom frontend/src/store/controllers/favorites-controller.ts:
export class FavoritesController implements ReactiveController {
constructor(host: ReactiveControllerHost);
isFavorited(filePath: string): boolean;
get iconName(): string; // returns 'heart' or 'star'
toggleFavorite(filePath: string): Promise<void>;
}
Existing favorite icon pattern from track-list.ts:
// In the component class:
private favCtrl = new FavoritesController(this);
// In renderTrackRow():
const isFav = this.favCtrl.isFavorited(track.FilePath);
const favVariant = isFav ? 'solid' : 'regular';
// In the template, as the FIRST element in the track row:
<div
class=${classMap({ 'fav-icon': true, favorited: isFav })}
@click=${(e: MouseEvent) => {
e.stopPropagation();
void this.favCtrl.toggleFavorite(track.FilePath);
}}
>
<wa-icon
name=${this.favCtrl.iconName}
variant=${favVariant}
></wa-icon>
</div>
CSS for favorite icon (from track-list.ts):
.fav-icon {
display: flex; align-items: center; justify-content: center;
width: 24px; flex-shrink: 0; cursor: pointer;
color: var(--yj-text-tertiary, #666);
font-size: var(--yj-text-sm);
transition: color 0.1s ease;
}
.fav-icon:hover { color: var(--yj-text-primary, #fff); }
.fav-icon.favorited { color: var(--yj-accent, #ffd43b); }
.fav-icon.favorited:hover { color: var(--yj-accent, #ffd43b); opacity: 0.8; }
-
Add imports:
- Import
FavoritesControllerfrom@store/controllers/favorites-controller - Import
classMapfromlit/directives/class-map.js
- Import
-
Add controller instance to the class body (next to the existing
playercontroller):private favCtrl = new FavoritesController(this); -
Add CSS for
.fav-iconinside the existingstatic override styles = css\...`block, after the.track-durationrule. Use a compact sizing appropriate for the 12px font dropdown (usewidth: 18pxinstead of track-list's24px, andfont-size: 11px` to be proportional to the 12px track rows):.fav-icon { display: flex; align-items: center; justify-content: center; width: 18px; flex-shrink: 0; cursor: pointer; color: var(--yj-text-tertiary, #666); font-size: 11px; transition: color 0.1s ease; } .fav-icon:hover { color: var(--yj-text-primary, #fff); } .fav-icon.favorited { color: var(--yj-accent, #ffd43b); } .fav-icon.favorited:hover { color: var(--yj-accent, #ffd43b); opacity: 0.8; } -
Update
renderTrackRow()to add the favorite icon BETWEEN the track number and the track title. ComputeisFavandfavVariantat the top of the method, then insert the icon element:const isFav = this.favCtrl.isFavorited(track.FilePath); const favVariant = isFav ? 'solid' : 'regular';Insert after
<span class="track-number">and before<span class="track-title">:<div class=${classMap({ 'fav-icon': true, favorited: isFav })} @click=${(e: MouseEvent) => { e.stopPropagation(); void this.favCtrl.toggleFavorite(track.FilePath); }} > <wa-icon name=${this.favCtrl.iconName} variant=${favVariant} ></wa-icon> </div>
Important: The click handler MUST call e.stopPropagation() to prevent the track-row click handler from also firing when toggling favorites.
Run: cd frontend && npx tsc --noEmit
Verify: TypeScript compilation passes with no errors in album-dropdown.ts.
- Album dropdown track rows display a heart/star icon (matching user's configured icon style) between the track number and title
- Favorited tracks show the icon in accent color (solid variant)
- Non-favorited tracks show a subtle tertiary-colored icon (regular variant)
- Clicking the icon toggles the favorite state without triggering track selection
- Icon reactively updates when favorite state changes (via FavoritesController subscription)
<success_criteria>
- Favorite icon visible in album dropdown track rows
- Icon matches configured style (heart or star)
- Favorited state reflected visually (solid + accent color vs regular + tertiary)
- Click toggles favorite without selecting/playing track
- No TypeScript errors </success_criteria>