mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
e3aabd98b7
New /tracks route with three sections: - Hero "Track of the moment" — random pick with play / enqueue / reroll - Random Pick rail — 18 song cards, rerollable; hero song deduped - Browse all tracks — virtualized list (@tanstack/react-virtual), paginated 50 at a time Browse uses Navidrome's native /api/song?_sort=title&_order=ASC for proper A-Z order (no Subsonic equivalent), with automatic fallback to search3 on non-Navidrome servers. Search input drives search3 with 300ms debounce. Bearer token cached module-level, re-auth on 401. Play button on rows + cards calls a new enqueueAndPlay() helper that appends to the existing queue (skip if duplicate) and jumps to the song — different from playSongNow which replaces the queue. Enqueue button stays opaque (no hover-only). i18n keys for sidebar.tracks + tracks.* namespace in all 8 locales. New AudioLines sidebar icon. Sidebar entry inserted between "All Albums" and "Build a Mix". Performance: cover thumbnails dropped (uniform layout instead), RAF-throttled scroll prefetch, hover transforms removed from cards (WebKitGTK compositing-friendly). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
import { StrictMode } from 'react';
|
|
import ReactDOM from 'react-dom/client';
|
|
import { invoke } from '@tauri-apps/api/core';
|
|
import { getCurrentWindow } from '@tauri-apps/api/window';
|
|
import App from './App';
|
|
import './i18n';
|
|
import './styles/theme.css';
|
|
import './styles/layout.css';
|
|
import './styles/components.css';
|
|
import './styles/tracks.css';
|
|
|
|
// Expose the Tauri window label synchronously so App() can pick its root
|
|
// component (main app vs mini player) on first render without flicker.
|
|
try {
|
|
(window as any).__PSY_WINDOW_LABEL__ = getCurrentWindow().label;
|
|
} catch {
|
|
(window as any).__PSY_WINDOW_LABEL__ = 'main';
|
|
}
|
|
|
|
// Sync backend HTTP User-Agent from the main webview once at startup.
|
|
try {
|
|
const windowLabel = (window as any).__PSY_WINDOW_LABEL__ ?? 'main';
|
|
if (windowLabel === 'main') {
|
|
const ua = window.navigator.userAgent?.trim();
|
|
if (ua) {
|
|
void invoke('set_subsonic_wire_user_agent', { userAgent: ua, windowLabel });
|
|
}
|
|
}
|
|
} catch {
|
|
// Ignore in non-Tauri runtimes.
|
|
}
|
|
|
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
<StrictMode>
|
|
<App />
|
|
</StrictMode>
|
|
);
|