From 3d69e2d20c9490f653080bb330dde7beefe0ecfe Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sun, 12 Jan 2025 13:26:38 -0600 Subject: [PATCH 1/4] Add placeholder client logic to date primitive --- src/components/ResponsiveDate.tsx | 46 ++++++++++++++++++++++++------- src/photo/PhotoDate.tsx | 2 ++ src/site/globals.css | 4 +++ src/utility/date.ts | 44 +++++++++++++++++++---------- 4 files changed, 72 insertions(+), 24 deletions(-) diff --git a/src/components/ResponsiveDate.tsx b/src/components/ResponsiveDate.tsx index 433ae5bb..1134f8cc 100644 --- a/src/components/ResponsiveDate.tsx +++ b/src/components/ResponsiveDate.tsx @@ -1,40 +1,66 @@ +'use client'; + import { formatDate } from '@/utility/date'; import { clsx } from 'clsx/lite'; +import { useEffect, useState } from 'react'; export default function ResponsiveDate({ date, className, titleLabel, + timezone: timezoneFromProps, }: { date: Date className?: string titleLabel?: string + timezone?: string | null }) { + const [timezone, setTimezone] = useState(timezoneFromProps); + + useEffect(() => { + if (timezoneFromProps === null) { + setTimezone(Intl.DateTimeFormat().resolvedOptions().timeZone); + } + }, [timezoneFromProps]); + + const showPlaceholderContent = timezone === null; + + const titleDateFormatted = formatDate(date).toLocaleUpperCase(); + const title = titleLabel - ? `${titleLabel}: ${formatDate(date).toLocaleUpperCase()}` - : formatDate(date).toLocaleUpperCase(); + ? `${titleLabel}: ${titleDateFormatted}` + : titleDateFormatted; + + const contentClass = showPlaceholderContent && 'opacity-0 select-none'; + return ( {/* Small */} - {formatDate(date, 'short')} + {formatDate(date, 'short', showPlaceholderContent)} {/* Medium */} - {formatDate(date, 'medium')} + {formatDate(date, 'medium', showPlaceholderContent)} {/* Large */} - - {formatDate(date)} + + {formatDate(date, undefined, showPlaceholderContent)} ); diff --git a/src/photo/PhotoDate.tsx b/src/photo/PhotoDate.tsx index a8c3efb4..8966a6ba 100644 --- a/src/photo/PhotoDate.tsx +++ b/src/photo/PhotoDate.tsx @@ -10,6 +10,7 @@ export default function PhotoDate({ photo: Photo className?: string dateType?: 'takenAt' | 'createdAt' | 'updatedAt' + timezone?: string | null }) { const date = useMemo(() => { const date = new Date(dateType === 'takenAt' @@ -41,6 +42,7 @@ export default function PhotoDate({ date, className, titleLabel: getTitleLabel(), + timezone: null, }} /> ); } diff --git a/src/site/globals.css b/src/site/globals.css index 13d47311..e80a7ad3 100644 --- a/src/site/globals.css +++ b/src/site/globals.css @@ -164,6 +164,10 @@ @apply bg-white dark:bg-black } + .bg-dim { + @apply + bg-gray-100 dark:bg-gray-900/75 + } .bg-content { @apply bg-white border-gray-200 diff --git a/src/utility/date.ts b/src/utility/date.ts index fdbe6454..96f99c99 100644 --- a/src/utility/date.ts +++ b/src/utility/date.ts @@ -1,25 +1,41 @@ import { format, parseISO, parse } from 'date-fns'; -const DATE_STRING_FORMAT_TINY = 'dd MMM yy'; -const DATE_STRING_FORMAT_SHORT = 'dd MMM yyyy'; -const DATE_STRING_FORMAT_MEDIUM = 'dd MMM yy h:mma'; -const DATE_STRING_FORMAT = 'dd MMM yyyy h:mma'; -const DATE_STRING_FORMAT_POSTGRES = 'yyyy-MM-dd HH:mm:ss'; +const DATE_STRING_FORMAT_TINY = 'dd MMM yy'; +const DATE_STRING_FORMAT_TINY_PLACEHOLDER = '00 000 00'; + +const DATE_STRING_FORMAT_SHORT = 'dd MMM yyyy'; +const DATE_STRING_FORMAT_SHORT_PLACEHOLDER = '00 000 0000'; + +const DATE_STRING_FORMAT_MEDIUM = 'dd MMM yy h:mma'; +const DATE_STRING_FORMAT_MEDIUM_PLACEHOLDER = '00 000 00 00:0000'; + +const DATE_STRING_FORMAT_LONG = 'dd MMM yyyy h:mma'; +const DATE_STRING_FORMAT_LONG_PLACEHOLDER = '00 000 0000 00:0000'; + +const DATE_STRING_FORMAT_POSTGRES = 'yyyy-MM-dd HH:mm:ss'; type AmbiguousTimestamp = number | string; type Length = 'tiny' | 'short' | 'medium' | 'long'; -export const formatDate = (date: Date, length: Length = 'long') => { +export const formatDate = ( + date: Date, + length: Length = 'long', + showPlaceholder?: boolean, +) => { switch (length) { - case 'tiny': - return format(date, DATE_STRING_FORMAT_TINY); - case 'short': - return format(date, DATE_STRING_FORMAT_SHORT); - case 'medium': - return format(date, DATE_STRING_FORMAT_MEDIUM); - default: - return format(date, DATE_STRING_FORMAT); + case 'tiny': return showPlaceholder + ? DATE_STRING_FORMAT_TINY_PLACEHOLDER + : format(date, DATE_STRING_FORMAT_TINY); + case 'short': return showPlaceholder + ? DATE_STRING_FORMAT_SHORT_PLACEHOLDER + : format(date, DATE_STRING_FORMAT_SHORT); + case 'medium': return showPlaceholder + ? DATE_STRING_FORMAT_MEDIUM_PLACEHOLDER + : format(date, DATE_STRING_FORMAT_MEDIUM); + default: return showPlaceholder + ? DATE_STRING_FORMAT_LONG_PLACEHOLDER + : format(date, DATE_STRING_FORMAT_LONG); } }; From 5e3521c687cddd6cadcbe0b5fc8d1017772d1a4a Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sun, 12 Jan 2025 17:13:45 -0600 Subject: [PATCH 2/4] Store client timezone in cookie and use on server when possible --- package.json | 1 + pnpm-lock.yaml | 12 ++++++++++++ src/admin/AdminPhotosClient.tsx | 5 +++++ src/admin/AdminPhotosTable.tsx | 4 ++++ src/app/admin/photos/page.tsx | 5 +++++ src/components/ResponsiveDate.tsx | 16 +++++++++------- src/components/cmdk/CommandKClient.tsx | 7 +++++-- src/photo/PhotoDate.tsx | 6 ++++-- src/photo/PhotoLarge.tsx | 3 +++ src/site/CommandK.tsx | 5 +++++ src/state/AppStateProvider.tsx | 2 ++ src/utility/cookie.ts | 21 +++++++++++++++++++++ src/utility/date.ts | 21 ++++++++++++++++----- src/utility/timezone.ts | 18 ++++++++++++++++++ 14 files changed, 110 insertions(+), 16 deletions(-) create mode 100644 src/utility/cookie.ts create mode 100644 src/utility/timezone.ts diff --git a/package.json b/package.json index db492a40..9816e848 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "camelcase-keys": "^9.1.3", "cmdk": "^1.0.4", "date-fns": "^4.1.0", + "date-fns-tz": "^3.2.0", "exifr": "^7.1.3", "framer-motion": "^11.17.0", "nanoid": "^5.0.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81025d86..3042825e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -53,6 +53,9 @@ importers: date-fns: specifier: ^4.1.0 version: 4.1.0 + date-fns-tz: + specifier: ^3.2.0 + version: 3.2.0(date-fns@4.1.0) exifr: specifier: ^7.1.3 version: 7.1.3 @@ -2177,6 +2180,11 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + date-fns-tz@3.2.0: + resolution: {integrity: sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==} + peerDependencies: + date-fns: ^3.0.0 || ^4.0.0 + date-fns@4.1.0: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} @@ -7037,6 +7045,10 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + date-fns-tz@3.2.0(date-fns@4.1.0): + dependencies: + date-fns: 4.1.0 + date-fns@4.1.0: {} debounce@1.2.1: {} diff --git a/src/admin/AdminPhotosClient.tsx b/src/admin/AdminPhotosClient.tsx index 8c82d61c..1da58678 100644 --- a/src/admin/AdminPhotosClient.tsx +++ b/src/admin/AdminPhotosClient.tsx @@ -13,6 +13,7 @@ import { StorageListResponse } from '@/services/storage'; import { useState } from 'react'; import { LiaBroomSolid } from 'react-icons/lia'; import AdminUploadsTable from './AdminUploadsTable'; +import { Timezone } from '@/utility/timezone'; export default function AdminPhotosClient({ photos, @@ -22,6 +23,7 @@ export default function AdminPhotosClient({ blobPhotoUrls, infiniteScrollInitial, infiniteScrollMultiple, + timezone, }: { photos: Photo[] photosCount: number @@ -30,6 +32,7 @@ export default function AdminPhotosClient({ blobPhotoUrls: StorageListResponse infiniteScrollInitial: number infiniteScrollMultiple: number + timezone: Timezone }) { const [isUploading, setIsUploading] = useState(false); @@ -74,12 +77,14 @@ export default function AdminPhotosClient({ {photosCount > photos.length && } } diff --git a/src/admin/AdminPhotosTable.tsx b/src/admin/AdminPhotosTable.tsx index ee1ec308..03002e7e 100644 --- a/src/admin/AdminPhotosTable.tsx +++ b/src/admin/AdminPhotosTable.tsx @@ -14,6 +14,7 @@ import { useAppState } from '@/state/AppState'; import { RevalidatePhoto } from '@/photo/InfinitePhotoScroll'; import PhotoSyncButton from './PhotoSyncButton'; import DeletePhotoButton from './DeletePhotoButton'; +import { Timezone } from '@/utility/timezone'; export default function AdminPhotosTable({ photos, @@ -24,6 +25,7 @@ export default function AdminPhotosTable({ showUpdatedAt, canEdit = true, canDelete = true, + timezone, }: { photos: Photo[], onLastPhotoVisible?: () => void @@ -33,6 +35,7 @@ export default function AdminPhotosTable({ showUpdatedAt?: boolean canEdit?: boolean canDelete?: boolean + timezone?: Timezone }) { const { invalidateSwr } = useAppState(); @@ -90,6 +93,7 @@ export default function AdminPhotosTable({ diff --git a/src/app/admin/photos/page.tsx b/src/app/admin/photos/page.tsx index 4ae24299..d8ef3d11 100644 --- a/src/app/admin/photos/page.tsx +++ b/src/app/admin/photos/page.tsx @@ -4,6 +4,8 @@ import { getPhotosMetaCached } from '@/photo/cache'; import { OUTDATED_THRESHOLD } from '@/photo'; import AdminPhotosClient from '@/admin/AdminPhotosClient'; import { revalidatePath } from 'next/cache'; +import { cookies } from 'next/headers'; +import { TIMEZONE_COOKIE_NAME } from '@/utility/timezone'; export const maxDuration = 60; @@ -13,6 +15,8 @@ const INFINITE_SCROLL_INITIAL_ADMIN_PHOTOS = 25; const INFINITE_SCROLL_MULTIPLE_ADMIN_PHOTOS = 50; export default async function AdminPhotosPage() { + const timezone = (await cookies()).get(TIMEZONE_COOKIE_NAME)?.value; + const [ photos, photosCount, @@ -51,6 +55,7 @@ export default async function AdminPhotosPage() { blobPhotoUrls, infiniteScrollInitial: INFINITE_SCROLL_INITIAL_ADMIN_PHOTOS, infiniteScrollMultiple: INFINITE_SCROLL_MULTIPLE_ADMIN_PHOTOS, + timezone, }} /> ); } diff --git a/src/components/ResponsiveDate.tsx b/src/components/ResponsiveDate.tsx index 1134f8cc..e593a390 100644 --- a/src/components/ResponsiveDate.tsx +++ b/src/components/ResponsiveDate.tsx @@ -1,6 +1,7 @@ 'use client'; import { formatDate } from '@/utility/date'; +import { Timezone } from '@/utility/timezone'; import { clsx } from 'clsx/lite'; import { useEffect, useState } from 'react'; @@ -13,19 +14,20 @@ export default function ResponsiveDate({ date: Date className?: string titleLabel?: string - timezone?: string | null + timezone?: Timezone }) { const [timezone, setTimezone] = useState(timezoneFromProps); useEffect(() => { - if (timezoneFromProps === null) { + if (!timezoneFromProps) { setTimezone(Intl.DateTimeFormat().resolvedOptions().timeZone); } }, [timezoneFromProps]); - const showPlaceholderContent = timezone === null; + const showPlaceholderContent = timezone === undefined; - const titleDateFormatted = formatDate(date).toLocaleUpperCase(); + const titleDateFormatted = formatDate(date, undefined, timezone) + .toLocaleUpperCase(); const title = titleLabel ? `${titleLabel}: ${titleDateFormatted}` @@ -47,20 +49,20 @@ export default function ResponsiveDate({ className={clsx('xs:hidden', contentClass)} aria-hidden > - {formatDate(date, 'short', showPlaceholderContent)} + {formatDate(date, 'short', timezone, showPlaceholderContent)} {/* Medium */} - {formatDate(date, 'medium', showPlaceholderContent)} + {formatDate(date, 'medium', timezone,showPlaceholderContent)} {/* Large */} - {formatDate(date, undefined, showPlaceholderContent)} + {formatDate(date, undefined, timezone, showPlaceholderContent)} ); diff --git a/src/components/cmdk/CommandKClient.tsx b/src/components/cmdk/CommandKClient.tsx index e73ac731..6c36cd0a 100644 --- a/src/components/cmdk/CommandKClient.tsx +++ b/src/components/cmdk/CommandKClient.tsx @@ -48,6 +48,7 @@ import CommandKItem from './CommandKItem'; import { GRID_HOMEPAGE_ENABLED } from '@/site/config'; import { DialogDescription, DialogTitle } from '@radix-ui/react-dialog'; import * as VisuallyHidden from '@radix-ui/react-visually-hidden'; +import { Timezone } from '@/utility/timezone'; const DIALOG_TITLE = 'Global Command-K Menu'; const DIALOG_DESCRIPTION = 'For searching photos, views, and settings'; @@ -76,11 +77,13 @@ export default function CommandKClient({ serverSections = [], showDebugTools, footer, + timezone, }: { tags: Tags serverSections?: CommandKSection[] showDebugTools?: boolean footer?: string + timezone: Timezone }) { const pathname = usePathname(); @@ -166,7 +169,7 @@ export default function CommandKClient({ items: photos.map(photo => ({ label: titleForPhoto(photo), keywords: getKeywordsForPhoto(photo), - annotation: , + annotation: , accessory: , path: pathForPhoto({ photo }), })), @@ -184,7 +187,7 @@ export default function CommandKClient({ setIsLoading(false); }); } - }, [queryDebounced, isPending]); + }, [queryDebounced, isPending, timezone]); useEffect(() => { if (queryLive === '') { diff --git a/src/photo/PhotoDate.tsx b/src/photo/PhotoDate.tsx index 8966a6ba..96449f0f 100644 --- a/src/photo/PhotoDate.tsx +++ b/src/photo/PhotoDate.tsx @@ -1,16 +1,18 @@ import ResponsiveDate from '@/components/ResponsiveDate'; import { Photo } from '.'; import { useMemo } from 'react'; +import { Timezone } from '@/utility/timezone'; export default function PhotoDate({ photo, className, dateType = 'takenAt', + timezone, }: { photo: Photo className?: string dateType?: 'takenAt' | 'createdAt' | 'updatedAt' - timezone?: string | null + timezone: Timezone }) { const date = useMemo(() => { const date = new Date(dateType === 'takenAt' @@ -42,7 +44,7 @@ export default function PhotoDate({ date, className, titleLabel: getTitleLabel(), - timezone: null, + timezone, }} /> ); } diff --git a/src/photo/PhotoLarge.tsx b/src/photo/PhotoLarge.tsx index 668298f4..32befc1b 100644 --- a/src/photo/PhotoLarge.tsx +++ b/src/photo/PhotoLarge.tsx @@ -247,6 +247,9 @@ export default function PhotoLarge({ // Prevent collision with admin button !hasNonDateContent && isUserSignedIn && 'md:pr-7', )} + // Created at is a naive datetime which + // does not require a timezone + timezone={null} />
; } diff --git a/src/state/AppStateProvider.tsx b/src/state/AppStateProvider.tsx index 262b4776..8a8f1da8 100644 --- a/src/state/AppStateProvider.tsx +++ b/src/state/AppStateProvider.tsx @@ -9,6 +9,7 @@ import useSWR from 'swr'; import { HIGH_DENSITY_GRID, MATTE_PHOTOS } from '@/site/config'; import { getPhotosHiddenMetaCachedAction } from '@/photo/actions'; import { ShareModalProps } from '@/share'; +import { storeTimezoneCookie } from '@/utility/timezone'; export default function AppStateProvider({ children, @@ -77,6 +78,7 @@ export default function AppStateProvider({ useEffect(() => { setHasLoaded?.(true); + storeTimezoneCookie(); }, []); return ( diff --git a/src/utility/cookie.ts b/src/utility/cookie.ts new file mode 100644 index 00000000..c69c64de --- /dev/null +++ b/src/utility/cookie.ts @@ -0,0 +1,21 @@ +export const storeCookie = ( + name: string, + value: string, + path= '/', + maxAge = 63158400, +) => { + document.cookie = `${name}=${value};Path=${path};Max-Age=${maxAge}`; +}; + +export const getCookie = (name: string) => { + const cookie: Record = {}; + document.cookie.split(';').forEach(function(el) { + const split = el.split('='); + cookie[split[0].trim()] = split.slice(1).join('='); + }); + return cookie[name]; +}; + +export const deleteCookie = (name: string) => { + document.cookie = `${name}=;Max-Age=0`; +}; diff --git a/src/utility/date.ts b/src/utility/date.ts index 96f99c99..30662c76 100644 --- a/src/utility/date.ts +++ b/src/utility/date.ts @@ -1,4 +1,6 @@ -import { format, parseISO, parse } from 'date-fns'; +import { parseISO, parse, format } from 'date-fns'; +import { formatInTimeZone } from 'date-fns-tz'; +import { Timezone } from './timezone'; const DATE_STRING_FORMAT_TINY = 'dd MMM yy'; const DATE_STRING_FORMAT_TINY_PLACEHOLDER = '00 000 00'; @@ -21,21 +23,30 @@ type Length = 'tiny' | 'short' | 'medium' | 'long'; export const formatDate = ( date: Date, length: Length = 'long', + timezone?: Timezone, showPlaceholder?: boolean, ) => { switch (length) { case 'tiny': return showPlaceholder ? DATE_STRING_FORMAT_TINY_PLACEHOLDER - : format(date, DATE_STRING_FORMAT_TINY); + : timezone + ? formatInTimeZone(date, timezone, DATE_STRING_FORMAT_TINY) + : format(date, DATE_STRING_FORMAT_TINY); case 'short': return showPlaceholder ? DATE_STRING_FORMAT_SHORT_PLACEHOLDER - : format(date, DATE_STRING_FORMAT_SHORT); + : timezone + ? formatInTimeZone(date, timezone, DATE_STRING_FORMAT_SHORT) + : format(date, DATE_STRING_FORMAT_SHORT); case 'medium': return showPlaceholder ? DATE_STRING_FORMAT_MEDIUM_PLACEHOLDER - : format(date, DATE_STRING_FORMAT_MEDIUM); + : timezone + ? formatInTimeZone(date, timezone, DATE_STRING_FORMAT_MEDIUM) + : format(date, DATE_STRING_FORMAT_MEDIUM); default: return showPlaceholder ? DATE_STRING_FORMAT_LONG_PLACEHOLDER - : format(date, DATE_STRING_FORMAT_LONG); + : timezone + ? formatInTimeZone(date, timezone, DATE_STRING_FORMAT_LONG) + : format(date, DATE_STRING_FORMAT_LONG); } }; diff --git a/src/utility/timezone.ts b/src/utility/timezone.ts new file mode 100644 index 00000000..c9836fef --- /dev/null +++ b/src/utility/timezone.ts @@ -0,0 +1,18 @@ +import { getCookie, storeCookie } from './cookie'; + +// Timezone +// string: timezone +// undefined: timezone must be resolved on the client +// null: timezone not required +export type Timezone = string | null | undefined; + +export const TIMEZONE_COOKIE_NAME = 'client-timezone'; + +export const storeTimezoneCookie = () => + storeCookie( + TIMEZONE_COOKIE_NAME, + Intl.DateTimeFormat().resolvedOptions().timeZone, + ); + +export const getTimezoneCookie = () => + getCookie(TIMEZONE_COOKIE_NAME); From d2ea11dd79eff2cb69b58bc20701e6339d02aace Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sun, 12 Jan 2025 17:21:19 -0600 Subject: [PATCH 3/4] Tweak timezone code --- src/utility/timezone.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utility/timezone.ts b/src/utility/timezone.ts index c9836fef..ba2b689b 100644 --- a/src/utility/timezone.ts +++ b/src/utility/timezone.ts @@ -4,9 +4,9 @@ import { getCookie, storeCookie } from './cookie'; // string: timezone // undefined: timezone must be resolved on the client // null: timezone not required -export type Timezone = string | null | undefined; +export type Timezone = string | undefined | null; -export const TIMEZONE_COOKIE_NAME = 'client-timezone'; +export const TIMEZONE_COOKIE_NAME = 'timezone-client'; export const storeTimezoneCookie = () => storeCookie( From f1fc3cbbc1b964072321c21dcce761e8fd0afaad Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Sun, 12 Jan 2025 17:33:10 -0600 Subject: [PATCH 4/4] Revert to naive times in CommandK menu --- src/components/cmdk/CommandKClient.tsx | 7 ++----- src/site/CommandK.tsx | 5 ----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/components/cmdk/CommandKClient.tsx b/src/components/cmdk/CommandKClient.tsx index 6c36cd0a..bd598885 100644 --- a/src/components/cmdk/CommandKClient.tsx +++ b/src/components/cmdk/CommandKClient.tsx @@ -48,7 +48,6 @@ import CommandKItem from './CommandKItem'; import { GRID_HOMEPAGE_ENABLED } from '@/site/config'; import { DialogDescription, DialogTitle } from '@radix-ui/react-dialog'; import * as VisuallyHidden from '@radix-ui/react-visually-hidden'; -import { Timezone } from '@/utility/timezone'; const DIALOG_TITLE = 'Global Command-K Menu'; const DIALOG_DESCRIPTION = 'For searching photos, views, and settings'; @@ -77,13 +76,11 @@ export default function CommandKClient({ serverSections = [], showDebugTools, footer, - timezone, }: { tags: Tags serverSections?: CommandKSection[] showDebugTools?: boolean footer?: string - timezone: Timezone }) { const pathname = usePathname(); @@ -169,7 +166,7 @@ export default function CommandKClient({ items: photos.map(photo => ({ label: titleForPhoto(photo), keywords: getKeywordsForPhoto(photo), - annotation: , + annotation: , accessory: , path: pathForPhoto({ photo }), })), @@ -187,7 +184,7 @@ export default function CommandKClient({ setIsLoading(false); }); } - }, [queryDebounced, isPending, timezone]); + }, [queryDebounced, isPending]); useEffect(() => { if (queryLive === '') { diff --git a/src/site/CommandK.tsx b/src/site/CommandK.tsx index ddc42958..b47c2903 100644 --- a/src/site/CommandK.tsx +++ b/src/site/CommandK.tsx @@ -22,12 +22,8 @@ import { labelForFilmSimulation } from '@/vendors/fujifilm'; import { getUniqueFocalLengths } from '@/photo/db/query'; import { formatFocalLength } from '@/focal'; import { TbCone } from 'react-icons/tb'; -import { cookies } from 'next/headers'; -import { TIMEZONE_COOKIE_NAME } from '@/utility/timezone'; export default async function CommandK() { - const timezone = (await cookies()).get(TIMEZONE_COOKIE_NAME)?.value; - const [ count, tags, @@ -92,6 +88,5 @@ export default async function CommandK() { ]} showDebugTools={ADMIN_DEBUG_TOOLS_ENABLED} footer={photoQuantityText(count, false)} - timezone={timezone} />; }