mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-16 05:36:00 +02:00
cleanup
This commit is contained in:
@@ -15,7 +15,7 @@ import {
|
|||||||
} from 'react';
|
} from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { generatePath, Link } from 'react-router';
|
import { generatePath, Link } from 'react-router';
|
||||||
import { List, RowComponentProps, useDynamicRowHeight } from 'react-window-v2';
|
import { List, RowComponentProps, useDynamicRowHeight, useListRef } from 'react-window-v2';
|
||||||
|
|
||||||
import styles from './item-detail.module.css';
|
import styles from './item-detail.module.css';
|
||||||
|
|
||||||
@@ -73,7 +73,9 @@ interface ItemDetailListProps {
|
|||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
items?: unknown[];
|
items?: unknown[];
|
||||||
onRangeChanged?: (range: { startIndex: number; stopIndex: number }) => Promise<void> | void;
|
onRangeChanged?: (range: { startIndex: number; stopIndex: number }) => Promise<void> | void;
|
||||||
|
onScrollEnd?: (rowIndex: number) => void;
|
||||||
rowHeight?: number;
|
rowHeight?: number;
|
||||||
|
scrollOffset?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RowData {
|
interface RowData {
|
||||||
@@ -815,6 +817,8 @@ const DetailListHeader = memo(
|
|||||||
|
|
||||||
DetailListHeader.displayName = 'DetailListHeader';
|
DetailListHeader.displayName = 'DetailListHeader';
|
||||||
|
|
||||||
|
const SCROLL_END_DEBOUNCE_MS = 150;
|
||||||
|
|
||||||
export const ItemDetailList = ({
|
export const ItemDetailList = ({
|
||||||
currentPage,
|
currentPage,
|
||||||
data,
|
data,
|
||||||
@@ -823,9 +827,13 @@ export const ItemDetailList = ({
|
|||||||
itemCount: externalItemCount,
|
itemCount: externalItemCount,
|
||||||
items,
|
items,
|
||||||
onRangeChanged,
|
onRangeChanged,
|
||||||
|
onScrollEnd,
|
||||||
}: ItemDetailListProps) => {
|
}: ItemDetailListProps) => {
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const listRef = useListRef(null);
|
||||||
|
const lastVisibleStartIndexRef = useRef(0);
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const controls = useDefaultItemListControls();
|
const controls = useDefaultItemListControls();
|
||||||
const isMutatingCreateFavorite = useIsMutatingCreateFavorite();
|
const isMutatingCreateFavorite = useIsMutatingCreateFavorite();
|
||||||
const isMutatingDeleteFavorite = useIsMutatingDeleteFavorite();
|
const isMutatingDeleteFavorite = useIsMutatingDeleteFavorite();
|
||||||
@@ -909,6 +917,7 @@ export const ItemDetailList = ({
|
|||||||
|
|
||||||
const handleRowsRendered = useCallback(
|
const handleRowsRendered = useCallback(
|
||||||
(range: { startIndex: number; stopIndex: number }) => {
|
(range: { startIndex: number; stopIndex: number }) => {
|
||||||
|
lastVisibleStartIndexRef.current = range.startIndex;
|
||||||
const el = headerLeftRef.current;
|
const el = headerLeftRef.current;
|
||||||
if (el) {
|
if (el) {
|
||||||
const album = getItem?.(range.startIndex) as Album | undefined;
|
const album = getItem?.(range.startIndex) as Album | undefined;
|
||||||
@@ -1017,8 +1026,27 @@ export const ItemDetailList = ({
|
|||||||
target: container,
|
target: container,
|
||||||
});
|
});
|
||||||
|
|
||||||
return () => osInstance()?.destroy();
|
let scrollEndTimeoutId: null | ReturnType<typeof setTimeout> = null;
|
||||||
}, [initialize, osInstance]);
|
const handleScroll = () => {
|
||||||
|
if (scrollEndTimeoutId) clearTimeout(scrollEndTimeoutId);
|
||||||
|
scrollEndTimeoutId = setTimeout(() => {
|
||||||
|
scrollEndTimeoutId = null;
|
||||||
|
onScrollEnd?.(lastVisibleStartIndexRef.current);
|
||||||
|
}, SCROLL_END_DEBOUNCE_MS);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (onScrollEnd) {
|
||||||
|
viewport.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (onScrollEnd) {
|
||||||
|
viewport.removeEventListener('scroll', handleScroll);
|
||||||
|
if (scrollEndTimeoutId) clearTimeout(scrollEndTimeoutId);
|
||||||
|
}
|
||||||
|
osInstance()?.destroy();
|
||||||
|
};
|
||||||
|
}, [initialize, onScrollEnd, osInstance]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrapper}>
|
<div className={styles.wrapper}>
|
||||||
@@ -1033,6 +1061,7 @@ export const ItemDetailList = ({
|
|||||||
)}
|
)}
|
||||||
<div className={styles.container} ref={containerRef}>
|
<div className={styles.container} ref={containerRef}>
|
||||||
<List
|
<List
|
||||||
|
listRef={listRef}
|
||||||
onRowsRendered={throttledHandleRowsRendered}
|
onRowsRendered={throttledHandleRowsRendered}
|
||||||
rowComponent={
|
rowComponent={
|
||||||
RowComponent as (props: RowComponentProps<RowData>) => ReactElement
|
RowComponent as (props: RowComponentProps<RowData>) => ReactElement
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { UseSuspenseQueryOptions } from '@tanstack/react-query';
|
|||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { useItemListInfiniteLoader } from '/@/renderer/components/item-list/helpers/item-list-infinite-loader';
|
import { useItemListInfiniteLoader } from '/@/renderer/components/item-list/helpers/item-list-infinite-loader';
|
||||||
import { useItemListScrollPersist } from '/@/renderer/components/item-list/helpers/use-item-list-scroll-persist';
|
|
||||||
import { ItemDetailList } from '/@/renderer/components/item-list/item-detail-list/item-detail';
|
import { ItemDetailList } from '/@/renderer/components/item-list/item-detail-list/item-detail';
|
||||||
import { ItemListComponentProps } from '/@/renderer/components/item-list/types';
|
import { ItemListComponentProps } from '/@/renderer/components/item-list/types';
|
||||||
import { albumQueries } from '/@/renderer/features/albums/api/album-api';
|
import { albumQueries } from '/@/renderer/features/albums/api/album-api';
|
||||||
@@ -25,7 +24,6 @@ export const AlbumListInfiniteDetail = ({
|
|||||||
sortBy: AlbumListSort.NAME,
|
sortBy: AlbumListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: SortOrder.ASC,
|
||||||
},
|
},
|
||||||
saveScrollOffset = true,
|
|
||||||
serverId,
|
serverId,
|
||||||
}: AlbumListInfiniteDetailProps) => {
|
}: AlbumListInfiniteDetailProps) => {
|
||||||
const listCountQuery = albumQueries.listCount({
|
const listCountQuery = albumQueries.listCount({
|
||||||
@@ -45,10 +43,6 @@ export const AlbumListInfiniteDetail = ({
|
|||||||
serverId,
|
serverId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleOnScrollEnd, scrollOffset } = useItemListScrollPersist({
|
|
||||||
enabled: saveScrollOffset,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ItemDetailList
|
<ItemDetailList
|
||||||
data={loadedItems}
|
data={loadedItems}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { UseSuspenseQueryOptions } from '@tanstack/react-query';
|
|||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { useItemListPaginatedLoader } from '/@/renderer/components/item-list/helpers/item-list-paginated-loader';
|
import { useItemListPaginatedLoader } from '/@/renderer/components/item-list/helpers/item-list-paginated-loader';
|
||||||
import { useItemListScrollPersist } from '/@/renderer/components/item-list/helpers/use-item-list-scroll-persist';
|
|
||||||
import { ItemDetailList } from '/@/renderer/components/item-list/item-detail-list/item-detail';
|
import { ItemDetailList } from '/@/renderer/components/item-list/item-detail-list/item-detail';
|
||||||
import { ItemListWithPagination } from '/@/renderer/components/item-list/item-list-pagination/item-list-pagination';
|
import { ItemListWithPagination } from '/@/renderer/components/item-list/item-list-pagination/item-list-pagination';
|
||||||
import { useItemListPagination } from '/@/renderer/components/item-list/item-list-pagination/use-item-list-pagination';
|
import { useItemListPagination } from '/@/renderer/components/item-list/item-list-pagination/use-item-list-pagination';
|
||||||
@@ -27,7 +26,6 @@ export const AlbumListPaginatedDetail = ({
|
|||||||
sortBy: AlbumListSort.NAME,
|
sortBy: AlbumListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: SortOrder.ASC,
|
||||||
},
|
},
|
||||||
saveScrollOffset = true,
|
|
||||||
serverId,
|
serverId,
|
||||||
}: AlbumListPaginatedDetailProps) => {
|
}: AlbumListPaginatedDetailProps) => {
|
||||||
const listCountQuery = albumQueries.listCount({
|
const listCountQuery = albumQueries.listCount({
|
||||||
@@ -50,10 +48,6 @@ export const AlbumListPaginatedDetail = ({
|
|||||||
serverId,
|
serverId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleOnScrollEnd, scrollOffset } = useItemListScrollPersist({
|
|
||||||
enabled: saveScrollOffset,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ItemListWithPagination
|
<ItemListWithPagination
|
||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ export const applyFavoriteOptimisticUpdates = (
|
|||||||
pendingUpdates.push({
|
pendingUpdates.push({
|
||||||
previousData: data,
|
previousData: data,
|
||||||
queryKey,
|
queryKey,
|
||||||
updater: (prev: { items: Song[] } | undefined) => {
|
updater: (prev: undefined | { items: Song[] }) => {
|
||||||
if (!prev) return prev;
|
if (!prev) return prev;
|
||||||
const updatedItems = updateItemInArray(prev.items, itemIdSet, (item) =>
|
const updatedItems = updateItemInArray(prev.items, itemIdSet, (item) =>
|
||||||
createFavoriteUpdater<Song>(item),
|
createFavoriteUpdater<Song>(item),
|
||||||
@@ -701,10 +701,7 @@ export const applyFavoriteOptimisticUpdatesDeferred = (
|
|||||||
queryKeys.playlists.songList(variables.apiClientProps.serverId),
|
queryKeys.playlists.songList(variables.apiClientProps.serverId),
|
||||||
'playlist-song-list',
|
'playlist-song-list',
|
||||||
);
|
);
|
||||||
collectQueries(
|
collectQueries(queryKeys.songs.list(variables.apiClientProps.serverId), 'song-list');
|
||||||
queryKeys.songs.list(variables.apiClientProps.serverId),
|
|
||||||
'song-list',
|
|
||||||
);
|
|
||||||
collectQueries(
|
collectQueries(
|
||||||
queryKeys.albumArtists.topSongs(variables.apiClientProps.serverId),
|
queryKeys.albumArtists.topSongs(variables.apiClientProps.serverId),
|
||||||
'top-songs',
|
'top-songs',
|
||||||
|
|||||||
Reference in New Issue
Block a user