mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
1a7a2a0bfce2e6540cb46f38363c9071d9a53a6e
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1a7a2a0bfc |
chore(servers): remove quick/full scan buttons from server cards (#843)
Drops the Quick/Full scan actions and all supporting logic — they are no longer needed. Removes the ServerScanActions component (incl. the unused compact variant), the subsonicScan API, the scanStore, and the app-root useScanPolling hook (no more background scan polling). Cleans up the .server-scan-* CSS and the settings.scan i18n block across all 9 locales. 440 deletions, no new code; tsc + bundle clean. |
||
|
|
bca45d5a80 |
feat(servers): scan actions + edit existing server profiles (#780)
* feat(server-scan): plumbing for triggering library scans
Adds `startScan` / `getScanStatus` against the Subsonic API
(`fullScan=true` is Navidrome's extension), a small per-server scan
store, and a global polling hook (2 s cadence) that emits a toast when
each scan finishes. Scans can run on any configured server, including
inactive ones, by reusing `apiForServer`.
UI surfaces follow in the next commit.
* feat(server-scan): expose Quick / Full Scan in switcher + settings cards
Adds a `ServerScanActions` component with two variants (compact for the
server-switcher dropdown, card for the Settings server cards) backed by
the scan store from the previous commit. Full Scan requires a second
click within 3 s to confirm, matching the playlist-delete pattern.
Status slot shows a spinner with running track count while scanning, a
green check when finished, and a red icon on error.
The switcher row is converted from a single button to a flex container
so per-server scan controls don't hijack the server-switch click.
i18n added across all 9 locales.
* fix(server-scan): reorder switcher row to check / name / scan actions
Moves the check / spinner slot from the right edge to the left so the
spinner pop-in on server switch doesn't sit next to the scan icons.
Removes the layout shift that briefly hovered the Quick scan button
when the row re-rendered.
* feat(servers): edit existing server profiles in Settings → Servers
* Pencil-button on each server card opens an inline edit form that
replaces the card (prefilled name / URL / username / password).
* `AddServerForm` reused with an `editingServer` prop — title flips to
"Edit Server", submit label to "Save", magic-string field hidden (the
edit scope is manual fields; magic-string remains an add-time invite
shortcut).
* Edit saves unconditionally — ping runs post-save as a status indicator
(analog to the existing Test button) instead of gating the save. Lets
users update a profile when the server is currently unreachable.
* Translations across all 9 locales (`editServer`, `editServerTitle`).
* fix(servers): submit Add/Edit Server form on Enter
Wrapped the form body in a real <form>, made the submit button
type="submit", marked Cancel as type="button" so Enter no longer
cancels. Add-Mode now also responds to Enter — same flow, consistent
across both modes.
* fix(servers): collapse card action buttons to icon-only on narrow screens
* Quick-Scan / Full-Scan / Test buttons in each server card hide their
text label below 1100px viewport via the .server-card-btn-label class
and a single media query in connection-indicator.css.
* Labels remain accessible via data-tooltip and aria-label so screen
readers + hover both keep working in the collapsed state.
* No content reflow above the breakpoint — pure additive CSS.
* fix(servers): include Use button in icon-only narrow-screen collapse
The Use ("Verwenden") button on inactive server cards lacked the
.server-card-btn-label wrapper, so its text stayed visible at narrow
viewports and pushed Edit/Delete off-screen. Added a Power icon and
wrapped the label so it collapses alongside the other action buttons.
* docs(changelog,credits): #780 server scan + edit
|
||
|
|
04149c048e |
fix(settings): server row actions wrap inside the card at narrow widths (#751)
The action cluster (Test Connection / Use / Delete) had `flex-shrink: 0` and the parent flex row had no `flex-wrap`, so on narrower Settings panes the buttons spilled past the card's right edge instead of flowing under the server info. Enable `flex-wrap: wrap` on the parent and pin the actions with `margin-left: auto` so they stay right-aligned when they wrap to a new line. |
||
|
|
3b94368ffa |
fix(ui): visual consistency sweep — shapes, buttons, hero, header alignment (#745)
* fix(ui): square shape across badges, pills and non-player buttons zunoz on Discord flagged inconsistent shapes for play buttons, badges and pills across the app. Unify to var(--radius-sm) for non-player surfaces so the same visual indicator looks identical wherever it appears. Player Bar, Fullscreen Player and Mini Player keep their circular shape as part of the player family; toggle switches, sliders, search input, pagination dots and theme overrides are left alone. Covers: hero play + nav arrows, album-card details button, album header icon buttons, playlist suggestion play, album-row nav arrows; .badge (incl. New / album-detail), genre pill, np chip/tag/badge, np-dash toolbar badge, radio filter chip, radio card chip, mp album plays pill, settings search-result badge, alphabet filter buttons, download hint, mobile search chip, artist release-group count, artist external link, all Orbit session pills, device-sync count badge; ServersTab "Aktiv" badge, PlaylistCard loading badge, AlbumRow / ArtistRow "more" buttons. * fix(composers): collapse empty space between virtual rows The composer grid uses text-only tiles (~78 px intrinsic) but estimateRowHeightPx scaled with cell width like the image variants, clamped to a 200 px maximum. On normal viewports every virtual row reserved ~200 px while the actual card was ~78 px, leaving ~120 px of empty space below each row. Pin the composer variant to min === max so the rowHeight is a fixed 88 px regardless of cell width. * fix(ui): unify secondary action buttons on btn-surface Action rows on the Artist, Album, Tracks, Favorites and Most Played pages mixed btn-ghost (borderless), btn-surface (bordered) and bare .btn (no variant, picked up bordered look in light themes only). Result was per-page and per-theme inconsistency — secondary buttons sometimes had borders, sometimes not. Unify on btn-surface for all secondary actions so the same affordance looks identical across pages and the difference between themes is just border tone, not border presence. - Tracks hero: Enqueue and Reroll buttons - AlbumHeader: Shuffle, Enqueue, Star, Share, Bio, Download and the Offline-cache states - MostPlayed: sort toggle and compilations filter (now matches the Albums page header) * fix(hero): make pagination dots visible on light backdrops The pagination dots used `rgba(255, 255, 255, 0.35)` which disappears against white-dominant cover art and on light themes, even under the hero gradient overlay. zunoz on Discord reported the inactive dots as effectively invisible. Bump inactive dots to 85 % white with a dark outline + drop shadow so they read against any backdrop, and switch the active dot to the accent color so the highlight reads as colour, not just width. Also opaque-fill `.badge` (`var(--accent)` + `--ctp-crust` text) so the hero pills do not disappear against light cover art either — base class previously used `--accent-dim` which is too transparent for badges per the existing badge rule. * fix(tracks): align Browse-all-tracks header with rows The Tracks page header sat outside the scroll container while rows sat inside it, so the scrollbar gutter shrank only the rows and the last header column drifted right of its row data. With OpenDyslexic selected the wider glyphs pushed "Duration" past the viewport edge entirely; zunoz on Discord reported it. Move SongListHeader inside the scroll container with position: sticky so header and rows share the same width budget. Sticky keeps the header visible while scrolling as a side benefit. * test(cardGridLayout): pin composer variant to fixed row height Guards the fix that collapsed the empty space between Composers grid rows. Re-introducing the `cellWidthPx + extra` scaling for composer would silently bring back ~120 px of dead space per virtual row, so the test asserts the fixed 88 px output across a wide cellWidth range. Image variants (artist / album / playlist) get baseline assertions so the composer case is documented as the deliberate exception, not an oversight. * docs(changelog): UI consistency sweep (PR #745) |
||
|
|
7a7a9f5e6b |
refactor(utils): group utils/ files into topic folders (Phase L, part 1) (#689)
111 of 122 top-level src/utils/ files move into 16 topic folders (audio, cache, cover, share, server, playback, playlist, deviceSync, waveform, mix, format, export, changelog, ui, perf, componentHelpers). True singletons with no cluster stay at the utils/ root. Pure file-move: a path-aware codemod rewrote 539 relative-import specifiers across 275 files; no logic touched. The hot-path coverage gate list (.github/frontend-hot-path-files.txt) is updated to the new paths for the 11 gated utils files — a mechanical consequence of the move, not a CI change. tsc is green. |
||
|
|
8adad2be6f |
refactor(settings): G.60 — extract Storage + Servers + System tabs (cluster) (#626)
Three-tab cluster cut. Settings.tsx 1393 → 345 LOC (−1048); the page now keeps only the tab header, search UI, route-state handling, ndAdminAuth probe, and tab dispatch — every section body lives in its own file. StorageTab — owns offline dir + cache size readouts + cache-clear flow + waveform-cache clear + buffering toggles (preload mode / hot cache incl. dir picker, sliders, clear) + ZIP downloads dir. The hot-cache state (imageCacheBytes / offlineCacheBytes / hotCacheBytes / showClearConfirm / clearing), the hotCacheTrackCount memo, all three hot-cache useEffects, handleClearCache / handleClearWaveformCache, and pickOfflineDir / pickHotCacheDir / pickDownloadFolder move with it. Side effect: the two live hotCacheBytes-refresh useEffects were gated on `activeTab === 'audio'` (a stale leftover from when hot cache lived on the audio tab); they now run while StorageTab is mounted, which is the only place hotCacheBytes is actually displayed. ServersTab — owns the server list, DnD reorder (psy-drop listener + drop-target hover state + serverContainerEl + handleServerDragMove), connStatus map, AddServerForm flow (showAddForm + pastedServerInvite + addServerInviteAnchorRef + the scroll-into-view useLayoutEffect), testConnection / switchToServer / deleteServer / handleAddServer / closeAddServerForm / handleLogout. Settings still owns the route-state useEffect that catches `openAddServerInvite` and flips to the servers tab; it passes the invite as `initialInvite` and ServersTab consumes it on mount + on later prop changes. SystemTab — owns Language picker, behavior toggles (tray, minimize to tray, Linux kinetic scroll), Backup section, logging mode + export runtime logs, About card (maintainers, release notes link, show-changelog-on-update), Contributors grid, Licenses panel. The exportRuntimeLogs handler moves with it. UsersTab stays inline in Settings.tsx — it's an 8-line wrapper around UserManagementSection gated on ndAdminAuth, which Settings already owns for the tab-bar visibility check. The Settings.tsx import list drops 30+ names that only the extracted tabs used: many lucide icons, openDialog/saveDialog, openUrl, Trans, showToast, invoke, getImageCacheSize/clearImageCache, usePlayerStore, useOfflineStore, useHotCacheStore, useDragDrop, pingWithCredentials, scheduleInstantMixProbeForServer, switchActiveServer, formatBytes, snapHotCacheMb, MAINTAINERS, CONTRIBUTORS, LicensesPanel, AboutPsysonicBrandHeader, BackupSection, AddServerForm, ServerGripHandle, serverListDisplayLabel, showAudiomuseNavidromeServerSetting, shortHostFromServerUrl, ServerProfile, LoggingMode, LoudnessLufsPreset, appVersion, i18n, IS_LINUX/IS_WINDOWS, CustomSelect, SettingsSubSection, plus useMemo/useCallback/useLayoutEffect. Pure code move otherwise — no behaviour change. |