mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 06:25:41 +00:00
refactor(app-shell): I.1 — split AppShell.tsx 691 → 248 LOC across 12 files (#671)
* refactor(app-shell): extract appShellHelpers.ts
Move SIDEBAR_COLLAPSED_STORAGE_KEY + read/persist helpers and the
shouldSuppressQueueResizerMouseDown geometry helper out of AppShell.tsx
into utils/appShellHelpers.ts.
AppShell.tsx: 691 → 639 LOC.
* refactor(app-shell): extract usePlatformShellSetup hook
Bundle the one-shot platform/window-shell effects (tiling-WM detection,
no-compositing class, data-platform attr, custom titlebar sync, kinetic
scroll toggle, logging mode push) into hooks/usePlatformShellSetup.ts.
Returns isTilingWm so AppShell can still gate the custom titlebar.
AppShell.tsx: 639 → 604 LOC.
* refactor(app-shell): extract 5 lifecycle hooks
Pull these effect islands into hooks/:
- useOrbitBodyAttrs — orbit role/phase → <html data-orbit-*> attrs
- useWindowFullscreenState — Tauri isFullscreen() tracker
- useNowPlayingTrayTitle — title + tray tooltip sync
- useTrayMenuI18n — tray menu labels via i18n
- useServerCapabilitiesProbe — music folders + rating support + orbit
orphan sweep on login
AppShell.tsx: 604 → 497 LOC.
* refactor(app-shell): extract useQueueResizer hook
Bundle queueWidth state, drag listeners, sidebar-aligned handle position,
and the click-vs-drag mousedown handler into hooks/useQueueResizer.ts.
AppShell drops shouldSuppressQueueResizerMouseDown wiring and 4 local
state pieces.
AppShell.tsx: 497 → 403 LOC.
* refactor(app-shell): extract 4 misc lifecycle hooks
- useGlobalDndAndSelectionBlockers — document-level DnD/select-all/
selectstart blockers (Linux/WebKitGTK + Wayland workarounds).
- useAppActivityTracking — <html data-app-hidden> + <html data-app-blurred>
so CSS can pause cosmetic animation when the app isn't being looked at.
- useMainScrollingIndicator — scroll-idle tracker for main + np viewports.
- useOfflineAutoNav — connStatus transitions push to /offline or back.
AppShell.tsx: 403 → 282 LOC.
* refactor(app-shell): extract AppShellQueueResizerSeam subcomponent
The 6px resizer strip and the round resize/toggle handle (~50 LOC of JSX
with embedded scrollbar-collision suppression + self-heal logic) move
into components/AppShellQueueResizerSeam.tsx. Desktop-only.
AppShell.tsx: 282 → 248 LOC.
This commit is contained in:
committed by
GitHub
parent
988806e6b1
commit
b591a1cb5f
@@ -0,0 +1,81 @@
|
||||
import React from 'react';
|
||||
import type { TFunction } from 'i18next';
|
||||
import { PanelRight, PanelRightClose } from 'lucide-react';
|
||||
import { shouldSuppressQueueResizerMouseDown } from '../utils/appShellHelpers';
|
||||
|
||||
interface Props {
|
||||
isQueueVisible: boolean;
|
||||
queueWidth: number;
|
||||
queueHandleTop: number | null;
|
||||
isMainScrolling: boolean;
|
||||
setIsDraggingQueue: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
handleQueueHandleMouseDown: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
t: TFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* The seam between the main column and the queue panel — a 6px resizer
|
||||
* strip and the round resize/toggle handle floating over it. Desktop-only.
|
||||
*
|
||||
* The strip's mousedown is intentionally elaborate: it has to ignore
|
||||
* clicks aimed at the main viewport's overlay scrollbar thumb (which sits
|
||||
* inside the resizer's overlap region) and self-heal a stale
|
||||
* `is-overlay-scrollbar-thumb-drag` body flag if no thumb is actually
|
||||
* dragging. The handle is fixed-positioned and aligned with the sidebar's
|
||||
* collapse button so the two visually pair across resizes.
|
||||
*/
|
||||
export function AppShellQueueResizerSeam({
|
||||
isQueueVisible,
|
||||
queueWidth,
|
||||
queueHandleTop,
|
||||
isMainScrolling,
|
||||
setIsDraggingQueue,
|
||||
handleQueueHandleMouseDown,
|
||||
t,
|
||||
}: Props) {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="resizer resizer-queue"
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
if (document.body.classList.contains('is-overlay-scrollbar-thumb-drag')) {
|
||||
const activeThumbDrag = document.querySelector('.overlay-scroll__thumb.is-thumb-dragging');
|
||||
if (!activeThumbDrag) {
|
||||
document.body.classList.remove('is-overlay-scrollbar-thumb-drag');
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (shouldSuppressQueueResizerMouseDown(e.clientX, e.clientY, queueWidth)) return;
|
||||
setIsDraggingQueue(true);
|
||||
}}
|
||||
style={{
|
||||
display: isQueueVisible ? 'block' : 'none',
|
||||
right: `${Math.max(0, queueWidth - 3)}px`,
|
||||
}}
|
||||
/>
|
||||
{isQueueVisible && (
|
||||
<button
|
||||
type="button"
|
||||
className="resizer-queue-handle"
|
||||
onMouseDown={handleQueueHandleMouseDown}
|
||||
style={{
|
||||
position: 'fixed',
|
||||
top: queueHandleTop != null ? `${queueHandleTop}px` : '50%',
|
||||
right: `${Math.max(0, queueWidth - 11)}px`,
|
||||
transform: 'translateY(-50%)',
|
||||
zIndex: 101,
|
||||
opacity: isMainScrolling ? 0 : 1,
|
||||
pointerEvents: isMainScrolling ? 'none' : 'auto',
|
||||
}}
|
||||
data-tooltip={t('player.collapseQueueResize')}
|
||||
data-tooltip-pos="left"
|
||||
aria-label={t('player.collapseQueueResize')}
|
||||
>
|
||||
{isQueueVisible ? <PanelRightClose size={14} /> : <PanelRight size={14} />}
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user