mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
refactor(miniPlayer): co-locate mini player feature into features/miniPlayer
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@ import { initPinnedOfflineSync } from '../utils/offline/pinnedOfflineSync';
|
||||
import { initResumeIncompleteOfflinePins, scheduleResumeIncompleteOfflinePins } from '../utils/offline/resumeIncompleteOfflinePins';
|
||||
import { runLegacyOfflineFileMigration } from '../utils/migrations/legacyOfflineFileMigration';
|
||||
import { reconcileLibraryTierForServer } from '../utils/offline/libraryTierReconcile';
|
||||
import { initMiniPlayerBridgeOnMain } from '../utils/miniPlayerBridge';
|
||||
import { initMiniPlayerBridgeOnMain } from '@/features/miniPlayer';
|
||||
import { runAdvancedModeMigration } from '../utils/migrations/advancedModeMigration';
|
||||
import { bootstrapAllIndexedServers } from '../utils/library/librarySession';
|
||||
import { hydrateQueueFromIndex } from '../utils/library/queueRestore';
|
||||
|
||||
@@ -28,7 +28,7 @@ vi.mock('../utils/perf/perfFlags', () => ({
|
||||
vi.mock('../i18n', () => ({
|
||||
default: { changeLanguage: vi.fn() },
|
||||
}));
|
||||
vi.mock('../components/MiniPlayer', () => ({ default: () => <div data-testid="mini-player" /> }));
|
||||
vi.mock('@/features/miniPlayer', () => ({ default: () => <div data-testid="mini-player" /> }));
|
||||
vi.mock('../components/GlobalConfirmModal', () => ({ default: () => <div data-testid="confirm-modal" /> }));
|
||||
vi.mock('@/ui/TooltipPortal', () => ({ default: () => <div data-testid="tooltip-portal" /> }));
|
||||
vi.mock('../components/FpsOverlay', () => ({ default: () => <div data-testid="fps-overlay" /> }));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import { DragDropProvider } from '../contexts/DragDropContext';
|
||||
import MiniPlayer from '../components/MiniPlayer';
|
||||
import MiniPlayer from '@/features/miniPlayer';
|
||||
import GlobalConfirmModal from '../components/GlobalConfirmModal';
|
||||
import TooltipPortal from '@/ui/TooltipPortal';
|
||||
import FpsOverlay from '../components/FpsOverlay';
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { star, unstar } from '../api/subsonicStarRating';
|
||||
import { star, unstar } from '@/api/subsonicStarRating';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { emit } from '@tauri-apps/api/event';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Play, Trash2, Disc3, User, Heart, Info } from 'lucide-react';
|
||||
import type { MiniTrackInfo } from '../utils/miniPlayerBridge';
|
||||
import type { MiniTrackInfo } from '@/features/miniPlayer/utils/miniPlayerBridge';
|
||||
|
||||
interface Props {
|
||||
x: number;
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import { Pause, Play, SkipBack, SkipForward } from 'lucide-react';
|
||||
import { formatTrackTime } from '../../utils/format/formatDuration';
|
||||
import type { MiniControlAction } from '../../utils/miniPlayerBridge';
|
||||
import { formatTrackTime } from '@/utils/format/formatDuration';
|
||||
import type { MiniControlAction } from '@/features/miniPlayer/utils/miniPlayerBridge';
|
||||
|
||||
interface Props {
|
||||
isPlaying: boolean;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { emit } from '@tauri-apps/api/event';
|
||||
import CachedImage from '@/ui/CachedImage';
|
||||
import { OpenArtistRefInline } from '../OpenArtistRefInline';
|
||||
import type { MiniTrackInfo } from '../../utils/miniPlayerBridge';
|
||||
import { OpenArtistRefInline } from '@/components/OpenArtistRefInline';
|
||||
import type { MiniTrackInfo } from '@/features/miniPlayer/utils/miniPlayerBridge';
|
||||
|
||||
interface Props {
|
||||
track: MiniTrackInfo | null;
|
||||
@@ -1,29 +1,29 @@
|
||||
import { usePlaybackCoverArt } from '../hooks/usePlaybackCoverArt';
|
||||
import { usePlaybackTrackCoverRef } from '../cover/useLibraryCoverRef';
|
||||
import { usePlaybackCoverArt } from '@/hooks/usePlaybackCoverArt';
|
||||
import { usePlaybackTrackCoverRef } from '@/cover/useLibraryCoverRef';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { emit } from '@tauri-apps/api/event';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { usePlayerStore } from '../store/playerStore';
|
||||
import { registerQueueDragHitTest } from '../contexts/DragDropContext';
|
||||
import MiniContextMenu from './MiniContextMenu';
|
||||
import type { MiniSyncPayload, MiniControlAction, MiniTrackInfo } from '../utils/miniPlayerBridge';
|
||||
import { usePlayerStore } from '@/store/playerStore';
|
||||
import { registerQueueDragHitTest } from '@/contexts/DragDropContext';
|
||||
import MiniContextMenu from '@/features/miniPlayer/components/MiniContextMenu';
|
||||
import type { MiniSyncPayload, MiniControlAction, MiniTrackInfo } from '@/features/miniPlayer/utils/miniPlayerBridge';
|
||||
import {
|
||||
COLLAPSED_SIZE, EXPANDED_SIZE, COLLAPSED_MIN, EXPANDED_MIN,
|
||||
EXPANDED_H_KEY, QUEUE_OPEN_KEY,
|
||||
readStoredExpandedHeight, readQueueOpen, initialSnapshot,
|
||||
} from '../utils/componentHelpers/miniPlayerHelpers';
|
||||
import { MiniTitlebar } from './miniPlayer/MiniTitlebar';
|
||||
import { MiniMeta } from './miniPlayer/MiniMeta';
|
||||
import { MiniControls } from './miniPlayer/MiniControls';
|
||||
import { MiniToolbar } from './miniPlayer/MiniToolbar';
|
||||
import { MiniQueue } from './miniPlayer/MiniQueue';
|
||||
import { useMiniVolumePopover } from '../hooks/useMiniVolumePopover';
|
||||
import { useMiniCrossfadePopover } from '../hooks/useMiniCrossfadePopover';
|
||||
import { useMiniQueueDrag } from '../hooks/useMiniQueueDrag';
|
||||
import { useMiniSync } from '../hooks/useMiniSync';
|
||||
import { useMiniWindowSetup } from '../hooks/useMiniWindowSetup';
|
||||
import { useMiniKeyboardShortcuts } from '../hooks/useMiniKeyboardShortcuts';
|
||||
} from '@/features/miniPlayer/utils/miniPlayerHelpers';
|
||||
import { MiniTitlebar } from '@/features/miniPlayer/components/MiniTitlebar';
|
||||
import { MiniMeta } from '@/features/miniPlayer/components/MiniMeta';
|
||||
import { MiniControls } from '@/features/miniPlayer/components/MiniControls';
|
||||
import { MiniToolbar } from '@/features/miniPlayer/components/MiniToolbar';
|
||||
import { MiniQueue } from '@/features/miniPlayer/components/MiniQueue';
|
||||
import { useMiniVolumePopover } from '@/features/miniPlayer/hooks/useMiniVolumePopover';
|
||||
import { useMiniCrossfadePopover } from '@/features/miniPlayer/hooks/useMiniCrossfadePopover';
|
||||
import { useMiniQueueDrag } from '@/features/miniPlayer/hooks/useMiniQueueDrag';
|
||||
import { useMiniSync } from '@/features/miniPlayer/hooks/useMiniSync';
|
||||
import { useMiniWindowSetup } from '@/features/miniPlayer/hooks/useMiniWindowSetup';
|
||||
import { useMiniKeyboardShortcuts } from '@/features/miniPlayer/hooks/useMiniKeyboardShortcuts';
|
||||
|
||||
export default function MiniPlayer() {
|
||||
const { t } = useTranslation();
|
||||
+1
-1
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import type { TFunction } from 'i18next';
|
||||
import OverlayScrollArea from '@/ui/OverlayScrollArea';
|
||||
import type { MiniSyncPayload, MiniTrackInfo } from '../../utils/miniPlayerBridge';
|
||||
import type { MiniSyncPayload, MiniTrackInfo } from '@/features/miniPlayer/utils/miniPlayerBridge';
|
||||
|
||||
// Stable initial rect so the virtualizer never re-initializes on re-render (an
|
||||
// inline literal would be a new ref each render → render loop). Replaced by the
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { Maximize2, Pin, PinOff, X } from 'lucide-react';
|
||||
import type { TFunction } from 'i18next';
|
||||
import { IS_LINUX } from '../../utils/platform';
|
||||
import { IS_LINUX } from '@/utils/platform';
|
||||
|
||||
interface Props {
|
||||
trackTitle: string | undefined;
|
||||
+2
-2
@@ -3,8 +3,8 @@ import { createPortal } from 'react-dom';
|
||||
import { emit } from '@tauri-apps/api/event';
|
||||
import { Blend, Infinity as InfinityIcon, ListMusic, MoveRight, Shuffle, Volume2, VolumeX, Waves } from 'lucide-react';
|
||||
import type { TFunction } from 'i18next';
|
||||
import type { MiniSyncPayload } from '../../utils/miniPlayerBridge';
|
||||
import { getTransitionMode } from '../../utils/playback/playbackTransition';
|
||||
import type { MiniSyncPayload } from '@/features/miniPlayer/utils/miniPlayerBridge';
|
||||
import { getTransitionMode } from '@/utils/playback/playbackTransition';
|
||||
|
||||
interface Props {
|
||||
state: MiniSyncPayload;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { useMiniAnchoredPopover } from './useMiniAnchoredPopover';
|
||||
import { useMiniAnchoredPopover } from '@/features/miniPlayer/hooks/useMiniAnchoredPopover';
|
||||
|
||||
/** Open-state, refs, and fixed positioning of the portaled mini-player
|
||||
* crossfade settings popover (seconds slider + trim-silence toggle). Opened by
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import { emit } from '@tauri-apps/api/event';
|
||||
import { useKeybindingsStore, matchInAppBinding } from '../store/keybindingsStore';
|
||||
import { useKeybindingsStore, matchInAppBinding } from '@/store/keybindingsStore';
|
||||
|
||||
/** Mini-window keyboard shortcuts. Space/Arrow{Left,Right} run the standard
|
||||
* play-pause/next/prev shortcut actions (source: 'mini-window' so the bridge
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { emit } from '@tauri-apps/api/event';
|
||||
import { useDragDrop } from '../contexts/DragDropContext';
|
||||
import { usePlayerStore } from '../store/playerStore';
|
||||
import { useDragDrop } from '@/contexts/DragDropContext';
|
||||
import { usePlayerStore } from '@/store/playerStore';
|
||||
|
||||
interface Args {
|
||||
queueOpen: boolean;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { emit, listen } from '@tauri-apps/api/event';
|
||||
import { useWindowVisibility } from './useWindowVisibility';
|
||||
import type { MiniSyncPayload } from '../utils/miniPlayerBridge';
|
||||
import { useWindowVisibility } from '@/hooks/useWindowVisibility';
|
||||
import type { MiniSyncPayload } from '@/features/miniPlayer/utils/miniPlayerBridge';
|
||||
|
||||
interface ProgressPayload {
|
||||
current_time: number;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { useMiniAnchoredPopover } from './useMiniAnchoredPopover';
|
||||
import { useMiniAnchoredPopover } from '@/features/miniPlayer/hooks/useMiniAnchoredPopover';
|
||||
|
||||
/** Open-state, refs, and fixed positioning of the portaled mini-player volume
|
||||
* popover. Thin wrapper over {@link useMiniAnchoredPopover} that preserves the
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
import { useEffect } from 'react';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { IS_LINUX } from '../utils/platform';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { IS_LINUX } from '@/utils/platform';
|
||||
import {
|
||||
EXPANDED_SIZE, EXPANDED_MIN, readStoredExpandedHeight,
|
||||
} from '../utils/componentHelpers/miniPlayerHelpers';
|
||||
} from '@/features/miniPlayer/utils/miniPlayerHelpers';
|
||||
|
||||
/** Three window-bound setup effects bundled together:
|
||||
* - Linux WebKitGTK smooth-scroll per-window (re-applies after auth hydrates
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Mini player feature — the compact always-on-top mini-player window UI
|
||||
* (controls, meta, queue, titlebar, toolbar, context menu) plus the main↔mini
|
||||
* IPC bridge. The webview entry shell (`app/MiniPlayerApp`) stays in `app/` and
|
||||
* renders this feature's default export.
|
||||
*/
|
||||
export { default } from './components/MiniPlayer';
|
||||
export { initMiniPlayerBridgeOnMain } from './utils/miniPlayerBridge';
|
||||
@@ -1,11 +1,11 @@
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window';
|
||||
import { listen, emitTo } from '@tauri-apps/api/event';
|
||||
import { usePlayerStore } from '../store/playerStore';
|
||||
import { useAuthStore } from '../store/authStore';
|
||||
import { setTransitionMode, type TransitionMode } from './playback/playbackTransition';
|
||||
import { resolveQueueTrack } from './library/queueTrackView';
|
||||
import type { SubsonicOpenArtistRef } from '../api/subsonicTypes';
|
||||
import type { Track } from '../store/playerStoreTypes';
|
||||
import { usePlayerStore } from '@/store/playerStore';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
import { setTransitionMode, type TransitionMode } from '@/utils/playback/playbackTransition';
|
||||
import { resolveQueueTrack } from '@/utils/library/queueTrackView';
|
||||
import type { SubsonicOpenArtistRef } from '@/api/subsonicTypes';
|
||||
import type { Track } from '@/store/playerStoreTypes';
|
||||
|
||||
export const MINI_WINDOW_LABEL = 'mini';
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
import { usePlayerStore } from '../../store/playerStore';
|
||||
import { resolveQueueTrack } from '../library/queueTrackView';
|
||||
import type { MiniSyncPayload, MiniTrackInfo } from '../miniPlayerBridge';
|
||||
import type { Track } from '../../store/playerStoreTypes';
|
||||
import { usePlayerStore } from '@/store/playerStore';
|
||||
import { resolveQueueTrack } from '@/utils/library/queueTrackView';
|
||||
import type { MiniSyncPayload, MiniTrackInfo } from '@/features/miniPlayer/utils/miniPlayerBridge';
|
||||
import type { Track } from '@/store/playerStoreTypes';
|
||||
|
||||
/** Half-width of the mini initial-snapshot queue window (matches the bridge). */
|
||||
const MINI_SNAPSHOT_HALF = 100;
|
||||
Reference in New Issue
Block a user