mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
refactor(sidebar): co-locate sidebar feature into features/sidebar
This commit is contained in:
@@ -2,10 +2,10 @@ import { lazy } from 'react';
|
|||||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||||
import MobilePlayerView from '../components/MobilePlayerView';
|
import MobilePlayerView from '../components/MobilePlayerView';
|
||||||
import { useIsMobile } from '../hooks/useIsMobile';
|
import { useIsMobile } from '../hooks/useIsMobile';
|
||||||
import { useSidebarStore } from '../store/sidebarStore';
|
import { useSidebarStore } from '@/features/sidebar';
|
||||||
import { useAuthStore } from '../store/authStore';
|
import { useAuthStore } from '../store/authStore';
|
||||||
import { useLuckyMixAvailable } from '../hooks/useLuckyMixAvailable';
|
import { useLuckyMixAvailable } from '../hooks/useLuckyMixAvailable';
|
||||||
import { resolveStartRoute } from '../utils/componentHelpers/sidebarNavReorder';
|
import { resolveStartRoute } from '@/features/sidebar';
|
||||||
|
|
||||||
// Route-level lazy loading: keeps the non-page graph (shell, player, stores) in
|
// Route-level lazy loading: keeps the non-page graph (shell, player, stores) in
|
||||||
// the entry chunk; each page is fetched when its route is first visited.
|
// the entry chunk; each page is fetched when its route is first visited.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { navigatePathWithAlbumReturnTo, shouldSkipMainScrollResetOnRouteChange }
|
|||||||
import { getCurrentWebview } from '@tauri-apps/api/webview';
|
import { getCurrentWebview } from '@tauri-apps/api/webview';
|
||||||
import { PanelRight } from 'lucide-react';
|
import { PanelRight } from 'lucide-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import Sidebar from '../components/Sidebar';
|
import Sidebar from '@/features/sidebar';
|
||||||
import PlayerBar from '../components/PlayerBar';
|
import PlayerBar from '../components/PlayerBar';
|
||||||
import BottomNav from '../components/BottomNav';
|
import BottomNav from '../components/BottomNav';
|
||||||
import { useIsMobile } from '../hooks/useIsMobile';
|
import { useIsMobile } from '../hooks/useIsMobile';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { createPortal } from 'react-dom';
|
|||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Settings, HardDriveDownload } from 'lucide-react';
|
import { Settings, HardDriveDownload } from 'lucide-react';
|
||||||
import { useSidebarStore } from '../store/sidebarStore';
|
import { useSidebarStore } from '@/features/sidebar';
|
||||||
import { useAuthStore } from '../store/authStore';
|
import { useAuthStore } from '../store/authStore';
|
||||||
import { ALL_NAV_ITEMS } from '../config/navItems';
|
import { ALL_NAV_ITEMS } from '../config/navItems';
|
||||||
import { useLuckyMixAvailable } from '../hooks/useLuckyMixAvailable';
|
import { useLuckyMixAvailable } from '../hooks/useLuckyMixAvailable';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { useHomeStore } from '../../store/homeStore';
|
|||||||
import { usePlayerBarLayoutStore } from '../../store/playerBarLayoutStore';
|
import { usePlayerBarLayoutStore } from '../../store/playerBarLayoutStore';
|
||||||
import { usePlaylistLayoutStore } from '../../store/playlistLayoutStore';
|
import { usePlaylistLayoutStore } from '../../store/playlistLayoutStore';
|
||||||
import { useQueueToolbarStore } from '../../store/queueToolbarStore';
|
import { useQueueToolbarStore } from '../../store/queueToolbarStore';
|
||||||
import { useSidebarStore } from '../../store/sidebarStore';
|
import { useSidebarStore } from '@/features/sidebar';
|
||||||
import SettingsSubSection from '../SettingsSubSection';
|
import SettingsSubSection from '../SettingsSubSection';
|
||||||
import { SettingsGroup } from './SettingsGroup';
|
import { SettingsGroup } from './SettingsGroup';
|
||||||
import { SettingsToggle } from './SettingsToggle';
|
import { SettingsToggle } from './SettingsToggle';
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { useCallback, useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useAuthStore } from '../../store/authStore';
|
import { useAuthStore } from '../../store/authStore';
|
||||||
import { useSidebarStore, SidebarItemConfig, CONSERVED_SIDEBAR_NAV_IDS } from '../../store/sidebarStore';
|
import { useSidebarStore, SidebarItemConfig, CONSERVED_SIDEBAR_NAV_IDS } from '@/features/sidebar';
|
||||||
import { useLuckyMixAvailable } from '../../hooks/useLuckyMixAvailable';
|
import { useLuckyMixAvailable } from '../../hooks/useLuckyMixAvailable';
|
||||||
import { ALL_NAV_ITEMS } from '../../config/navItems';
|
import { ALL_NAV_ITEMS } from '../../config/navItems';
|
||||||
import { applySidebarReorderById } from '../../utils/componentHelpers/sidebarNavReorder';
|
import { applySidebarReorderById } from '@/features/sidebar';
|
||||||
import { useListReorderDnd } from '../../hooks/useListReorderDnd';
|
import { useListReorderDnd } from '../../hooks/useListReorderDnd';
|
||||||
import type { ListReorderDropTarget } from '../../utils/componentHelpers/listReorder';
|
import type { ListReorderDropTarget } from '../../utils/componentHelpers/listReorder';
|
||||||
import { ReorderGripHandle } from './ReorderGripHandle';
|
import { ReorderGripHandle } from './ReorderGripHandle';
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
import { useState, useRef, useEffect, useMemo } from 'react';
|
import { useState, useRef, useEffect, useMemo } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { usePlayerStore } from '../store/playerStore';
|
import { usePlayerStore } from '@/store/playerStore';
|
||||||
import { useOfflineJobStore } from '../store/offlineJobStore';
|
import { useOfflineJobStore } from '@/store/offlineJobStore';
|
||||||
import { clearOfflinePinTasks } from '../utils/offline/offlinePinQueue';
|
import { clearOfflinePinTasks } from '@/utils/offline/offlinePinQueue';
|
||||||
import { useDeviceSyncJobStore } from '@/features/deviceSync';
|
import { useDeviceSyncJobStore } from '@/features/deviceSync';
|
||||||
import { useAuthStore } from '../store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { useSidebarStore } from '../store/sidebarStore';
|
import { useSidebarStore } from '@/features/sidebar/store/sidebarStore';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PanelLeft, PanelLeftClose, Trash2 } from 'lucide-react';
|
import { PanelLeft, PanelLeftClose, Trash2 } from 'lucide-react';
|
||||||
import PsysonicLogo from './PsysonicLogo';
|
import PsysonicLogo from '@/components/PsysonicLogo';
|
||||||
import PSmallLogo from './PSmallLogo';
|
import PSmallLogo from '@/components/PSmallLogo';
|
||||||
import { usePlaylistStore } from '../store/playlistStore';
|
import { usePlaylistStore } from '@/store/playlistStore';
|
||||||
import OverlayScrollArea from '@/ui/OverlayScrollArea';
|
import OverlayScrollArea from '@/ui/OverlayScrollArea';
|
||||||
import {
|
import {
|
||||||
getLibraryItemsForReorder,
|
getLibraryItemsForReorder,
|
||||||
getSystemItemsForReorder,
|
getSystemItemsForReorder,
|
||||||
} from '../utils/componentHelpers/sidebarNavReorder';
|
} from '@/features/sidebar/utils/sidebarNavReorder';
|
||||||
import { useLuckyMixAvailable } from '../hooks/useLuckyMixAvailable';
|
import { useLuckyMixAvailable } from '@/hooks/useLuckyMixAvailable';
|
||||||
import { usePerfProbeFlags } from '../utils/perf/perfFlags';
|
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
|
||||||
import { useSidebarNewReleasesUnread } from '../hooks/useSidebarNewReleasesUnread';
|
import { useSidebarNewReleasesUnread } from '@/features/sidebar/hooks/useSidebarNewReleasesUnread';
|
||||||
import { useSidebarNavDnd } from '../hooks/useSidebarNavDnd';
|
import { useSidebarNavDnd } from '@/features/sidebar/hooks/useSidebarNavDnd';
|
||||||
import { useSidebarLibraryDropdown } from '../hooks/useSidebarLibraryDropdown';
|
import { useSidebarLibraryDropdown } from '@/features/sidebar/hooks/useSidebarLibraryDropdown';
|
||||||
import { useSidebarScrollVisible } from '../hooks/useSidebarScrollVisible';
|
import { useSidebarScrollVisible } from '@/features/sidebar/hooks/useSidebarScrollVisible';
|
||||||
import { isOfflineSidebarNavAllowed } from '../utils/offline/offlineNavPolicy';
|
import { isOfflineSidebarNavAllowed } from '@/utils/offline/offlineNavPolicy';
|
||||||
import { useOfflineBrowseContext } from '../hooks/useOfflineBrowseContext';
|
import { useOfflineBrowseContext } from '@/hooks/useOfflineBrowseContext';
|
||||||
import { offlineBrowseNavFlags } from '../utils/offline/offlineBrowseContext';
|
import { offlineBrowseNavFlags } from '@/utils/offline/offlineBrowseContext';
|
||||||
import { useSidebarPerfProbe } from '../hooks/useSidebarPerfProbe';
|
import { useSidebarPerfProbe } from '@/features/sidebar/hooks/useSidebarPerfProbe';
|
||||||
import SidebarPerfProbeModal from './sidebar/SidebarPerfProbeModal';
|
import SidebarPerfProbeModal from '@/features/sidebar/components/SidebarPerfProbeModal';
|
||||||
import SidebarNavBody from './sidebar/SidebarNavBody';
|
import SidebarNavBody from '@/features/sidebar/components/SidebarNavBody';
|
||||||
|
|
||||||
|
|
||||||
export default function Sidebar({
|
export default function Sidebar({
|
||||||
+7
-7
@@ -2,13 +2,13 @@ import React from 'react';
|
|||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { AudioLines, ChevronRight, HardDriveDownload, Settings } from 'lucide-react';
|
import { AudioLines, ChevronRight, HardDriveDownload, Settings } from 'lucide-react';
|
||||||
import type { SidebarItemConfig } from '../../store/sidebarStore';
|
import type { SidebarItemConfig } from '@/features/sidebar/store/sidebarStore';
|
||||||
import { ALL_NAV_ITEMS } from '../../config/navItems';
|
import { ALL_NAV_ITEMS } from '@/config/navItems';
|
||||||
import WhatsNewBanner from '../WhatsNewBanner';
|
import WhatsNewBanner from '@/components/WhatsNewBanner';
|
||||||
import ThemeUpdateBanner from '../ThemeUpdateBanner';
|
import ThemeUpdateBanner from '@/components/ThemeUpdateBanner';
|
||||||
import SidebarLibraryPicker from './SidebarLibraryPicker';
|
import SidebarLibraryPicker from '@/features/sidebar/components/SidebarLibraryPicker';
|
||||||
import SidebarPlaylistsSection from './SidebarPlaylistsSection';
|
import SidebarPlaylistsSection from '@/features/sidebar/components/SidebarPlaylistsSection';
|
||||||
import SidebarActiveJobs from './SidebarActiveJobs';
|
import SidebarActiveJobs from '@/features/sidebar/components/SidebarActiveJobs';
|
||||||
|
|
||||||
interface NavDndState {
|
interface NavDndState {
|
||||||
section: 'library' | 'system';
|
section: 'library' | 'system';
|
||||||
+9
-9
@@ -1,15 +1,15 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Activity, Network, ScrollText, SlidersHorizontal, Wrench, X } from 'lucide-react';
|
import { Activity, Network, ScrollText, SlidersHorizontal, Wrench, X } from 'lucide-react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import SidebarPerfProbeMonitorTab from './perfProbe/SidebarPerfProbeMonitorTab';
|
import SidebarPerfProbeMonitorTab from '@/features/sidebar/components/perfProbe/SidebarPerfProbeMonitorTab';
|
||||||
import SidebarPerfProbeTogglesTab from './perfProbe/SidebarPerfProbeTogglesTab';
|
import SidebarPerfProbeTogglesTab from '@/features/sidebar/components/perfProbe/SidebarPerfProbeTogglesTab';
|
||||||
import SidebarPerfProbeTuningTab from './perfProbe/SidebarPerfProbeTuningTab';
|
import SidebarPerfProbeTuningTab from '@/features/sidebar/components/perfProbe/SidebarPerfProbeTuningTab';
|
||||||
import SidebarPerfProbeLogsTab from './perfProbe/SidebarPerfProbeLogsTab';
|
import SidebarPerfProbeLogsTab from '@/features/sidebar/components/perfProbe/SidebarPerfProbeLogsTab';
|
||||||
import SidebarPerfProbeConnectionsTab from './perfProbe/SidebarPerfProbeConnectionsTab';
|
import SidebarPerfProbeConnectionsTab from '@/features/sidebar/components/perfProbe/SidebarPerfProbeConnectionsTab';
|
||||||
import { resetPerfProbeFlags, type PerfProbeFlags } from '../../utils/perf/perfFlags';
|
import { resetPerfProbeFlags, type PerfProbeFlags } from '@/utils/perf/perfFlags';
|
||||||
import { clearPerfLiveOverlayPins } from '../../utils/perf/perfOverlayPins';
|
import { clearPerfLiveOverlayPins } from '@/utils/perf/perfOverlayPins';
|
||||||
import { resetPerfOverlayAppearance } from '../../utils/perf/perfOverlayAppearance';
|
import { resetPerfOverlayAppearance } from '@/utils/perf/perfOverlayAppearance';
|
||||||
import { resetPerfOverlayMode } from '../../utils/perf/perfOverlayMode';
|
import { resetPerfOverlayMode } from '@/utils/perf/perfOverlayMode';
|
||||||
|
|
||||||
type TabId = 'monitor' | 'connections' | 'toggles' | 'tuning' | 'logs';
|
type TabId = 'monitor' | 'connections' | 'toggles' | 'tuning' | 'logs';
|
||||||
|
|
||||||
+6
-6
@@ -2,12 +2,12 @@ import React from 'react';
|
|||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ChevronRight, Folder, PlayCircle, Sparkles } from 'lucide-react';
|
import { ChevronRight, Folder, PlayCircle, Sparkles } from 'lucide-react';
|
||||||
import { displayPlaylistName, isSmartPlaylistName } from '../../utils/componentHelpers/sidebarHelpers';
|
import { displayPlaylistName, isSmartPlaylistName } from '@/features/sidebar/utils/sidebarHelpers';
|
||||||
import { useAuthStore } from '../../store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { usePlayerStore } from '../../store/playerStore';
|
import { usePlayerStore } from '@/store/playerStore';
|
||||||
import { usePlaylistStore } from '../../store/playlistStore';
|
import { usePlaylistStore } from '@/store/playlistStore';
|
||||||
import { EMPTY_SERVER_FOLDERS, usePlaylistFolderStore } from '../../store/playlistFolderStore';
|
import { EMPTY_SERVER_FOLDERS, usePlaylistFolderStore } from '@/store/playlistFolderStore';
|
||||||
import { groupPlaylistsByFolder } from '../../utils/playlist/playlistFolders';
|
import { groupPlaylistsByFolder } from '@/utils/playlist/playlistFolders';
|
||||||
|
|
||||||
interface SidebarPlaylist {
|
interface SidebarPlaylist {
|
||||||
id: string;
|
id: string;
|
||||||
+1
-1
@@ -4,7 +4,7 @@ import {
|
|||||||
libraryCoverBackfillResetCursor,
|
libraryCoverBackfillResetCursor,
|
||||||
libraryCoverBackfillRunFullPass,
|
libraryCoverBackfillRunFullPass,
|
||||||
libraryCoverBackfillSetParallel,
|
libraryCoverBackfillSetParallel,
|
||||||
} from '../../../api/coverCache';
|
} from '@/api/coverCache';
|
||||||
|
|
||||||
const COVER_THREADS_MIN = 1;
|
const COVER_THREADS_MIN = 1;
|
||||||
const COVER_THREADS_MAX = 16;
|
const COVER_THREADS_MAX = 16;
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
import { perfLiveCpuSnapshotSupported } from '../../../utils/perf/perfLiveCpuSnapshot';
|
import { perfLiveCpuSnapshotSupported } from '@/utils/perf/perfLiveCpuSnapshot';
|
||||||
import {
|
import {
|
||||||
PERF_LIVE_POLL_MS_MAX,
|
PERF_LIVE_POLL_MS_MAX,
|
||||||
PERF_LIVE_POLL_MS_MIN,
|
PERF_LIVE_POLL_MS_MIN,
|
||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
setPerfLivePollIntervalMs,
|
setPerfLivePollIntervalMs,
|
||||||
usePerfLiveIncludeThreadGroups,
|
usePerfLiveIncludeThreadGroups,
|
||||||
usePerfLivePollIntervalMs,
|
usePerfLivePollIntervalMs,
|
||||||
} from '../../../utils/perf/perfLivePollSettings';
|
} from '@/utils/perf/perfLivePollSettings';
|
||||||
|
|
||||||
export default function PerfLivePollControls() {
|
export default function PerfLivePollControls() {
|
||||||
const pollMs = usePerfLivePollIntervalMs();
|
const pollMs = usePerfLivePollIntervalMs();
|
||||||
+1
-1
@@ -3,7 +3,7 @@ import {
|
|||||||
setPerfOverlayCorner,
|
setPerfOverlayCorner,
|
||||||
setPerfOverlayOpacity,
|
setPerfOverlayOpacity,
|
||||||
usePerfOverlayAppearance,
|
usePerfOverlayAppearance,
|
||||||
} from '../../../utils/perf/perfOverlayAppearance';
|
} from '@/utils/perf/perfOverlayAppearance';
|
||||||
|
|
||||||
export default function PerfOverlayAppearanceControls() {
|
export default function PerfOverlayAppearanceControls() {
|
||||||
const { corner, opacity } = usePerfOverlayAppearance();
|
const { corner, opacity } = usePerfOverlayAppearance();
|
||||||
+1
-1
@@ -2,7 +2,7 @@ import {
|
|||||||
PERF_OVERLAY_MODE_OPTIONS,
|
PERF_OVERLAY_MODE_OPTIONS,
|
||||||
setPerfOverlayMode,
|
setPerfOverlayMode,
|
||||||
usePerfOverlayMode,
|
usePerfOverlayMode,
|
||||||
} from '../../../utils/perf/perfOverlayMode';
|
} from '@/utils/perf/perfOverlayMode';
|
||||||
|
|
||||||
export default function PerfOverlayModeControls() {
|
export default function PerfOverlayModeControls() {
|
||||||
const mode = usePerfOverlayMode();
|
const mode = usePerfOverlayMode();
|
||||||
+10
-10
@@ -1,13 +1,13 @@
|
|||||||
import { useAuthStore } from '../../../store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { usePlayerStore } from '../../../store/playerStore';
|
import { usePlayerStore } from '@/store/playerStore';
|
||||||
import { useConnectionStatus } from '../../../hooks/useConnectionStatus';
|
import { useConnectionStatus } from '@/hooks/useConnectionStatus';
|
||||||
import { useNavidromeAdminRole } from '../../../hooks/useNavidromeAdminRole';
|
import { useNavidromeAdminRole } from '@/hooks/useNavidromeAdminRole';
|
||||||
import { serverListDisplayLabel } from '../../../utils/server/serverDisplayName';
|
import { serverListDisplayLabel } from '@/utils/server/serverDisplayName';
|
||||||
import { findServerByIdOrIndexKey } from '../../../utils/server/serverLookup';
|
import { findServerByIdOrIndexKey } from '@/utils/server/serverLookup';
|
||||||
import { PerfProbeMetricSection } from './PerfProbeMetricCard';
|
import { PerfProbeMetricSection } from '@/features/sidebar/components/perfProbe/PerfProbeMetricCard';
|
||||||
import PerfProbeDetailList from './PerfProbeDetailList';
|
import PerfProbeDetailList from '@/features/sidebar/components/perfProbe/PerfProbeDetailList';
|
||||||
import PerfProbeStatusBadge, { type PerfProbeBadgeTone } from './PerfProbeStatusBadge';
|
import PerfProbeStatusBadge, { type PerfProbeBadgeTone } from '@/features/sidebar/components/perfProbe/PerfProbeStatusBadge';
|
||||||
import SidebarPerfProbeServerSection from './SidebarPerfProbeServerSection';
|
import SidebarPerfProbeServerSection from '@/features/sidebar/components/perfProbe/SidebarPerfProbeServerSection';
|
||||||
|
|
||||||
function connectionStatusBadge(status: string): { tone: PerfProbeBadgeTone; label: string } {
|
function connectionStatusBadge(status: string): { tone: PerfProbeBadgeTone; label: string } {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
+5
-5
@@ -11,13 +11,13 @@ import { Copy, Download, Pause, Play, Trash2 } from 'lucide-react';
|
|||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { save as saveDialog } from '@tauri-apps/plugin-dialog';
|
import { save as saveDialog } from '@tauri-apps/plugin-dialog';
|
||||||
import { writeFile } from '@tauri-apps/plugin-fs';
|
import { writeFile } from '@tauri-apps/plugin-fs';
|
||||||
import { getLoggingMode, tailRuntimeLogs, type RuntimeLogLine } from '../../../api/runtimeLogs';
|
import { getLoggingMode, tailRuntimeLogs, type RuntimeLogLine } from '@/api/runtimeLogs';
|
||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { useAuthStore } from '../../../store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import type { LoggingMode } from '../../../store/authStoreTypes';
|
import type { LoggingMode } from '@/store/authStoreTypes';
|
||||||
import CustomSelect from '@/ui/CustomSelect';
|
import CustomSelect from '@/ui/CustomSelect';
|
||||||
import { filterLogLines } from '../../../utils/perf/filterLogLines';
|
import { filterLogLines } from '@/utils/perf/filterLogLines';
|
||||||
import { sanitizeLogLine } from '../../../utils/perf/sanitizeLogLine';
|
import { sanitizeLogLine } from '@/utils/perf/sanitizeLogLine';
|
||||||
|
|
||||||
function formatLogLinesText(lines: RuntimeLogLine[]): string {
|
function formatLogLinesText(lines: RuntimeLogLine[]): string {
|
||||||
return lines.map(line => line.text).join('\n');
|
return lines.map(line => line.text).join('\n');
|
||||||
+7
-7
@@ -1,17 +1,17 @@
|
|||||||
import { useMemo, useRef } from 'react';
|
import { useMemo, useRef } from 'react';
|
||||||
import { isPerfLivePollWaitingForCpu, usePerfLiveSnapshot } from '../../../utils/perf/perfLiveStore';
|
import { isPerfLivePollWaitingForCpu, usePerfLiveSnapshot } from '@/utils/perf/perfLiveStore';
|
||||||
import { usePerfLiveIncludeThreadGroups } from '../../../utils/perf/perfLivePollSettings';
|
import { usePerfLiveIncludeThreadGroups } from '@/utils/perf/perfLivePollSettings';
|
||||||
import {
|
import {
|
||||||
togglePerfLiveOverlayPin,
|
togglePerfLiveOverlayPin,
|
||||||
togglePipelineOverlayPin,
|
togglePipelineOverlayPin,
|
||||||
usePerfLiveOverlayPins,
|
usePerfLiveOverlayPins,
|
||||||
usePipelineOverlayPinned,
|
usePipelineOverlayPinned,
|
||||||
type PerfLiveOverlayPinId,
|
type PerfLiveOverlayPinId,
|
||||||
} from '../../../utils/perf/perfOverlayPins';
|
} from '@/utils/perf/perfOverlayPins';
|
||||||
import PerfProbeMetricCard, { PerfProbeMetricSection } from './PerfProbeMetricCard';
|
import PerfProbeMetricCard, { PerfProbeMetricSection } from '@/features/sidebar/components/perfProbe/PerfProbeMetricCard';
|
||||||
import PerfOverlayAppearanceControls from './PerfOverlayAppearanceControls';
|
import PerfOverlayAppearanceControls from '@/features/sidebar/components/perfProbe/PerfOverlayAppearanceControls';
|
||||||
import PerfOverlayModeControls from './PerfOverlayModeControls';
|
import PerfOverlayModeControls from '@/features/sidebar/components/perfProbe/PerfOverlayModeControls';
|
||||||
import PerfLivePollControls from './PerfLivePollControls';
|
import PerfLivePollControls from '@/features/sidebar/components/perfProbe/PerfLivePollControls';
|
||||||
|
|
||||||
function memoryBarPct(rssKb: number, maxKb: number): number {
|
function memoryBarPct(rssKb: number, maxKb: number): number {
|
||||||
if (maxKb <= 0) return 0;
|
if (maxKb <= 0) return 0;
|
||||||
+9
-9
@@ -1,16 +1,16 @@
|
|||||||
import { useAuthStore } from '../../../store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import type { NavidromeAdminRole } from '../../../hooks/useNavidromeAdminRole';
|
import type { NavidromeAdminRole } from '@/hooks/useNavidromeAdminRole';
|
||||||
import { isNavidromeServer, formatServerSoftware } from '../../../utils/server/subsonicServerIdentity';
|
import { isNavidromeServer, formatServerSoftware } from '@/utils/server/subsonicServerIdentity';
|
||||||
import { FEATURE_AUDIOMUSE_SIMILAR_TRACKS, OP_SIMILAR_TRACKS } from '../../../serverCapabilities/catalog';
|
import { FEATURE_AUDIOMUSE_SIMILAR_TRACKS, OP_SIMILAR_TRACKS } from '@/serverCapabilities/catalog';
|
||||||
import {
|
import {
|
||||||
isFeatureActiveForServer,
|
isFeatureActiveForServer,
|
||||||
resolveCallRoutesForServer,
|
resolveCallRoutesForServer,
|
||||||
resolveFeatureForServer,
|
resolveFeatureForServer,
|
||||||
} from '../../../serverCapabilities/storeView';
|
} from '@/serverCapabilities/storeView';
|
||||||
import type { CapabilityStatus, FeatureTrust, ResolvedCapability } from '../../../serverCapabilities/types';
|
import type { CapabilityStatus, FeatureTrust, ResolvedCapability } from '@/serverCapabilities/types';
|
||||||
import { PerfProbeMetricSection } from './PerfProbeMetricCard';
|
import { PerfProbeMetricSection } from '@/features/sidebar/components/perfProbe/PerfProbeMetricCard';
|
||||||
import PerfProbeDetailList, { type PerfProbeDetailRow } from './PerfProbeDetailList';
|
import PerfProbeDetailList, { type PerfProbeDetailRow } from '@/features/sidebar/components/perfProbe/PerfProbeDetailList';
|
||||||
import PerfProbeStatusBadge, { type PerfProbeBadgeTone } from './PerfProbeStatusBadge';
|
import PerfProbeStatusBadge, { type PerfProbeBadgeTone } from '@/features/sidebar/components/perfProbe/PerfProbeStatusBadge';
|
||||||
|
|
||||||
function detectionBadge(status: CapabilityStatus): { tone: PerfProbeBadgeTone; label: string } {
|
function detectionBadge(status: CapabilityStatus): { tone: PerfProbeBadgeTone; label: string } {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
+3
-3
@@ -1,12 +1,12 @@
|
|||||||
import { useState, type CSSProperties } from 'react';
|
import { useState, type CSSProperties } from 'react';
|
||||||
import { ChevronRight } from 'lucide-react';
|
import { ChevronRight } from 'lucide-react';
|
||||||
import { setPerfProbeFlag, type PerfProbeFlags } from '../../../utils/perf/perfFlags';
|
import { setPerfProbeFlag, type PerfProbeFlags } from '@/utils/perf/perfFlags';
|
||||||
import type { PerfToggleEngineLeaf, PerfToggleLeaf, PerfToggleNode } from '../../../utils/perf/perfProbeToggleTree';
|
import type { PerfToggleEngineLeaf, PerfToggleLeaf, PerfToggleNode } from '@/utils/perf/perfProbeToggleTree';
|
||||||
import {
|
import {
|
||||||
isPerfToggleEngineLeaf,
|
isPerfToggleEngineLeaf,
|
||||||
isPerfToggleGroup,
|
isPerfToggleGroup,
|
||||||
PERF_PROBE_TOGGLE_TREE,
|
PERF_PROBE_TOGGLE_TREE,
|
||||||
} from '../../../utils/perf/perfProbeToggleTree';
|
} from '@/utils/perf/perfProbeToggleTree';
|
||||||
|
|
||||||
interface EngineProps {
|
interface EngineProps {
|
||||||
hotCacheEnabled: boolean;
|
hotCacheEnabled: boolean;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import PerfCoverThreadsControl from './PerfCoverThreadsControl';
|
import PerfCoverThreadsControl from '@/features/sidebar/components/perfProbe/PerfCoverThreadsControl';
|
||||||
|
|
||||||
export default function SidebarPerfProbeTuningTab() {
|
export default function SidebarPerfProbeTuningTab() {
|
||||||
return (
|
return (
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import type { SidebarItemConfig } from '../store/sidebarStore';
|
import type { SidebarItemConfig } from '@/features/sidebar/store/sidebarStore';
|
||||||
import {
|
import {
|
||||||
applySidebarReorderById,
|
applySidebarReorderById,
|
||||||
isSidebarNavItemUserHideable,
|
isSidebarNavItemUserHideable,
|
||||||
type SidebarNavDropTarget,
|
type SidebarNavDropTarget,
|
||||||
} from '../utils/componentHelpers/sidebarNavReorder';
|
} from '@/features/sidebar/utils/sidebarNavReorder';
|
||||||
import {
|
import {
|
||||||
SIDEBAR_NAV_LONG_PRESS_MOVE_CANCEL_PX,
|
SIDEBAR_NAV_LONG_PRESS_MOVE_CANCEL_PX,
|
||||||
SIDEBAR_NAV_LONG_PRESS_MS,
|
SIDEBAR_NAV_LONG_PRESS_MS,
|
||||||
isPointerOutsideAsideSidebar,
|
isPointerOutsideAsideSidebar,
|
||||||
} from '../utils/componentHelpers/sidebarHelpers';
|
} from '@/features/sidebar/utils/sidebarHelpers';
|
||||||
|
|
||||||
interface NavDndState {
|
interface NavDndState {
|
||||||
section: 'library' | 'system';
|
section: 'library' | 'system';
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { getAlbumList } from '../api/subsonicLibrary';
|
import { getAlbumList } from '@/api/subsonicLibrary';
|
||||||
import { isActiveServerReachable } from '../utils/network/activeServerReachability';
|
import { isActiveServerReachable } from '@/utils/network/activeServerReachability';
|
||||||
import {
|
import {
|
||||||
NEW_RELEASES_RESET_DELAY_MS,
|
NEW_RELEASES_RESET_DELAY_MS,
|
||||||
NEW_RELEASES_SEEN_MAX_IDS,
|
NEW_RELEASES_SEEN_MAX_IDS,
|
||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
NEW_RELEASES_UNREAD_SAMPLE_SIZE,
|
NEW_RELEASES_UNREAD_SAMPLE_SIZE,
|
||||||
NEW_RELEASES_UNREAD_STORAGE_PREFIX,
|
NEW_RELEASES_UNREAD_STORAGE_PREFIX,
|
||||||
mergeSeenNewReleaseIdsCap,
|
mergeSeenNewReleaseIdsCap,
|
||||||
} from '../utils/componentHelpers/sidebarHelpers';
|
} from '@/features/sidebar/utils/sidebarHelpers';
|
||||||
|
|
||||||
interface Args {
|
interface Args {
|
||||||
serverId: string;
|
serverId: string;
|
||||||
+7
-7
@@ -1,14 +1,14 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { acquirePerfLivePoll, patchPerfLiveAnalysis } from '../utils/perf/perfLiveStore';
|
import { acquirePerfLivePoll, patchPerfLiveAnalysis } from '@/utils/perf/perfLiveStore';
|
||||||
import { setPerfProbeTelemetryActive } from '../utils/perf/perfTelemetry';
|
import { setPerfProbeTelemetryActive } from '@/utils/perf/perfTelemetry';
|
||||||
import { useAnalysisPerfLast } from '../utils/perf/analysisPerfStore';
|
import { useAnalysisPerfLast } from '@/utils/perf/analysisPerfStore';
|
||||||
import { useAnalysisPerfListener } from './useAnalysisPerfListener';
|
import { useAnalysisPerfListener } from '@/hooks/useAnalysisPerfListener';
|
||||||
import { useCoverPerfListener, useCoverUiThroughputPoll } from './useCoverPerfListener';
|
import { useCoverPerfListener, useCoverUiThroughputPoll } from '@/hooks/useCoverPerfListener';
|
||||||
import {
|
import {
|
||||||
getPerfProbeFlags,
|
getPerfProbeFlags,
|
||||||
subscribePerfProbeFlags,
|
subscribePerfProbeFlags,
|
||||||
} from '../utils/perf/perfFlags';
|
} from '@/utils/perf/perfFlags';
|
||||||
import { hasAnyLiveMetricPollNeed, usePerfLiveOverlayPins } from '../utils/perf/perfOverlayPins';
|
import { hasAnyLiveMetricPollNeed, usePerfLiveOverlayPins } from '@/utils/perf/perfOverlayPins';
|
||||||
import { useSyncExternalStore } from 'react';
|
import { useSyncExternalStore } from 'react';
|
||||||
|
|
||||||
interface Result {
|
interface Result {
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Sidebar feature — the primary nav sidebar (library/system nav, playlists
|
||||||
|
* section, library picker, active jobs) plus its nav config store, reorder
|
||||||
|
* helpers, and the in-sidebar performance-probe overlay (Ctrl+Shift+P).
|
||||||
|
*/
|
||||||
|
export { default } from './components/Sidebar';
|
||||||
|
export { useSidebarStore, CONSERVED_SIDEBAR_NAV_IDS } from './store/sidebarStore';
|
||||||
|
export type { SidebarItemConfig } from './store/sidebarStore';
|
||||||
|
export { applySidebarReorderById, resolveStartRoute } from './utils/sidebarNavReorder';
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
import { applySidebarReorderById, resolveStartRoute } from './sidebarNavReorder';
|
import { applySidebarReorderById, resolveStartRoute } from '@/features/sidebar/utils/sidebarNavReorder';
|
||||||
import { DEFAULT_SIDEBAR_ITEMS, type SidebarItemConfig } from '../../store/sidebarStore';
|
import { DEFAULT_SIDEBAR_ITEMS, type SidebarItemConfig } from '@/features/sidebar/store/sidebarStore';
|
||||||
|
|
||||||
const hide = (items: SidebarItemConfig[], ...ids: string[]): SidebarItemConfig[] =>
|
const hide = (items: SidebarItemConfig[], ...ids: string[]): SidebarItemConfig[] =>
|
||||||
items.map(i => (ids.includes(i.id) ? { ...i, visible: false } : i));
|
items.map(i => (ids.includes(i.id) ? { ...i, visible: false } : i));
|
||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
import { ALL_NAV_ITEMS } from '../../config/navItems';
|
import { ALL_NAV_ITEMS } from '@/config/navItems';
|
||||||
import { CONSERVED_SIDEBAR_NAV_IDS, type SidebarItemConfig } from '../../store/sidebarStore';
|
import { CONSERVED_SIDEBAR_NAV_IDS, type SidebarItemConfig } from '@/features/sidebar/store/sidebarStore';
|
||||||
import { applyListReorderById, type ListReorderDropTarget } from './listReorder';
|
import { applyListReorderById, type ListReorderDropTarget } from '@/utils/componentHelpers/listReorder';
|
||||||
|
|
||||||
export type SidebarNavSection = 'library' | 'system';
|
export type SidebarNavSection = 'library' | 'system';
|
||||||
|
|
||||||
Reference in New Issue
Block a user