refactor(tauri-bridge): split TauriEventBridge into per-concern hooks (#682)

Each Rust<->React bridge concern moves into its own hook under
hooks/tauriBridge/; TauriEventBridge just composes them:

- useZipDownloadBridge        download:zip:progress
- usePreviewBridge            audio:preview-* lifecycle
- useAudioDeviceBridge        audio:device-changed / -reset
- useCliBridge                full cli:* listener surface
- useTrayIconSync             tray-icon visibility
- useInAppKeybindings         configurable keydown chords
- useMediaAndWindowBridge     media keys, tray, shortcuts, close/force-quit
- usePlayerSnapshotPublisher  psysonic --info JSON snapshot

Pure code-move — event names, payloads, effect deps and cleanup all
verbatim. The MainApp call site is unchanged.
This commit is contained in:
Frank Stellmacher
2026-05-14 12:31:14 +02:00
committed by GitHub
parent b89b5d7c94
commit 1dd74f0fa1
9 changed files with 571 additions and 499 deletions
+21
View File
@@ -0,0 +1,21 @@
import { useEffect } from 'react';
import { listen } from '@tauri-apps/api/event';
import { usePreviewStore } from '../../store/previewStore';
/** Track-preview lifecycle: Rust audio engine emits start/progress/end. The
* store mirrors them so any tracklist row can render its preview UI. */
export function usePreviewBridge() {
useEffect(() => {
const unlistenFns: Array<() => void> = [];
listen<string>('audio:preview-start', e => {
usePreviewStore.getState()._onStart(e.payload);
}).then(u => unlistenFns.push(u));
listen<{ id: string; elapsed: number; duration: number }>('audio:preview-progress', e => {
usePreviewStore.getState()._onProgress(e.payload.id, e.payload.elapsed, e.payload.duration);
}).then(u => unlistenFns.push(u));
listen<{ id: string; reason: string }>('audio:preview-end', e => {
usePreviewStore.getState()._onEnd(e.payload.id);
}).then(u => unlistenFns.push(u));
return () => { unlistenFns.forEach(fn => fn()); };
}, []);
}