mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-06 20:10:12 +02:00
adjust top songs / favorite songs sections
- use table row height configuration for container calculation - add wrapper component and use for both Top Songs and Favorite Songs - remove the view more button, show all items by default
This commit is contained in:
@@ -225,6 +225,39 @@ const AlbumArtistMetadataBiography = ({
|
||||
);
|
||||
};
|
||||
|
||||
const TABLE_ROW_HEIGHT = {
|
||||
compact: 40,
|
||||
default: 64,
|
||||
large: 88,
|
||||
} as const;
|
||||
|
||||
const TABLE_HEADER_HEIGHT = 40;
|
||||
|
||||
interface SongTableListContainerProps {
|
||||
children: React.ReactNode;
|
||||
enableHeader?: boolean;
|
||||
itemCount: number;
|
||||
maxRows?: number;
|
||||
tableSize?: 'compact' | 'default' | 'large';
|
||||
}
|
||||
|
||||
function getTableRowHeight(size: 'compact' | 'default' | 'large' | undefined): number {
|
||||
return size ? TABLE_ROW_HEIGHT[size] : TABLE_ROW_HEIGHT.default;
|
||||
}
|
||||
|
||||
const SongTableListContainer = ({
|
||||
children,
|
||||
enableHeader = true,
|
||||
itemCount,
|
||||
maxRows = 5,
|
||||
tableSize = 'default',
|
||||
}: SongTableListContainerProps) => {
|
||||
const rowHeight = getTableRowHeight(tableSize);
|
||||
const headerOffset = enableHeader ? TABLE_HEADER_HEIGHT : 0;
|
||||
const height = headerOffset + rowHeight * Math.min(itemCount, maxRows);
|
||||
return <div style={{ height }}>{children}</div>;
|
||||
};
|
||||
|
||||
interface AlbumArtistMetadataTopSongsProps {
|
||||
detailQuery: ReturnType<typeof useSuspenseQuery<AlbumArtistDetailResponse>>;
|
||||
routeId: string;
|
||||
@@ -237,7 +270,6 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
const { t } = useTranslation();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 300);
|
||||
const [showAll, setShowAll] = useState(false);
|
||||
const [topSongsQueryType, setTopSongsQueryType] = useLocalStorage<'community' | 'personal'>({
|
||||
defaultValue: 'community',
|
||||
key: 'album-artist-top-songs-query-type',
|
||||
@@ -269,13 +301,8 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
}, [tableConfig?.columns]);
|
||||
|
||||
const filteredSongs = useMemo(() => {
|
||||
const filtered = searchLibraryItems(songs, debouncedSearchTerm, LibraryItem.SONG);
|
||||
// When searching, show all results. Otherwise, limit to 5 if not showing all
|
||||
if (debouncedSearchTerm?.trim() || showAll) {
|
||||
return filtered;
|
||||
}
|
||||
return filtered.slice(0, 5);
|
||||
}, [songs, debouncedSearchTerm, showAll]);
|
||||
return searchLibraryItems(songs, debouncedSearchTerm, LibraryItem.SONG);
|
||||
}, [songs, debouncedSearchTerm]);
|
||||
|
||||
const { handleColumnReordered } = useItemListColumnReorder({
|
||||
itemListKey: ItemListKey.SONG,
|
||||
@@ -459,35 +486,35 @@ const AlbumArtistMetadataTopSongsContent = ({
|
||||
tableColumnsData={SONG_TABLE_COLUMNS}
|
||||
/>
|
||||
</Group>
|
||||
<ItemTableList
|
||||
activeRowId={currentSongId}
|
||||
autoFitColumns={tableConfig.autoFitColumns}
|
||||
CellComponent={ItemTableListColumn}
|
||||
columns={columns}
|
||||
data={filteredSongs}
|
||||
enableAlternateRowColors={tableConfig.enableAlternateRowColors}
|
||||
enableDrag
|
||||
enableDragScroll={false}
|
||||
enableExpansion={false}
|
||||
<SongTableListContainer
|
||||
enableHeader={tableConfig.enableHeader}
|
||||
enableHorizontalBorders={tableConfig.enableHorizontalBorders}
|
||||
enableRowHoverHighlight={tableConfig.enableRowHoverHighlight}
|
||||
enableSelection
|
||||
enableSelectionDialog={false}
|
||||
enableVerticalBorders={tableConfig.enableVerticalBorders}
|
||||
itemType={LibraryItem.SONG}
|
||||
onColumnReordered={handleColumnReordered}
|
||||
onColumnResized={handleColumnResized}
|
||||
overrideControls={overrideControls}
|
||||
size={tableConfig.size}
|
||||
/>
|
||||
{!searchTerm.trim() && songs.length > 5 && !showAll && (
|
||||
<Group justify="center" w="100%">
|
||||
<Button onClick={() => setShowAll(true)} variant="subtle">
|
||||
{t('action.viewMore', { postProcess: 'sentenceCase' })}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
itemCount={filteredSongs.length}
|
||||
maxRows={5}
|
||||
tableSize={tableConfig.size}
|
||||
>
|
||||
<ItemTableList
|
||||
activeRowId={currentSongId}
|
||||
autoFitColumns={tableConfig.autoFitColumns}
|
||||
CellComponent={ItemTableListColumn}
|
||||
columns={columns}
|
||||
data={filteredSongs}
|
||||
enableAlternateRowColors={tableConfig.enableAlternateRowColors}
|
||||
enableDrag
|
||||
enableDragScroll={false}
|
||||
enableExpansion={false}
|
||||
enableHeader={tableConfig.enableHeader}
|
||||
enableHorizontalBorders={tableConfig.enableHorizontalBorders}
|
||||
enableRowHoverHighlight={tableConfig.enableRowHoverHighlight}
|
||||
enableSelection
|
||||
enableSelectionDialog={false}
|
||||
enableVerticalBorders={tableConfig.enableVerticalBorders}
|
||||
itemType={LibraryItem.SONG}
|
||||
onColumnReordered={handleColumnReordered}
|
||||
onColumnResized={handleColumnResized}
|
||||
overrideControls={overrideControls}
|
||||
size={tableConfig.size}
|
||||
/>
|
||||
</SongTableListContainer>
|
||||
</>
|
||||
) : null}
|
||||
</Stack>
|
||||
@@ -523,7 +550,6 @@ const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavori
|
||||
const { t } = useTranslation();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 300);
|
||||
const [showAll, setShowAll] = useState(false);
|
||||
const tableConfig = useSettingsStore((state) => state.lists[ItemListKey.SONG]?.table);
|
||||
const currentSong = usePlayerSong();
|
||||
const player = usePlayer();
|
||||
@@ -548,13 +574,8 @@ const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavori
|
||||
}, [tableConfig?.columns]);
|
||||
|
||||
const filteredSongs = useMemo(() => {
|
||||
const filtered = searchLibraryItems(songs, debouncedSearchTerm, LibraryItem.SONG);
|
||||
// When searching, show all results. Otherwise, limit to 5 if not showing all
|
||||
if (debouncedSearchTerm?.trim() || showAll) {
|
||||
return filtered;
|
||||
}
|
||||
return filtered.slice(0, 5);
|
||||
}, [songs, debouncedSearchTerm, showAll]);
|
||||
return searchLibraryItems(songs, debouncedSearchTerm, LibraryItem.SONG);
|
||||
}, [songs, debouncedSearchTerm]);
|
||||
|
||||
const { handleColumnReordered } = useItemListColumnReorder({
|
||||
itemListKey: ItemListKey.SONG,
|
||||
@@ -717,8 +738,12 @@ const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavori
|
||||
tableColumnsData={SONG_TABLE_COLUMNS}
|
||||
/>
|
||||
</Group>
|
||||
{/* Restrict the height. Rendering all items in the DOM makes for a long delay */}
|
||||
<div style={{ height: 50 + 64 * Math.min(songs.length, 5) }}>
|
||||
<SongTableListContainer
|
||||
enableHeader={tableConfig.enableHeader}
|
||||
itemCount={filteredSongs.length}
|
||||
maxRows={5}
|
||||
tableSize={tableConfig.size}
|
||||
>
|
||||
<ItemTableList
|
||||
activeRowId={currentSongId}
|
||||
autoFitColumns={tableConfig.autoFitColumns}
|
||||
@@ -741,15 +766,7 @@ const AlbumArtistMetadataFavoriteSongs = ({ routeId }: AlbumArtistMetadataFavori
|
||||
overrideControls={overrideControls}
|
||||
size={tableConfig.size}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{!searchTerm.trim() && songs.length > 5 && !showAll && (
|
||||
<Group justify="center" w="100%">
|
||||
<Button onClick={() => setShowAll(true)} variant="subtle">
|
||||
{t('action.viewMore', { postProcess: 'sentenceCase' })}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
</SongTableListContainer>
|
||||
</>
|
||||
) : null}
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user