- Add genre and uploader filters to /songs with persistent query params in pagination
- Implement site-wide "Trending" strip showing recently liked songs
- Introduce responsive hamburger nav for mobile with animated icon & ARIA support
- Refactor song row layout: move duration into separate `.song-duration` element
- Update CSS for mobile grid (2 columns), optimized song rows, and facet selects
- Add database tables for song/playlist likes and favorites
- Create `social` service with toggle functions and enrichment helpers
- Implement `/api/:type/:id/(like|favorite)` routes with CSRF protection
- Add like/favorite buttons to player, song lists, playlists, and cards
- Support guest → login redirect via `data-require-login`
- Inject CSRF token into layout for JS API requests
- Add `slug` column to `songs` and `playlists` tables via migrations 005 & 006
- Implement slug generation logic (lowercase, hyphenated, unique) in both services
- Backfill existing rows with auto-generated slugs on startup
- Update public routes to use `/songs/:slug` and `/playlists/:slug`
- Replace all view templates to link using slugs instead of numeric IDs
- Display playlist creator name on public and admin playlist views
- Add shuffle playback button for playlists in player UI
- Implement drag-and-drop reordering for playlist tracks with visual feedback
- Improve email verification UX: redirect pending users to verify page with resend option
- Simplify admin routes by removing redundant role checks (user-based filtering already handled)
- Adjust featured playlist count and add "show all" links on home page
- Add public/logged_in/private visibility levels to songs and playlists via database migration (002_visibility.sql)
- Replace old `is_public` boolean with new `visibility` enum in admin forms, API schemas, and services
- Implement access control logic:
- Guests see only public items that don't contain restricted tracks
- Logged-in users see public + logged_in items (excluding private ones)
- Admins see all; regular users manage their own content
- Auto-upgrade playlist visibility when adding more restrictive songs
- Add UI badges for visibility levels and update admin views to reflect new hierarchy
PWA enhancements:
- Update web manifest with proper name, colors, and icon paths
- Add service worker (sw.js) with cache-first for static assets and network-first for HTML
- Register SW at root (/sw.js) with Service-Worker-Allowed header for full origin scope
- Add theme-color meta tag and navigate.js for client-side routing
Other:
- Update admin nav label from "Admin" to "My Music" to reflect role-based access
- Introduce `songUploadSchema` for flexible uploads where title/artist are optional
- Add `extractAudioMetadata()` to parse ID3/Vorbis tags and embedded cover art from uploaded files
- Merge form values with extracted metadata, falling back to filename-derived title if needed
- Automatically write embedded cover art to `media/covers/` when no manual cover is uploaded
- Update song form UI to indicate optional fields and tag-based fallback behavior
- Switch JSON rendering in partials from `<%-` (unescaped) to `<%=`, improving safety