mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
b591a1cb5f
* 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.
43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
import { useEffect } from 'react';
|
|
|
|
/**
|
|
* Surface "is the app currently being looked at?" as two `<html>` data
|
|
* attributes so global CSS can pause cosmetic animations:
|
|
*
|
|
* - `data-app-hidden` mirrors `document.hidden` (browser/tab hidden).
|
|
* Tauri `win.hide()` is mirrored separately by Rust via
|
|
* `data-psy-native-hidden`, since WebView2 may keep compositing.
|
|
* - `data-app-blurred` mirrors `document.hasFocus()` (window loses OS
|
|
* focus but stays visible — alt-tab, click into another app). On
|
|
* low-VRAM laptops WebView2 keeps compositing mesh blobs / waveform
|
|
* / marquee at full rate while unfocused — see issue #334.
|
|
*
|
|
* `window.__psyBlurred` is set as a JS-readable mirror for hot-path code
|
|
* that can't go through the DOM (e.g. RAF loops).
|
|
*/
|
|
export function useAppActivityTracking(): void {
|
|
useEffect(() => {
|
|
const update = () => {
|
|
document.documentElement.dataset.appHidden = document.hidden ? 'true' : 'false';
|
|
};
|
|
document.addEventListener('visibilitychange', update);
|
|
update();
|
|
return () => document.removeEventListener('visibilitychange', update);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const update = () => {
|
|
const blurred = !document.hasFocus();
|
|
window.__psyBlurred = blurred;
|
|
document.documentElement.dataset.appBlurred = blurred ? 'true' : 'false';
|
|
};
|
|
window.addEventListener('focus', update);
|
|
window.addEventListener('blur', update);
|
|
update();
|
|
return () => {
|
|
window.removeEventListener('focus', update);
|
|
window.removeEventListener('blur', update);
|
|
};
|
|
}, []);
|
|
}
|