mirror of
https://github.com/jeffvli/feishin.git
synced 2026-07-15 07:00:03 +02:00
add additional height calculation for album group
This commit is contained in:
@@ -2,9 +2,9 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--theme-spacing-xs);
|
gap: var(--theme-spacing-xs);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: var(--theme-spacing-xxs);
|
min-height: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--theme-spacing-sm);
|
gap: var(--theme-spacing-sm);
|
||||||
|
align-items: flex-start;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0 var(--theme-spacing-xs);
|
padding: 0 var(--theme-spacing-xs);
|
||||||
@@ -42,15 +43,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
grid-template-rows: auto auto auto;
|
||||||
|
gap: 0;
|
||||||
|
align-content: start;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow: hidden;
|
padding-top: calc(var(--theme-spacing-xs) * 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info.enlarged-image {
|
||||||
|
padding-top: var(--theme-spacing-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.album-name {
|
.album-name {
|
||||||
font-size: var(--theme-font-size-sm);
|
font-size: var(--theme-font-size-sm);
|
||||||
|
line-height: 1.25;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
.album-name a {
|
.album-name a {
|
||||||
@@ -64,5 +73,13 @@
|
|||||||
|
|
||||||
.artist-name {
|
.artist-name {
|
||||||
font-size: var(--theme-font-size-xs);
|
font-size: var(--theme-font-size-xs);
|
||||||
|
line-height: 1.25;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.controls-row {
|
||||||
|
flex-shrink: 0;
|
||||||
|
min-height: 22px;
|
||||||
|
margin-top: var(--theme-spacing-xxs);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ReactElement, useState } from 'react';
|
import clsx from 'clsx';
|
||||||
|
import { ReactElement, useLayoutEffect, useRef, useState } from 'react';
|
||||||
import { generatePath, Link } from 'react-router';
|
import { generatePath, Link } from 'react-router';
|
||||||
|
|
||||||
import imageColumnStyles from '../item-detail-list/columns/image-column.module.css';
|
import imageColumnStyles from '../item-detail-list/columns/image-column.module.css';
|
||||||
@@ -21,6 +22,8 @@ import { Play } from '/@/shared/types/types';
|
|||||||
interface AlbumGroupHeaderProps {
|
interface AlbumGroupHeaderProps {
|
||||||
groupRowCount?: number;
|
groupRowCount?: number;
|
||||||
onPlay?: (playType: Play) => void;
|
onPlay?: (playType: Play) => void;
|
||||||
|
rowIndex?: number;
|
||||||
|
setAlbumGroupContentHeight?: (rowIndex: number, height: number) => void;
|
||||||
size?: 'compact' | 'large' | 'normal';
|
size?: 'compact' | 'large' | 'normal';
|
||||||
song: Song | undefined;
|
song: Song | undefined;
|
||||||
}
|
}
|
||||||
@@ -28,10 +31,13 @@ interface AlbumGroupHeaderProps {
|
|||||||
export const AlbumGroupHeader = ({
|
export const AlbumGroupHeader = ({
|
||||||
groupRowCount,
|
groupRowCount,
|
||||||
onPlay,
|
onPlay,
|
||||||
|
rowIndex,
|
||||||
|
setAlbumGroupContentHeight,
|
||||||
size = 'normal',
|
size = 'normal',
|
||||||
song,
|
song,
|
||||||
}: AlbumGroupHeaderProps): ReactElement => {
|
}: AlbumGroupHeaderProps): ReactElement => {
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
|
const [resolvedInfoHeight, setResolvedInfoHeight] = useState<number | undefined>();
|
||||||
const playButtonBehavior = usePlayButtonBehavior();
|
const playButtonBehavior = usePlayButtonBehavior();
|
||||||
const albumImageSize = useAlbumGroupImageSize();
|
const albumImageSize = useAlbumGroupImageSize();
|
||||||
const rowHeight = {
|
const rowHeight = {
|
||||||
@@ -66,6 +72,31 @@ export const AlbumGroupHeader = ({
|
|||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
|
const infoRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
const infoEl = infoRef.current;
|
||||||
|
if (!infoEl) return;
|
||||||
|
|
||||||
|
const measure = () => {
|
||||||
|
const contentHeight = infoEl.scrollHeight;
|
||||||
|
const resolved = Math.max(infoHeight ?? 0, contentHeight);
|
||||||
|
|
||||||
|
setResolvedInfoHeight(resolved);
|
||||||
|
|
||||||
|
if (rowIndex !== undefined && setAlbumGroupContentHeight) {
|
||||||
|
setAlbumGroupContentHeight(rowIndex, contentHeight);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
measure();
|
||||||
|
|
||||||
|
const resizeObserver = new ResizeObserver(measure);
|
||||||
|
resizeObserver.observe(infoEl);
|
||||||
|
|
||||||
|
return () => resizeObserver.disconnect();
|
||||||
|
}, [infoHeight, rowIndex, setAlbumGroupContentHeight]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={styles.container}
|
className={styles.container}
|
||||||
@@ -100,7 +131,11 @@ export const AlbumGroupHeader = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.info} style={{ height: infoHeight }}>
|
<div
|
||||||
|
className={clsx(styles.info, albumImageSize > 0 && styles.enlargedImage)}
|
||||||
|
ref={infoRef}
|
||||||
|
style={{ minHeight: resolvedInfoHeight ?? infoHeight }}
|
||||||
|
>
|
||||||
<div className={styles.albumName}>
|
<div className={styles.albumName}>
|
||||||
{song?.albumId && albumPath ? (
|
{song?.albumId && albumPath ? (
|
||||||
<Link state={{ item: song }} to={albumPath}>
|
<Link state={{ item: song }} to={albumPath}>
|
||||||
@@ -118,12 +153,14 @@ export const AlbumGroupHeader = ({
|
|||||||
rootTextProps={{ fw: 400, size: 'xs' }}
|
rootTextProps={{ fw: 400, size: 'xs' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<AlbumGroupControls
|
<div className={styles.controlsRow}>
|
||||||
albumId={song?.albumId}
|
<AlbumGroupControls
|
||||||
isGroupHovered={isHovered}
|
albumId={song?.albumId}
|
||||||
serverId={song?._serverId}
|
isGroupHovered={isHovered}
|
||||||
serverType={song?._serverType}
|
serverId={song?._serverId}
|
||||||
/>
|
serverType={song?._serverType}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ export const AlbumGroupColumn = (props: ItemTableListInnerColumn) => {
|
|||||||
<AlbumGroupHeader
|
<AlbumGroupHeader
|
||||||
groupRowCount={groupRowCount}
|
groupRowCount={groupRowCount}
|
||||||
onPlay={handlePlay}
|
onPlay={handlePlay}
|
||||||
|
rowIndex={props.rowIndex}
|
||||||
|
setAlbumGroupContentHeight={props.setAlbumGroupContentHeight}
|
||||||
size={props.size === 'default' ? 'normal' : props.size}
|
size={props.size === 'default' ? 'normal' : props.size}
|
||||||
song={item}
|
song={item}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -414,6 +414,38 @@ export function getAlbumGroupRowCount(
|
|||||||
return end - start + 1;
|
return end - start + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAlbumGroupSpanHeight(
|
||||||
|
groupRowCount: number,
|
||||||
|
baseHeight: number,
|
||||||
|
albumGroupImageSize: number,
|
||||||
|
contentHeight = 0,
|
||||||
|
): number {
|
||||||
|
const rowSpanHeight = groupRowCount * baseHeight;
|
||||||
|
const imageSpanHeight =
|
||||||
|
albumGroupImageSize > 0 ? Math.max(albumGroupImageSize, rowSpanHeight) : rowSpanHeight;
|
||||||
|
|
||||||
|
return Math.max(imageSpanHeight, contentHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAlbumGroupStartRowIndex(
|
||||||
|
rowIndex: number,
|
||||||
|
getRowItem: ((index: number) => unknown) | undefined,
|
||||||
|
enableHeader: boolean | undefined,
|
||||||
|
): number {
|
||||||
|
const item = getRowItem?.(rowIndex) as null | undefined | { album?: string };
|
||||||
|
if (!item?.album) return rowIndex;
|
||||||
|
|
||||||
|
const firstDataRow = enableHeader ? 1 : 0;
|
||||||
|
let start = rowIndex;
|
||||||
|
while (start > firstDataRow) {
|
||||||
|
const prevItem = getRowItem?.(start - 1) as null | undefined | { album?: string };
|
||||||
|
if (!prevItem || prevItem.album !== item.album) break;
|
||||||
|
start--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
export function isAlbumGroupingActive(columns: { id: string; isEnabled?: boolean }[]): boolean {
|
export function isAlbumGroupingActive(columns: { id: string; isEnabled?: boolean }[]): boolean {
|
||||||
return columns.some((col) => col.id === TableColumn.ALBUM_GROUP && col.isEnabled);
|
return columns.some((col) => col.id === TableColumn.ALBUM_GROUP && col.isEnabled);
|
||||||
}
|
}
|
||||||
@@ -513,9 +545,21 @@ function getAlbumGroupClampHeight(props: ItemTableListInnerColumn): null | numbe
|
|||||||
props.enableHeader,
|
props.enableHeader,
|
||||||
props.data.length,
|
props.data.length,
|
||||||
);
|
);
|
||||||
|
const groupStartRowIndex = getAlbumGroupStartRowIndex(
|
||||||
|
props.rowIndex,
|
||||||
|
props.getRowItem,
|
||||||
|
props.enableHeader,
|
||||||
|
);
|
||||||
|
const contentHeight = props.albumGroupContentHeights?.get(groupStartRowIndex) ?? 0;
|
||||||
|
const totalGroupHeight = getAlbumGroupSpanHeight(
|
||||||
|
groupRowCount,
|
||||||
|
baseHeight,
|
||||||
|
albumImageSize,
|
||||||
|
contentHeight,
|
||||||
|
);
|
||||||
|
|
||||||
// Only clamp when the row was actually grown to fit the image.
|
// Only clamp when the row was actually grown to fit the image or wrapped text.
|
||||||
if (albumImageSize <= groupRowCount * baseHeight) return null;
|
if (totalGroupHeight <= groupRowCount * baseHeight) return null;
|
||||||
|
|
||||||
return baseHeight;
|
return baseHeight;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ import { useTableRowModel } from '/@/renderer/components/item-list/item-table-li
|
|||||||
import { useTableScrollToIndex } from '/@/renderer/components/item-list/item-table-list/hooks/use-table-scroll-to-index';
|
import { useTableScrollToIndex } from '/@/renderer/components/item-list/item-table-list/hooks/use-table-scroll-to-index';
|
||||||
import {
|
import {
|
||||||
getAlbumGroupRowCount,
|
getAlbumGroupRowCount,
|
||||||
|
getAlbumGroupSpanHeight,
|
||||||
|
getAlbumGroupStartRowIndex,
|
||||||
isLastInAlbumGroup,
|
isLastInAlbumGroup,
|
||||||
ItemTableListColumn,
|
ItemTableListColumn,
|
||||||
} from '/@/renderer/components/item-list/item-table-list/item-table-list-column';
|
} from '/@/renderer/components/item-list/item-table-list/item-table-list-column';
|
||||||
@@ -174,6 +176,7 @@ const ItemTableScrollShadowRight = memo(function ItemTableScrollShadowRight({
|
|||||||
ItemTableScrollShadowRight.displayName = 'ItemTableScrollShadowRight';
|
ItemTableScrollShadowRight.displayName = 'ItemTableScrollShadowRight';
|
||||||
|
|
||||||
interface VirtualizedTableGridProps {
|
interface VirtualizedTableGridProps {
|
||||||
|
albumGroupContentHeights: Map<number, number>;
|
||||||
calculatedColumnWidths: number[];
|
calculatedColumnWidths: number[];
|
||||||
CellComponent: JSXElementConstructor<CellComponentProps<TableItemProps>>;
|
CellComponent: JSXElementConstructor<CellComponentProps<TableItemProps>>;
|
||||||
data: unknown[];
|
data: unknown[];
|
||||||
@@ -191,12 +194,14 @@ interface VirtualizedTableGridProps {
|
|||||||
pinnedRowCount: number;
|
pinnedRowCount: number;
|
||||||
pinnedRowRef: React.RefObject<HTMLDivElement | null>;
|
pinnedRowRef: React.RefObject<HTMLDivElement | null>;
|
||||||
scrollShadowStore: TableScrollShadowStore;
|
scrollShadowStore: TableScrollShadowStore;
|
||||||
|
setAlbumGroupContentHeight: (rowIndex: number, height: number) => void;
|
||||||
tableConfig: ItemTableListConfig;
|
tableConfig: ItemTableListConfig;
|
||||||
totalColumnCount: number;
|
totalColumnCount: number;
|
||||||
totalRowCount: number;
|
totalRowCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VirtualizedTableGrid = ({
|
const VirtualizedTableGrid = ({
|
||||||
|
albumGroupContentHeights,
|
||||||
calculatedColumnWidths,
|
calculatedColumnWidths,
|
||||||
CellComponent,
|
CellComponent,
|
||||||
data,
|
data,
|
||||||
@@ -214,6 +219,7 @@ const VirtualizedTableGrid = ({
|
|||||||
pinnedRowCount,
|
pinnedRowCount,
|
||||||
pinnedRowRef,
|
pinnedRowRef,
|
||||||
scrollShadowStore,
|
scrollShadowStore,
|
||||||
|
setAlbumGroupContentHeight,
|
||||||
tableConfig,
|
tableConfig,
|
||||||
totalColumnCount,
|
totalColumnCount,
|
||||||
totalRowCount,
|
totalRowCount,
|
||||||
@@ -377,41 +383,15 @@ const VirtualizedTableGrid = ({
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const gridOnlyProps = useMemo(
|
|
||||||
() => ({
|
|
||||||
calculatedColumnWidths,
|
|
||||||
data: dataWithGroups,
|
|
||||||
getAdjustedRowIndex,
|
|
||||||
getGroupRenderData,
|
|
||||||
getRowItem,
|
|
||||||
groupHeaderInfoByRowIndex,
|
|
||||||
hasAlbumGroupColumn: parsedColumns.some((col) => col.id === TableColumn.ALBUM_GROUP),
|
|
||||||
pinnedLeftColumnCount,
|
|
||||||
pinnedLeftColumnWidths,
|
|
||||||
pinnedRightColumnCount,
|
|
||||||
pinnedRightColumnWidths,
|
|
||||||
}),
|
|
||||||
[
|
|
||||||
calculatedColumnWidths,
|
|
||||||
dataWithGroups,
|
|
||||||
getRowItem,
|
|
||||||
getAdjustedRowIndex,
|
|
||||||
getGroupRenderData,
|
|
||||||
groupHeaderInfoByRowIndex,
|
|
||||||
parsedColumns,
|
|
||||||
pinnedLeftColumnCount,
|
|
||||||
pinnedLeftColumnWidths,
|
|
||||||
pinnedRightColumnCount,
|
|
||||||
pinnedRightColumnWidths,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
const itemProps: TableItemProps = useMemo(
|
const itemProps: TableItemProps = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
albumGroupContentHeights,
|
||||||
albumGroupImageSize,
|
albumGroupImageSize,
|
||||||
|
calculatedColumnWidths,
|
||||||
cellPadding: tableConfig.cellPadding,
|
cellPadding: tableConfig.cellPadding,
|
||||||
columns: tableConfig.columns,
|
columns: tableConfig.columns,
|
||||||
controls: tableConfig.controls,
|
controls: tableConfig.controls,
|
||||||
|
data: dataWithGroups,
|
||||||
enableAlternateRowColors: tableConfig.enableAlternateRowColors,
|
enableAlternateRowColors: tableConfig.enableAlternateRowColors,
|
||||||
enableColumnReorder: tableConfig.enableColumnReorder,
|
enableColumnReorder: tableConfig.enableColumnReorder,
|
||||||
enableColumnResize: tableConfig.enableColumnResize,
|
enableColumnResize: tableConfig.enableColumnResize,
|
||||||
@@ -422,18 +402,43 @@ const VirtualizedTableGrid = ({
|
|||||||
enableRowHoverHighlight: tableConfig.enableRowHoverHighlight,
|
enableRowHoverHighlight: tableConfig.enableRowHoverHighlight,
|
||||||
enableSelection: tableConfig.enableSelection,
|
enableSelection: tableConfig.enableSelection,
|
||||||
enableVerticalBorders: tableConfig.enableVerticalBorders,
|
enableVerticalBorders: tableConfig.enableVerticalBorders,
|
||||||
|
getAdjustedRowIndex,
|
||||||
|
getGroupRenderData,
|
||||||
getRowHeight: tableConfig.getRowHeight,
|
getRowHeight: tableConfig.getRowHeight,
|
||||||
|
getRowItem,
|
||||||
|
groupHeaderInfoByRowIndex,
|
||||||
groups: tableConfig.groups,
|
groups: tableConfig.groups,
|
||||||
|
hasAlbumGroupColumn: parsedColumns.some((col) => col.id === TableColumn.ALBUM_GROUP),
|
||||||
internalState: tableConfig.internalState,
|
internalState: tableConfig.internalState,
|
||||||
itemType: tableConfig.itemType,
|
itemType: tableConfig.itemType,
|
||||||
|
pinnedLeftColumnCount,
|
||||||
|
pinnedLeftColumnWidths,
|
||||||
|
pinnedRightColumnCount,
|
||||||
|
pinnedRightColumnWidths,
|
||||||
playerContext: tableConfig.playerContext,
|
playerContext: tableConfig.playerContext,
|
||||||
playlistId: tableConfig.playlistId,
|
playlistId: tableConfig.playlistId,
|
||||||
|
setAlbumGroupContentHeight,
|
||||||
size: tableConfig.size,
|
size: tableConfig.size,
|
||||||
startRowIndex: tableConfig.startRowIndex,
|
startRowIndex: tableConfig.startRowIndex,
|
||||||
tableId: tableConfig.tableId,
|
tableId: tableConfig.tableId,
|
||||||
...gridOnlyProps,
|
|
||||||
}),
|
}),
|
||||||
[albumGroupImageSize, gridOnlyProps, tableConfig],
|
[
|
||||||
|
albumGroupContentHeights,
|
||||||
|
albumGroupImageSize,
|
||||||
|
calculatedColumnWidths,
|
||||||
|
dataWithGroups,
|
||||||
|
getAdjustedRowIndex,
|
||||||
|
getGroupRenderData,
|
||||||
|
getRowItem,
|
||||||
|
groupHeaderInfoByRowIndex,
|
||||||
|
parsedColumns,
|
||||||
|
pinnedLeftColumnCount,
|
||||||
|
pinnedLeftColumnWidths,
|
||||||
|
pinnedRightColumnCount,
|
||||||
|
pinnedRightColumnWidths,
|
||||||
|
setAlbumGroupContentHeight,
|
||||||
|
tableConfig,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const pinnedLeftGridMinWidthPx = useMemo(() => {
|
const pinnedLeftGridMinWidthPx = useMemo(() => {
|
||||||
@@ -729,6 +734,8 @@ const MemoizedVirtualizedTableGrid = memo(VirtualizedTableGrid, (prevProps, next
|
|||||||
prevProps.calculatedColumnWidths,
|
prevProps.calculatedColumnWidths,
|
||||||
nextProps.calculatedColumnWidths,
|
nextProps.calculatedColumnWidths,
|
||||||
) &&
|
) &&
|
||||||
|
prevProps.albumGroupContentHeights === nextProps.albumGroupContentHeights &&
|
||||||
|
prevProps.setAlbumGroupContentHeight === nextProps.setAlbumGroupContentHeight &&
|
||||||
prevProps.tableConfig === nextProps.tableConfig &&
|
prevProps.tableConfig === nextProps.tableConfig &&
|
||||||
prevProps.data === nextProps.data &&
|
prevProps.data === nextProps.data &&
|
||||||
prevProps.dataWithGroups === nextProps.dataWithGroups &&
|
prevProps.dataWithGroups === nextProps.dataWithGroups &&
|
||||||
@@ -766,6 +773,7 @@ export interface TableGroupHeader {
|
|||||||
|
|
||||||
export interface TableItemProps {
|
export interface TableItemProps {
|
||||||
adjustedRowIndexMap?: Map<number, number>;
|
adjustedRowIndexMap?: Map<number, number>;
|
||||||
|
albumGroupContentHeights?: Map<number, number>;
|
||||||
albumGroupImageSize?: number;
|
albumGroupImageSize?: number;
|
||||||
calculatedColumnWidths?: number[];
|
calculatedColumnWidths?: number[];
|
||||||
cellPadding?: ItemTableListProps['cellPadding'];
|
cellPadding?: ItemTableListProps['cellPadding'];
|
||||||
@@ -799,6 +807,7 @@ export interface TableItemProps {
|
|||||||
pinnedRightColumnWidths?: number[];
|
pinnedRightColumnWidths?: number[];
|
||||||
playerContext: PlayerContext;
|
playerContext: PlayerContext;
|
||||||
playlistId?: string;
|
playlistId?: string;
|
||||||
|
setAlbumGroupContentHeight?: (rowIndex: number, height: number) => void;
|
||||||
size?: ItemTableListProps['size'];
|
size?: ItemTableListProps['size'];
|
||||||
startRowIndex?: number;
|
startRowIndex?: number;
|
||||||
tableId: string;
|
tableId: string;
|
||||||
@@ -1286,6 +1295,23 @@ const BaseItemTableList = ({
|
|||||||
const tableId = useId();
|
const tableId = useId();
|
||||||
const albumGroupImageSize = useAlbumGroupImageSize();
|
const albumGroupImageSize = useAlbumGroupImageSize();
|
||||||
const baseItemCount = itemCount ?? data.length;
|
const baseItemCount = itemCount ?? data.length;
|
||||||
|
const [albumGroupContentHeights, setAlbumGroupContentHeights] = useState(
|
||||||
|
() => new Map<number, number>(),
|
||||||
|
);
|
||||||
|
|
||||||
|
const setAlbumGroupContentHeight = useCallback((rowIndex: number, height: number) => {
|
||||||
|
setAlbumGroupContentHeights((prev) => {
|
||||||
|
if (prev.get(rowIndex) === height) return prev;
|
||||||
|
const next = new Map(prev);
|
||||||
|
next.set(rowIndex, height);
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setAlbumGroupContentHeights(new Map());
|
||||||
|
}, [baseItemCount, data]);
|
||||||
|
|
||||||
const totalItemCount = enableHeader ? baseItemCount + 1 : baseItemCount;
|
const totalItemCount = enableHeader ? baseItemCount + 1 : baseItemCount;
|
||||||
const [centerContainerWidth, setCenterContainerWidth] = useState(0);
|
const [centerContainerWidth, setCenterContainerWidth] = useState(0);
|
||||||
const [totalContainerWidth, setTotalContainerWidth] = useState(0);
|
const [totalContainerWidth, setTotalContainerWidth] = useState(0);
|
||||||
@@ -1444,12 +1470,10 @@ const BaseItemTableList = ({
|
|||||||
return headerHeight;
|
return headerHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When an album image is enlarged beyond the album group's combined
|
// Grow the group's LAST row when the album image or wrapped album
|
||||||
// row height, grow the group's LAST row to reserve the leftover
|
// info (title + artists + controls) needs more than the standard
|
||||||
// space (so the following album isn't clipped). Other rows keep
|
// combined row height. Other rows keep their standard height.
|
||||||
// their standard height.
|
|
||||||
if (
|
if (
|
||||||
albumGroupImageSize > baseHeight &&
|
|
||||||
cellProps?.hasAlbumGroupColumn &&
|
cellProps?.hasAlbumGroupColumn &&
|
||||||
isLastInAlbumGroup(
|
isLastInAlbumGroup(
|
||||||
index,
|
index,
|
||||||
@@ -1466,7 +1490,20 @@ const BaseItemTableList = ({
|
|||||||
cellProps.enableHeader,
|
cellProps.enableHeader,
|
||||||
cellProps.data.length,
|
cellProps.data.length,
|
||||||
);
|
);
|
||||||
const lastRowHeight = albumGroupImageSize - (groupRowCount - 1) * baseHeight;
|
const groupStartRowIndex = getAlbumGroupStartRowIndex(
|
||||||
|
index,
|
||||||
|
cellProps.getRowItem,
|
||||||
|
cellProps.enableHeader,
|
||||||
|
);
|
||||||
|
const contentHeight =
|
||||||
|
cellProps.albumGroupContentHeights?.get(groupStartRowIndex) ?? 0;
|
||||||
|
const totalGroupHeight = getAlbumGroupSpanHeight(
|
||||||
|
groupRowCount,
|
||||||
|
baseHeight,
|
||||||
|
albumGroupImageSize,
|
||||||
|
contentHeight,
|
||||||
|
);
|
||||||
|
const lastRowHeight = totalGroupHeight - (groupRowCount - 1) * baseHeight;
|
||||||
if (lastRowHeight > baseHeight) {
|
if (lastRowHeight > baseHeight) {
|
||||||
return lastRowHeight;
|
return lastRowHeight;
|
||||||
}
|
}
|
||||||
@@ -1775,6 +1812,7 @@ const BaseItemTableList = ({
|
|||||||
totalColumnCount={totalColumnCount}
|
totalColumnCount={totalColumnCount}
|
||||||
/>
|
/>
|
||||||
<MemoizedVirtualizedTableGrid
|
<MemoizedVirtualizedTableGrid
|
||||||
|
albumGroupContentHeights={albumGroupContentHeights}
|
||||||
calculatedColumnWidths={displayColumnWidths}
|
calculatedColumnWidths={displayColumnWidths}
|
||||||
CellComponent={optimizedCellComponent}
|
CellComponent={optimizedCellComponent}
|
||||||
data={data}
|
data={data}
|
||||||
@@ -1792,6 +1830,7 @@ const BaseItemTableList = ({
|
|||||||
pinnedRowCount={pinnedRowCount}
|
pinnedRowCount={pinnedRowCount}
|
||||||
pinnedRowRef={pinnedRowRef}
|
pinnedRowRef={pinnedRowRef}
|
||||||
scrollShadowStore={scrollShadowStore}
|
scrollShadowStore={scrollShadowStore}
|
||||||
|
setAlbumGroupContentHeight={setAlbumGroupContentHeight}
|
||||||
tableConfig={tableConfigValue}
|
tableConfig={tableConfigValue}
|
||||||
totalColumnCount={totalColumnCount}
|
totalColumnCount={totalColumnCount}
|
||||||
totalRowCount={totalRowCount}
|
totalRowCount={totalRowCount}
|
||||||
|
|||||||
Reference in New Issue
Block a user