refactor(hooks): move generic scroll/pagination/dnd UI hooks into lib/hooks

This commit is contained in:
Psychotoxical
2026-06-30 19:34:28 +02:00
parent 31bc24a178
commit 1f93984482
28 changed files with 41 additions and 41 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ import { usePrefetchReleaseNotes } from '../hooks/usePrefetchReleaseNotes';
import { useTrayMenuI18n } from '../hooks/useTrayMenuI18n';
import { useServerCapabilitiesProbe } from '../hooks/useServerCapabilitiesProbe';
import { useQueueResizer } from '@/features/queue';
import { useGlobalDndAndSelectionBlockers } from '../hooks/useGlobalDndAndSelectionBlockers';
import { useGlobalDndAndSelectionBlockers } from '@/lib/hooks/useGlobalDndAndSelectionBlockers';
import { useAppActivityTracking } from '../hooks/useAppActivityTracking';
import { useMainScrollingIndicator } from '../hooks/useMainScrollingIndicator';
import { useCoverNavigationPriority } from '../hooks/useCoverNavigationPriority';
@@ -37,9 +37,9 @@ import {
mergeAlbumCatalogChunk,
} from '@/features/album/utils/albumBrowseCatalogChunk';
import { useOfflineBrowseContext } from '@/features/offline';
import { useClientSliceInfiniteScroll } from '@/hooks/useClientSliceInfiniteScroll';
import { useClientSliceInfiniteScroll } from '@/lib/hooks/useClientSliceInfiniteScroll';
import { useDebouncedValue } from '@/lib/hooks/useDebouncedValue';
import { useInpageScrollSentinel } from '@/hooks/useInpageScrollSentinel';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
const PAGE_SIZE = 30;
const CLIENT_SLICE_PAGE_SIZE = 60;
@@ -7,8 +7,8 @@ import {
GENRE_ALBUM_CATALOG_CHUNK,
GENRE_ALBUM_FIRST_PAGE,
} from '@/lib/library/genreAlbumBrowse';
import { useClientSliceInfiniteScroll } from '@/hooks/useClientSliceInfiniteScroll';
import { useInpageScrollSentinel } from '@/hooks/useInpageScrollSentinel';
import { useClientSliceInfiniteScroll } from '@/lib/hooks/useClientSliceInfiniteScroll';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
const CLIENT_SLICE_PAGE_SIZE = GENRE_ALBUM_FIRST_PAGE;
+2 -2
View File
@@ -27,8 +27,8 @@ import SelectionToggleButton from '@/ui/SelectionToggleButton';
import FilterQuickClear from '@/ui/FilterQuickClear';
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
import { useRangeSelection } from '@/lib/hooks/useRangeSelection';
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
import { useMainstageInpageHeaderTight } from '@/lib/hooks/useMainstageInpageHeaderTight';
import { useInpageScrollViewport } from '@/lib/hooks/useInpageScrollViewport';
import InpageScrollSentinel from '@/ui/InpageScrollSentinel';
import { VirtualCardGrid } from '@/ui/VirtualCardGrid';
import OverlayScrollArea from '@/ui/OverlayScrollArea';
+3 -3
View File
@@ -13,7 +13,7 @@ import { useDownloadModalStore } from '@/features/offline';
import { usePlayerStore } from '@/features/playback/store/playerStore';
import { useZipDownloadStore } from '@/features/offline';
import { useRangeSelection } from '@/lib/hooks/useRangeSelection';
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
import { useMainstageInpageHeaderTight } from '@/lib/hooks/useMainstageInpageHeaderTight';
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
import { showToast } from '@/utils/ui/toast';
import { invoke } from '@tauri-apps/api/core';
@@ -24,8 +24,8 @@ import { albumGridWarmCovers } from '@/cover/layoutSizes';
import { VirtualCardGrid } from '@/ui/VirtualCardGrid';
import OverlayScrollArea from '@/ui/OverlayScrollArea';
import { LOSSLESS_ALBUMS_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
import { useInpageScrollSentinel } from '@/hooks/useInpageScrollSentinel';
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
import { useInpageScrollViewport } from '@/lib/hooks/useInpageScrollViewport';
import InpageScrollSentinel from '@/ui/InpageScrollSentinel';
import { useLibraryIndexStore } from '@/store/libraryIndexStore';
import SortDropdown from '@/ui/SortDropdown';
+4 -4
View File
@@ -20,14 +20,14 @@ import { showToast } from '@/utils/ui/toast';
import { useZipDownloadStore } from '@/features/offline';
import { useRangeSelection } from '@/lib/hooks/useRangeSelection';
import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
import { useMainstageInpageHeaderTight } from '@/lib/hooks/useMainstageInpageHeaderTight';
import { albumGridWarmCovers } from '@/cover/layoutSizes';
import { VirtualCardGrid } from '@/ui/VirtualCardGrid';
import OverlayScrollArea from '@/ui/OverlayScrollArea';
import { NEW_RELEASES_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
import { useAsyncInpagePagination } from '@/hooks/useAsyncInpagePagination';
import { useInpageScrollSentinel } from '@/hooks/useInpageScrollSentinel';
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
import { useAsyncInpagePagination } from '@/lib/hooks/useAsyncInpagePagination';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
import { useInpageScrollViewport } from '@/lib/hooks/useInpageScrollViewport';
import InpageScrollSentinel from '@/ui/InpageScrollSentinel';
import { useAlbumGridBrowseFilters, type AlbumGridBrowseSnapshot } from '@/features/album/hooks/useAlbumGridBrowseFilters';
import { useAlbumBrowseScrollRestore } from '@/features/album/hooks/useAlbumBrowseScrollRestore';
+2 -2
View File
@@ -31,8 +31,8 @@ import {
import { VirtualCardGrid } from '@/ui/VirtualCardGrid';
import OverlayScrollArea from '@/ui/OverlayScrollArea';
import { RANDOM_ALBUMS_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
import { useMainstageInpageHeaderTight } from '@/lib/hooks/useMainstageInpageHeaderTight';
import { useInpageScrollViewport } from '@/lib/hooks/useInpageScrollViewport';
import { useAlbumGridBrowseFilters, type AlbumGridBrowseSnapshot } from '@/features/album/hooks/useAlbumGridBrowseFilters';
import { useAlbumBrowseScrollRestore } from '@/features/album/hooks/useAlbumBrowseScrollRestore';
import { useAlbumBrowseScrollSnapshotSync, type AlbumBrowseScrollSnapshot } from '@/features/album/hooks/useAlbumBrowseFilters';
@@ -6,4 +6,4 @@ export {
useClientSliceInfiniteScroll as useArtistsInfiniteScroll,
type UseClientSliceInfiniteScrollArgs as UseArtistsInfiniteScrollArgs,
type UseClientSliceInfiniteScrollResult as UseArtistsInfiniteScrollResult,
} from '@/hooks/useClientSliceInfiniteScroll';
} from '@/lib/hooks/useClientSliceInfiniteScroll';
+4 -4
View File
@@ -24,10 +24,10 @@ import { useArtistsFiltering } from '@/features/artist/hooks/useArtistsFiltering
import { useLibraryIgnoredArticles } from '@/hooks/useLibraryIgnoredArticles';
import { useArtistsBrowseCatalog } from '@/features/artist/hooks/useArtistsBrowseCatalog';
import { useBrowseArtistTextSearch } from '@/features/artist/hooks/useBrowseArtistTextSearch';
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
import { useClientSliceInfiniteScroll } from '@/hooks/useClientSliceInfiniteScroll';
import { useInpageScrollSentinel } from '@/hooks/useInpageScrollSentinel';
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
import { useMainstageInpageHeaderTight } from '@/lib/hooks/useMainstageInpageHeaderTight';
import { useClientSliceInfiniteScroll } from '@/lib/hooks/useClientSliceInfiniteScroll';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
import { useInpageScrollViewport } from '@/lib/hooks/useInpageScrollViewport';
import { ArtistsGridView } from '@/features/artist/components/ArtistsGridView';
import { ArtistsListView } from '@/features/artist/components/ArtistsListView';
import InpageScrollSentinel from '@/ui/InpageScrollSentinel';
+3 -3
View File
@@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next';
import { useVirtualizer } from '@tanstack/react-virtual';
import { APP_MAIN_SCROLL_VIEWPORT_ID, COMPOSERS_INPAGE_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
import { useElementClientHeightById, useElementClientHeightForElement } from '@/lib/hooks/useResizeClientHeight';
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
import { useMainstageInpageHeaderTight } from '@/lib/hooks/useMainstageInpageHeaderTight';
import { useBrowseArtistTextSearch } from '@/features/artist';
import { useComposersBrowseFilters, type ComposerBrowseScrollSnapshot } from '@/features/composers/hooks/useComposersBrowseFilters';
import { useComposersBrowseScrollRestore } from '@/features/composers/hooks/useComposersBrowseScrollRestore';
@@ -26,8 +26,8 @@ import { usePerfProbeFlags } from '@/utils/perf/perfFlags';
import { VirtualCardGrid } from '@/ui/VirtualCardGrid';
import OverlayScrollArea from '@/ui/OverlayScrollArea';
import { useVirtualizerScrollMargin } from '@/lib/hooks/useVirtualizerScrollMargin';
import { useClientSliceInfiniteScroll } from '@/hooks/useClientSliceInfiniteScroll';
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
import { useClientSliceInfiniteScroll } from '@/lib/hooks/useClientSliceInfiniteScroll';
import { useInpageScrollViewport } from '@/lib/hooks/useInpageScrollViewport';
import InpageScrollSentinel from '@/ui/InpageScrollSentinel';
const ALPHABET = [ALL_SENTINEL, '#', ...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('')];
+2 -2
View File
@@ -13,9 +13,9 @@ import { useAlbumBrowseScrollSnapshotSync, type AlbumBrowseScrollSnapshot } from
import { useGenreAlbumBrowse } from '@/features/album';
import { useAlbumBrowseScrollRestore } from '@/features/album';
import { useGenreDetailBrowse } from '@/features/genre/hooks/useGenreDetailBrowse';
import { useInpageScrollViewport } from '@/hooks/useInpageScrollViewport';
import { useInpageScrollViewport } from '@/lib/hooks/useInpageScrollViewport';
import { useLongPressAction } from '@/lib/hooks/useLongPressAction';
import { useMainstageInpageHeaderTight } from '@/hooks/useMainstageInpageHeaderTight';
import { useMainstageInpageHeaderTight } from '@/lib/hooks/useMainstageInpageHeaderTight';
import { useAuthStore } from '@/store/authStore';
import { useLibraryIndexStore } from '@/store/libraryIndexStore';
import { usePlayerStore } from '@/features/playback/store/playerStore';
@@ -1,7 +1,7 @@
import type { SubsonicSong } from '@/lib/api/subsonicTypes';
import React, { useRef } from 'react';
import SongRow, { SongListHeader } from '@/features/search/components/SongRow';
import { useInpageScrollSentinel } from '@/hooks/useInpageScrollSentinel';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
import InpageScrollSentinel from '@/ui/InpageScrollSentinel';
interface Props {
@@ -1,7 +1,7 @@
import { useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { useArtistLayoutStore, type ArtistSectionConfig, type ArtistSectionId } from '@/features/artist';
import { useListReorderDnd } from '@/hooks/useListReorderDnd';
import { useListReorderDnd } from '@/lib/hooks/useListReorderDnd';
import { applyListReorderById, type ListReorderDropTarget } from '@/utils/componentHelpers/listReorder';
import { ReorderGripHandle } from '@/features/settings/components/ReorderGripHandle';
@@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { useShallow } from 'zustand/react/shallow';
import { useAuthStore } from '@/store/authStore';
import type { LyricsSourceId } from '@/store/authStoreTypes';
import { useListReorderDnd } from '@/hooks/useListReorderDnd';
import { useListReorderDnd } from '@/lib/hooks/useListReorderDnd';
import { applyListReorderById, type ListReorderDropTarget } from '@/utils/componentHelpers/listReorder';
import { ReorderGripHandle } from '@/features/settings/components/ReorderGripHandle';
import { SettingsToggle } from '@/features/settings/components/SettingsToggle';
@@ -2,7 +2,7 @@ import { useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Blend, Infinity as InfinityIcon, ListMusic, MoveRight, Share2, Shuffle, Trash2, Waves } from 'lucide-react';
import { useQueueToolbarStore, QueueToolbarButtonId } from '@/store/queueToolbarStore';
import { useListReorderDnd } from '@/hooks/useListReorderDnd';
import { useListReorderDnd } from '@/lib/hooks/useListReorderDnd';
import { applyListReorderById, type ListReorderDropTarget } from '@/utils/componentHelpers/listReorder';
import { ReorderGripHandle } from '@/features/settings/components/ReorderGripHandle';
@@ -37,7 +37,7 @@ import { serverIndexKeyForProfile } from '@/utils/server/serverIndexKey';
import { switchActiveServer } from '@/utils/server/switchActiveServer';
import { AddServerForm } from '@/features/settings/components/AddServerForm';
import { ServerCapabilityHeaderBadge } from '@/features/settings/components/ServerCapabilityHeaderBadge';
import { useListReorderDnd } from '@/hooks/useListReorderDnd';
import { useListReorderDnd } from '@/lib/hooks/useListReorderDnd';
import { applyListReorderById, type ListReorderDropTarget } from '@/utils/componentHelpers/listReorder';
import { ReorderGripHandle } from '@/features/settings/components/ReorderGripHandle';
import { tooltipAttrs } from '@/ui/tooltipAttrs';
@@ -5,7 +5,7 @@ import { useSidebarStore, SidebarItemConfig, CONSERVED_SIDEBAR_NAV_IDS } from '@
import { useLuckyMixAvailable } from '@/features/randomMix';
import { ALL_NAV_ITEMS } from '@/config/navItems';
import { applySidebarReorderById } from '@/features/sidebar';
import { useListReorderDnd } from '@/hooks/useListReorderDnd';
import { useListReorderDnd } from '@/lib/hooks/useListReorderDnd';
import type { ListReorderDropTarget } from '@/utils/componentHelpers/listReorder';
import { ReorderGripHandle } from '@/features/settings/components/ReorderGripHandle';
import { SettingsGroup } from '@/features/settings/components/SettingsGroup';
@@ -1,6 +1,6 @@
import { act, renderHook } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { useAsyncInpagePagination } from './useAsyncInpagePagination';
import { useAsyncInpagePagination } from '@/lib/hooks/useAsyncInpagePagination';
describe('useAsyncInpagePagination', () => {
it('blocks concurrent page requests', async () => {
@@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { useAsyncInpagePagination } from './useAsyncInpagePagination';
import { useInpageScrollSentinel } from './useInpageScrollSentinel';
import { useAsyncInpagePagination } from '@/lib/hooks/useAsyncInpagePagination';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
export type UseAsyncInpageScrollArgs = {
pageSize: number;
@@ -1,8 +1,8 @@
import { act, renderHook } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { useClientSliceInfiniteScroll } from './useClientSliceInfiniteScroll';
import { useClientSliceInfiniteScroll } from '@/lib/hooks/useClientSliceInfiniteScroll';
vi.mock('./useInpageScrollSentinel', () => ({
vi.mock('@/lib/hooks/useInpageScrollSentinel', () => ({
useInpageScrollSentinel: () => vi.fn(),
}));
@@ -1,6 +1,6 @@
import { useCallback, useEffect, useRef, useState } from 'react';
import { APP_MAIN_SCROLL_VIEWPORT_ID } from '../constants/appScroll';
import { useInpageScrollSentinel } from './useInpageScrollSentinel';
import { APP_MAIN_SCROLL_VIEWPORT_ID } from '@/constants/appScroll';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
export type UseClientSliceInfiniteScrollArgs = {
pageSize: number;
@@ -1,6 +1,6 @@
import { describe, expect, it, vi } from 'vitest';
import { renderHook } from '@testing-library/react';
import { useInpageScrollSentinel } from './useInpageScrollSentinel';
import { useInpageScrollSentinel } from '@/lib/hooks/useInpageScrollSentinel';
describe('useInpageScrollSentinel', () => {
it('returns a callback ref function', () => {
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useDragDrop } from '@/lib/dnd/DragDropContext';
import type { ListReorderDropTarget } from '../utils/componentHelpers/listReorder';
import type { ListReorderDropTarget } from '@/utils/componentHelpers/listReorder';
interface Options {
/** Payload discriminator the drag source emits, e.g. `'lyrics_source_reorder'`. */