mirror of
https://github.com/spacedriveapp/spacedrive
synced 2024-07-04 14:33:34 +00:00
[ENG-1741] Improve date header (#2330)
improve date lookup and include placeholder
This commit is contained in:
parent
73cb692218
commit
a59c496ae0
|
@ -8,7 +8,7 @@ import { useExplorerViewContext } from '../Context';
|
|||
export const DATE_HEADER_HEIGHT = 140;
|
||||
|
||||
// million-ignore
|
||||
export const DateHeader = ({ date }: { date: string }) => {
|
||||
export const DateHeader = ({ date }: { date?: string }) => {
|
||||
const isDark = useIsDark();
|
||||
|
||||
const explorer = useExplorerContext();
|
||||
|
@ -52,7 +52,9 @@ export const DateHeader = ({ date }: { date: string }) => {
|
|||
isSticky ? 'opacity-100' : 'opacity-0'
|
||||
)}
|
||||
/>
|
||||
<div className="relative text-xl font-semibold">{date}</div>
|
||||
<div className={clsx('relative text-xl font-semibold', !date && 'opacity-75')}>
|
||||
{date ?? 'No date'}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { LoadMoreTrigger, useGrid, useScrollMargin, useVirtualizer } from '@virtual-grid/react';
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { getExplorerItemData, getOrderingDirection, orderingKey } from '@sd/client';
|
||||
import { getOrderingDirection, OrderingKey, orderingKey } from '@sd/client';
|
||||
|
||||
import { useExplorerContext } from '../../Context';
|
||||
import { getItemData, getItemId, uniqueId } from '../../util';
|
||||
|
@ -10,15 +10,15 @@ import { GridItem } from '../Grid/Item';
|
|||
import { useKeySelection } from '../Grid/useKeySelection';
|
||||
import { DATE_HEADER_HEIGHT, DateHeader } from './DateHeader';
|
||||
import { MediaViewItem } from './Item';
|
||||
import { formatDate } from './util';
|
||||
import { formatDate, getDate } from './util';
|
||||
|
||||
const SORT_BY_DATE_KEYS = [
|
||||
'dateCreated',
|
||||
'dateIndexed',
|
||||
'dateModified',
|
||||
'object.dateAccessed',
|
||||
'object.mediaData.epochTime'
|
||||
];
|
||||
const SORT_BY_DATE: Partial<Record<OrderingKey, boolean>> = {
|
||||
'dateCreated': true,
|
||||
'dateIndexed': true,
|
||||
'dateModified': true,
|
||||
'object.dateAccessed': true,
|
||||
'object.mediaData.epochTime': true
|
||||
};
|
||||
|
||||
export const MediaView = () => {
|
||||
const explorer = useExplorerContext();
|
||||
|
@ -30,7 +30,7 @@ export const MediaView = () => {
|
|||
const orderBy = explorerSettings.order && orderingKey(explorerSettings.order);
|
||||
const orderDirection = explorerSettings.order && getOrderingDirection(explorerSettings.order);
|
||||
|
||||
const isSortingByDate = orderBy && SORT_BY_DATE_KEYS.includes(orderBy);
|
||||
const isSortingByDate = orderBy && SORT_BY_DATE[orderBy];
|
||||
|
||||
const grid = useGrid({
|
||||
scrollRef: explorer.scrollRef,
|
||||
|
@ -73,6 +73,10 @@ export const MediaView = () => {
|
|||
const date = useMemo(() => {
|
||||
if (!isSortingByDate || !orderBy || !orderDirection) return;
|
||||
|
||||
// Prevent date placeholder from showing when
|
||||
// items are still fetching
|
||||
if (explorer.items === null) return '';
|
||||
|
||||
let firstRowIndex: number | undefined = undefined;
|
||||
let lastRowIndex: number | undefined = undefined;
|
||||
|
||||
|
@ -96,53 +100,38 @@ export const MediaView = () => {
|
|||
|
||||
if (firstRowIndex === undefined || lastRowIndex === undefined) return;
|
||||
|
||||
// Get the index of the last item and exclude any total count indexes
|
||||
let firstItemIndex = firstRowIndex * grid.columnCount;
|
||||
let lastItemIndex = lastRowIndex * grid.columnCount + grid.columnCount;
|
||||
|
||||
// Exclude any total count indexes
|
||||
if (lastItemIndex > grid.options.count - 1) lastItemIndex = grid.options.count - 1;
|
||||
|
||||
const firstExplorerItem = explorer.items?.[firstRowIndex * grid.columnCount];
|
||||
const lastExplorerItem = explorer.items?.[lastItemIndex];
|
||||
|
||||
const firstFilePath = firstExplorerItem && getExplorerItemData(firstExplorerItem);
|
||||
if (!firstFilePath) return;
|
||||
|
||||
const lastFilePath = lastExplorerItem && getExplorerItemData(lastExplorerItem);
|
||||
if (!lastFilePath) return;
|
||||
|
||||
let firstFilePathDate: string | null = null;
|
||||
let lastFilePathDate: string | null = null;
|
||||
|
||||
switch (orderBy) {
|
||||
case 'dateCreated': {
|
||||
firstFilePathDate = firstFilePath.dateCreated;
|
||||
lastFilePathDate = lastFilePath.dateCreated;
|
||||
break;
|
||||
// Look for the first date
|
||||
for (let i = firstItemIndex; i < lastItemIndex; i++) {
|
||||
const item = explorer.items[i];
|
||||
const date = item && getDate(item, orderBy);
|
||||
|
||||
if (!date) {
|
||||
if (i !== lastItemIndex - 1) firstItemIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
case 'dateIndexed': {
|
||||
firstFilePathDate = firstFilePath.dateIndexed;
|
||||
lastFilePathDate = lastFilePath.dateIndexed;
|
||||
break;
|
||||
}
|
||||
firstFilePathDate = date;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'dateModified': {
|
||||
firstFilePathDate = firstFilePath.dateModified;
|
||||
lastFilePathDate = lastFilePath.dateModified;
|
||||
break;
|
||||
}
|
||||
// Look for the last date up to where the first lookup ended
|
||||
for (let i = lastItemIndex; i > firstItemIndex; i--) {
|
||||
const item = explorer.items[i];
|
||||
const date = item && getDate(item, orderBy);
|
||||
|
||||
case 'object.dateAccessed': {
|
||||
firstFilePathDate = firstFilePath.dateAccessed;
|
||||
lastFilePathDate = lastFilePath.dateAccessed;
|
||||
break;
|
||||
}
|
||||
if (!date) continue;
|
||||
|
||||
// TODO: Uncomment when we add sorting by date taken
|
||||
// case 'object.mediaData.epochTime': {
|
||||
// firstFilePathDate = firstFilePath.dateTaken;
|
||||
// lastFilePathDate = lastFilePath.dateTaken;
|
||||
// break;
|
||||
// }
|
||||
lastFilePathDate = date;
|
||||
break;
|
||||
}
|
||||
|
||||
const firstDate = firstFilePathDate
|
||||
|
@ -153,16 +142,20 @@ export const MediaView = () => {
|
|||
? new Date(new Date(lastFilePathDate).setHours(0, 0, 0, 0))
|
||||
: undefined;
|
||||
|
||||
if (!firstDate || !lastDate) return;
|
||||
if (firstDate && !lastDate) return formatDate(firstDate);
|
||||
|
||||
if (!firstDate && lastDate) return formatDate(lastDate);
|
||||
|
||||
if (firstDate && lastDate) {
|
||||
if (firstDate.getTime() === lastDate.getTime()) {
|
||||
return formatDate(firstDate);
|
||||
}
|
||||
|
||||
if (firstDate.getTime() !== lastDate.getTime()) {
|
||||
return formatDate({
|
||||
from: orderDirection === 'Asc' ? firstDate : lastDate,
|
||||
to: orderDirection === 'Asc' ? lastDate : firstDate
|
||||
});
|
||||
}
|
||||
|
||||
return formatDate(firstDate);
|
||||
}, [
|
||||
explorer.items,
|
||||
grid.columnCount,
|
||||
|
@ -186,7 +179,7 @@ export const MediaView = () => {
|
|||
width: '100%'
|
||||
}}
|
||||
>
|
||||
{isSortingByDate && <DateHeader date={date ?? ''} />}
|
||||
{isSortingByDate && <DateHeader date={date} />}
|
||||
|
||||
<DragSelect grid={grid} onActiveItemChange={updateActiveItem}>
|
||||
{virtualRows.map((virtualRow) => (
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import dayjs from 'dayjs';
|
||||
import { ExplorerItem, getExplorerItemData, OrderingKey } from '@sd/client';
|
||||
|
||||
const DATE_FORMAT = 'D MMM YYYY';
|
||||
|
||||
|
@ -14,3 +15,32 @@ export const formatDate = (date: Date | { from: Date; to: Date }) => {
|
|||
|
||||
return `${dayjs(date.from).format(fromDateFormat)} - ${dayjs(date.to).format(DATE_FORMAT)}`;
|
||||
};
|
||||
|
||||
export function getDate(item: ExplorerItem, orderBy: OrderingKey) {
|
||||
const filePath = getExplorerItemData(item);
|
||||
|
||||
switch (orderBy) {
|
||||
case 'dateCreated': {
|
||||
return filePath.dateCreated;
|
||||
}
|
||||
|
||||
case 'dateIndexed': {
|
||||
return filePath.dateIndexed;
|
||||
}
|
||||
|
||||
case 'dateModified': {
|
||||
return filePath.dateModified;
|
||||
}
|
||||
|
||||
case 'object.dateAccessed': {
|
||||
return filePath.dateAccessed;
|
||||
}
|
||||
|
||||
// TODO: Uncomment when we add sorting by date taken
|
||||
// case 'object.mediaData.epochTime': {
|
||||
// firstFilePathDate = firstFilePath.dateTaken;
|
||||
// lastFilePathDate = lastFilePath.dateTaken;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue