From a59c496ae061c94a90db8e74db7138acf94f3618 Mon Sep 17 00:00:00 2001
From: nikec <43032218+niikeec@users.noreply.github.com>
Date: Mon, 15 Apr 2024 14:26:17 +0200
Subject: [PATCH] [ENG-1741] Improve date header (#2330)
improve date lookup and include placeholder
---
.../Explorer/View/MediaView/DateHeader.tsx | 6 +-
.../Explorer/View/MediaView/index.tsx | 95 +++++++++----------
.../Explorer/View/MediaView/util.ts | 30 ++++++
3 files changed, 78 insertions(+), 53 deletions(-)
diff --git a/interface/app/$libraryId/Explorer/View/MediaView/DateHeader.tsx b/interface/app/$libraryId/Explorer/View/MediaView/DateHeader.tsx
index e609d0f8f..9d16ca8ed 100644
--- a/interface/app/$libraryId/Explorer/View/MediaView/DateHeader.tsx
+++ b/interface/app/$libraryId/Explorer/View/MediaView/DateHeader.tsx
@@ -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'
)}
/>
-
{date}
+
+ {date ?? 'No date'}
+
);
};
diff --git a/interface/app/$libraryId/Explorer/View/MediaView/index.tsx b/interface/app/$libraryId/Explorer/View/MediaView/index.tsx
index cdf62f257..f70c2b81c 100644
--- a/interface/app/$libraryId/Explorer/View/MediaView/index.tsx
+++ b/interface/app/$libraryId/Explorer/View/MediaView/index.tsx
@@ -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> = {
+ '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 && }
+ {isSortingByDate && }
{virtualRows.map((virtualRow) => (
diff --git a/interface/app/$libraryId/Explorer/View/MediaView/util.ts b/interface/app/$libraryId/Explorer/View/MediaView/util.ts
index 42302b441..f2140e487 100644
--- a/interface/app/$libraryId/Explorer/View/MediaView/util.ts
+++ b/interface/app/$libraryId/Explorer/View/MediaView/util.ts
@@ -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;
+ // }
+ }
+}