mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
ad74578ef6
* feat(playlists): playlist folder model — store + pure grouping core Local, per-server folder layer over the server's flat playlist list (the Subsonic API has no folder concept). Adds: - playlistFolders.ts: shared types + pure groupPlaylistsByFolder (used by every surface), with full unit coverage. - playlistFolderStore.ts: persisted Zustand store (create/rename/delete/ assign/collapse), per-server scoped; deleting a folder drops its assignments so playlists fall back to ungrouped. UI surfaces (sidebar + Playlists page) build on this in following commits. * i18n(playlists): folder strings across all 9 locales Adds the playlists.folders.* namespace (folder names, move/remove, expand/ collapse, group-by-folders toggle, count plurals, and the local-only notice explaining that Navidrome and the Subsonic API have no native folder support). * feat(playlists): folder views, drag-to-folder, move-to-folder menu, view toggle Surfaces the local folder layer on both the Playlists page and the sidebar: - Page: collapsible folder sections + ungrouped remainder, each reusing VirtualCardGrid; flat grid is kept verbatim when no folders exist or the group view is toggled off. - Drag-to-folder via the shared mouse-based psy-drop system (HTML5 DnD is unusable in WebKitGTK); the whole section is the drop zone, and the ungrouped zone appears during a drag so a playlist can always return to root. - "Move to folder" submenu in the playlist context menu (keyboard-accessible path; also creates folders on the fly) — stays available offline. - Header gets a "New folder" action and a "Group by folders" view toggle (both context-aware); a notice surfaces the local-only caveat. - Sidebar renders the same collapsible folder groups. - groupView preference added to the folder store. * docs(changelog): note playlist folders (#1119)
95 lines
3.3 KiB
CSS
95 lines
3.3 KiB
CSS
@import './_intro.css';
|
|
@import './hero.css';
|
|
@import './page-header-row-title-actions.css';
|
|
@import './section-titles.css';
|
|
@import './album-card.css';
|
|
@import './artist-card-grid-view.css';
|
|
@import './composer-grid-text-only-compact.css';
|
|
@import './album-row-container.css';
|
|
@import './artist-card-selection-checkbox.css';
|
|
@import './live-search.css';
|
|
@import './album-detail.css';
|
|
@import './offline-library.css';
|
|
@import './cover-lightbox.css';
|
|
@import './offline-cache-button.css';
|
|
@import './download-folder-modal.css';
|
|
@import './song-info-modal.css';
|
|
@import './share-queue-preview-modal.css';
|
|
@import './tracklist.css';
|
|
@import './modal.css';
|
|
@import './playback-delay-sleep-delayed-start-modal.css';
|
|
@import './lucky-mix-pips-shared-by-the-inline-queue-lucky-cube-indicator.css';
|
|
@import './playback-buffering-overlay.css';
|
|
@import './playlist-edit-modal.css';
|
|
@import './playlist-folders.css';
|
|
@import './artists-page.css';
|
|
@import './years-page.css';
|
|
@import './settings.css';
|
|
@import './help-page.css';
|
|
@import './normalization-block-per-mode-sub-section.css';
|
|
@import './sidebar-customizer.css';
|
|
@import './login-page.css';
|
|
@import './loading-empty.css';
|
|
@import './fullscreen-player-adaptive-portrait.css';
|
|
@import './fullscreen-player-static.css';
|
|
@import './context-menu.css';
|
|
@import './css-tooltips.css';
|
|
@import './playlists-page.css';
|
|
@import './statistics-page.css';
|
|
@import './connection-indicator.css';
|
|
@import './now-playing-presence.css';
|
|
@import './offline-overlay.css';
|
|
@import './now-playing-page.css';
|
|
@import './now-playing-page-2.css';
|
|
@import './radio-nowplaying-section.css';
|
|
@import './equalizer.css';
|
|
@import './playback-rate.css';
|
|
@import './custom-select.css';
|
|
@import './changelog.css';
|
|
@import './genre-filter-bar.css';
|
|
@import './filter-quick-clear.css';
|
|
@import './genre-tag-cloud.css';
|
|
@import './random-landing.css';
|
|
@import './playlists-overview-header.css';
|
|
@import './favorites-offline-control.css';
|
|
@import './playlist-card-grid-overview.css';
|
|
@import './internet-radio.css';
|
|
@import './radio-toolbar.css';
|
|
@import './radio-card-edit-chip.css';
|
|
@import './alphabet-filter-bar.css';
|
|
@import './artists-page-alphabet-bar.css';
|
|
@import './radio-favorite-star.css';
|
|
@import './radio-browser-directory.css';
|
|
@import './bulk-select.css';
|
|
@import './playlist-search-panel.css';
|
|
@import './context-menu-submenu.css';
|
|
@import './tracklist-compact-title-artist-rows.css';
|
|
@import './artist-detail-page.css';
|
|
@import './album-artist-grid-fewer-columns.css';
|
|
@import './hero-mobile.css';
|
|
@import './live-search-full-width.css';
|
|
@import './section-page-titles.css';
|
|
@import './album-detail-header-stack-vertically-on-mobile.css';
|
|
@import './page-padding.css';
|
|
@import './hide-desktop-search-on-mobile.css';
|
|
@import './search-bar.css';
|
|
@import './results-area.css';
|
|
@import './empty-state.css';
|
|
@import './category-chips.css';
|
|
@import './recent-searches.css';
|
|
@import './section-headers.css';
|
|
@import './result-items.css';
|
|
@import './album-header-mobile-actions.css';
|
|
@import './album-tracklist-mobile.css';
|
|
@import './most-played-page.css';
|
|
@import './ui-scale-slider.css';
|
|
@import './zip-download-overlay.css';
|
|
@import './device-sync.css';
|
|
@import './what-s-new-banner-page.css';
|
|
@import './page.css';
|
|
@import './mini-player-window.css';
|
|
@import './_banner.css';
|
|
@import './np-dash.css';
|
|
@import './orbit-session-top-strip.css';
|
|
@import './back-to-top.css';
|