mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
383bbbd75f
* refactor(mini-player): H6 — extract helpers + constants
Pure code-move: window-size constants, localStorage keys + read helpers,
toMini track shape, initialSnapshot, and fmt(seconds) → utils/miniPlayerHelpers.ts.
MiniPlayer.tsx: 820 → 745 LOC.
* refactor(mini-player): H6 — extract MiniTitlebar + MiniMeta + MiniControls
Three small visual subcomponents move into components/miniPlayer/.
MiniPlayer drops the now-unused Pin/PinOff/Maximize2/X/Play/Pause/
SkipBack/SkipForward lucide icons and the CachedImage import.
MiniPlayer.tsx: 745 → 665 LOC.
* refactor(mini-player): H6 — extract MiniToolbar + useMiniVolumePopover
The whole toolbar (volume button + portaled popover, shuffle, gapless/
crossfade/infinite, queue toggle) moves into MiniToolbar.tsx. The volume
popover open-state + ref/style positioning + outside-click/Escape close
move into the useMiniVolumePopover hook.
MiniPlayer.tsx: 665 → 492 LOC.
* refactor(mini-player): H6 — extract MiniQueue + useMiniQueueDrag
The OverlayScrollArea + queue.map block moves into MiniQueue.tsx. The
PsyDnD wiring (drop-inside emits mini:reorder, drop-outside emits
mini:remove, reorder math collapsing same-position + adjusting for shift)
moves into the useMiniQueueDrag hook.
MiniPlayer.tsx: 492 → 346 LOC.
* refactor(mini-player): H6 — extract useMiniSync + useMiniWindowSetup + useMiniKeyboardShortcuts
Three more hooks pull the remaining side-effect islands out of MiniPlayer:
- useMiniSync owns mini:ready emit on mount + focus, plus the
mini:sync / audio:progress / audio:ended listeners. The hidden-window
visibility ref that gates progress now lives inside the hook.
- useMiniWindowSetup bundles three small window-bound effects:
Linux WebKitGTK smooth-scroll, the cold-start expanded-size restore
when queueOpen=true, and always-on-top reapply on mount + focus.
- useMiniKeyboardShortcuts moves the keyboard-shortcut bridge wiring.
MiniPlayer.tsx: 346 → 218 LOC.
69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
import { Maximize2, Pin, PinOff, X } from 'lucide-react';
|
|
import type { TFunction } from 'i18next';
|
|
import { IS_LINUX } from '../../utils/platform';
|
|
|
|
interface Props {
|
|
trackTitle: string | undefined;
|
|
alwaysOnTop: boolean;
|
|
toggleOnTop: () => void;
|
|
showMain: () => void;
|
|
closeMini: () => void;
|
|
t: TFunction;
|
|
}
|
|
|
|
export function MiniTitlebar({
|
|
trackTitle, alwaysOnTop, toggleOnTop, showMain, closeMini, t,
|
|
}: Props) {
|
|
return (
|
|
<div
|
|
className={`mini-player__titlebar${!IS_LINUX ? ' mini-player__titlebar--mac' : ''}`}
|
|
{...(!IS_LINUX ? {} : { 'data-tauri-drag-region': true })}
|
|
>
|
|
{IS_LINUX ? (
|
|
<span className="mini-player__titlebar-title" data-tauri-drag-region>
|
|
{trackTitle ?? 'Psysonic Mini'}
|
|
</span>
|
|
) : (
|
|
// macOS/Windows already render a native titlebar with the window
|
|
// title + close button; we just need a flexible spacer so the
|
|
// action buttons sit right.
|
|
<span className="mini-player__titlebar-spacer" />
|
|
)}
|
|
<button
|
|
type="button"
|
|
className={`mini-player__titlebar-btn${alwaysOnTop ? ' mini-player__titlebar-btn--active' : ''}`}
|
|
onClick={toggleOnTop}
|
|
data-tauri-drag-region="false"
|
|
data-tooltip={alwaysOnTop ? t('miniPlayer.pinOff') : t('miniPlayer.pinOnTop')}
|
|
aria-label={alwaysOnTop ? t('miniPlayer.pinOff') : t('miniPlayer.pinOnTop')}
|
|
>
|
|
{alwaysOnTop ? <Pin size={13} /> : <PinOff size={13} />}
|
|
</button>
|
|
<button
|
|
type="button"
|
|
className="mini-player__titlebar-btn"
|
|
onClick={showMain}
|
|
data-tauri-drag-region="false"
|
|
data-tooltip={t('miniPlayer.openMainWindow')}
|
|
aria-label={t('miniPlayer.openMainWindow')}
|
|
>
|
|
<Maximize2 size={13} />
|
|
</button>
|
|
{/* macOS + Windows already provide Close via the native titlebar —
|
|
skip the duplicate so the in-app titlebar stays minimal. */}
|
|
{IS_LINUX && (
|
|
<button
|
|
type="button"
|
|
className="mini-player__titlebar-btn mini-player__titlebar-btn--close"
|
|
onClick={closeMini}
|
|
data-tauri-drag-region="false"
|
|
data-tooltip={t('miniPlayer.close')}
|
|
aria-label={t('miniPlayer.close')}
|
|
>
|
|
<X size={13} />
|
|
</button>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|