diff --git a/app/about/edit/page.tsx b/app/about/edit/page.tsx index 62475055..90018f6e 100644 --- a/app/about/edit/page.tsx +++ b/app/about/edit/page.tsx @@ -1,26 +1,60 @@ import AdminAboutEditPage from '@/about/AdminAboutEditPage'; import { getAbout } from '@/about/query'; import { PRESERVE_ORIGINAL_UPLOADS } from '@/app/config'; -import { getPhotoNoStore } from '@/photo/cache'; +import { feedQueryOptions } from '@/feed'; +import { + getPhotosCached, + getPhotosMetaCached, +} from '@/photo/cache'; +import { getPhoto } from '@/photo/query'; + +const PHOTO_CHOOSER_QUERY_OPTIONS = feedQueryOptions({ + isGrid: true, + excludeFromFeeds: false, +}); export default async function AboutEditPage() { - const about = await getAbout().catch(() => undefined); + const [ + { + about, + photoAvatar, + photoHero, + }, + photos, + photosCount, + photosHidden, + ] = await Promise.all([ + getAbout().then(async about => { + const photoAvatar = about?.photoIdAvatar + ? await getPhoto(about?.photoIdAvatar ?? '', true) + .catch(() => undefined) + : undefined; - const photoAvatar = about?.photoIdAvatar - ? await getPhotoNoStore(about?.photoIdAvatar ?? '', true) - .catch(() => undefined) - : undefined; + const photoHero = about?.photoIdHero + ? await getPhoto(about?.photoIdHero ?? '', true) + .catch(() => undefined) + : undefined; - const photoHero = about?.photoIdHero - ? await getPhotoNoStore(about?.photoIdHero ?? '', true) - .catch(() => undefined) - : undefined; + return { + about, + photoAvatar, + photoHero, + }; + }), + getPhotosCached(PHOTO_CHOOSER_QUERY_OPTIONS), + getPhotosMetaCached(PHOTO_CHOOSER_QUERY_OPTIONS) + .then(({ count }) => count), + getPhotosCached({ hidden: 'only', limit: 1000 }), + ]); return ( ); diff --git a/app/full/[sortType]/[sortOrder]/page.tsx b/app/full/[sortType]/[sortOrder]/page.tsx index ec60ea4d..245ccaaa 100644 --- a/app/full/[sortType]/[sortOrder]/page.tsx +++ b/app/full/[sortType]/[sortOrder]/page.tsx @@ -8,12 +8,12 @@ import { getPhotosMetaCached } from '@/photo/cache'; import { SortProps } from '@/photo/sort'; import { getSortOptionsFromParams } from '@/photo/sort/path'; import { PhotoQueryOptions } from '@/db'; -import { FEED_META_QUERY_OPTIONS, getFeedQueryOptions } from '@/feed'; +import { FEED_META_QUERY_OPTIONS, feedQueryOptions } from '@/feed'; export const maxDuration = 60; const getPhotosCached = cache((options: PhotoQueryOptions) => - getPhotos(getFeedQueryOptions({ + getPhotos(feedQueryOptions({ isGrid: false, ...options, }))); diff --git a/app/full/page.tsx b/app/full/page.tsx index c3e17380..5dca8262 100644 --- a/app/full/page.tsx +++ b/app/full/page.tsx @@ -6,12 +6,12 @@ import { getPhotos } from '@/photo/query'; import PhotoFullPage from '@/photo/PhotoFullPage'; import { getPhotosMetaCached } from '@/photo/cache'; import { USER_DEFAULT_SORT_OPTIONS } from '@/app/config'; -import { FEED_META_QUERY_OPTIONS, getFeedQueryOptions } from '@/feed'; +import { FEED_META_QUERY_OPTIONS, feedQueryOptions } from '@/feed'; export const dynamic = 'force-static'; export const maxDuration = 60; -const getPhotosCached = cache(() => getPhotos(getFeedQueryOptions({ +const getPhotosCached = cache(() => getPhotos(feedQueryOptions({ isGrid: false, }))); diff --git a/app/grid/[sortType]/[sortOrder]/page.tsx b/app/grid/[sortType]/[sortOrder]/page.tsx index e332d7ef..041e7794 100644 --- a/app/grid/[sortType]/[sortOrder]/page.tsx +++ b/app/grid/[sortType]/[sortOrder]/page.tsx @@ -8,13 +8,13 @@ import { getDataForCategoriesCached } from '@/category/cache'; import { getPhotosMetaCached } from '@/photo/cache'; import { SortProps } from '@/photo/sort'; import { getSortOptionsFromParams } from '@/photo/sort/path'; -import { FEED_META_QUERY_OPTIONS, getFeedQueryOptions } from '@/feed'; +import { FEED_META_QUERY_OPTIONS, feedQueryOptions } from '@/feed'; import { PhotoQueryOptions } from '@/db'; export const maxDuration = 60; const getPhotosCached = cache((options: PhotoQueryOptions) => - getPhotos(getFeedQueryOptions({ + getPhotos(feedQueryOptions({ isGrid: true, ...options, }))); diff --git a/app/grid/page.tsx b/app/grid/page.tsx index ba6fe55f..b64512ef 100644 --- a/app/grid/page.tsx +++ b/app/grid/page.tsx @@ -7,12 +7,12 @@ import PhotoGridPage from '@/photo/PhotoGridPage'; import { getDataForCategoriesCached } from '@/category/cache'; import { getPhotosMetaCached } from '@/photo/cache'; import { USER_DEFAULT_SORT_OPTIONS } from '@/app/config'; -import { FEED_META_QUERY_OPTIONS, getFeedQueryOptions } from '@/feed'; +import { FEED_META_QUERY_OPTIONS, feedQueryOptions } from '@/feed'; export const dynamic = 'force-static'; export const maxDuration = 60; -const getPhotosCached = cache(() => getPhotos(getFeedQueryOptions({ +const getPhotosCached = cache(() => getPhotos(feedQueryOptions({ isGrid: true, }))); diff --git a/app/page.tsx b/app/page.tsx index f954497d..5c062cd7 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -9,12 +9,12 @@ import PhotoFullPage from '@/photo/PhotoFullPage'; import PhotoGridPage from '@/photo/PhotoGridPage'; import { getDataForCategoriesCached } from '@/category/cache'; import { getPhotosMetaCached } from '@/photo/cache'; -import { FEED_META_QUERY_OPTIONS, getFeedQueryOptions } from '@/feed'; +import { FEED_META_QUERY_OPTIONS, feedQueryOptions } from '@/feed'; export const dynamic = 'force-static'; export const maxDuration = 60; -const getPhotosCached = cache(() => getPhotos(getFeedQueryOptions({ +const getPhotosCached = cache(() => getPhotos(feedQueryOptions({ isGrid: GRID_HOMEPAGE_ENABLED, }))); diff --git a/src/about/AdminAboutEditPage.tsx b/src/about/AdminAboutEditPage.tsx index 79ba4d56..2ddadefd 100644 --- a/src/about/AdminAboutEditPage.tsx +++ b/src/about/AdminAboutEditPage.tsx @@ -14,6 +14,7 @@ import PhotoMedium from '@/photo/PhotoMedium'; import clsx from 'clsx/lite'; import useDynamicPhoto from '@/photo/useDynamicPhoto'; import { useAppText } from '@/i18n/state/client'; +import FieldsetPhotoChooser from '@/photo/form/FieldsetPhotoChooser'; export default function AdminAboutEditPage({ about, @@ -23,6 +24,9 @@ export default function AdminAboutEditPage({ about?: About photoAvatar?: Photo photoHero?: Photo + photos?: Photo[] + photosCount?: number + photosHidden?: Photo[] shouldResizeImages?: boolean }) { const appText = useAppText(); @@ -58,6 +62,13 @@ export default function AdminAboutEditPage({ action={updateAboutAction} >
+ setAboutForm(form => + ({ ...form, photoIdAvatar: convertUrlToPhotoId(photoIdAvatar) }))} + photo={photoAvatar} + /> clsx( - 'z-10', - 'min-w-[8rem]', - 'component-surface', - 'py-1', - 'not-dark:shadow-lg not-dark:shadow-gray-900/10', - 'data-[side=top]:dark:shadow-[0_0px_40px_rgba(0,0,0,0.6)]', - 'data-[side=bottom]:dark:shadow-[0_10px_40px_rgba(0,0,0,0.6)]', - 'data-[side=right]:dark:shadow-[0_10px_40px_rgba(0,0,0,0.6)]', - 'data-[side=top]:animate-fade-in-from-bottom', - 'data-[side=bottom]:animate-fade-in-from-top', - 'data-[side=right]:animate-fade-in-from-top', - className, -); +import { menuSurfaceStyles } from '../primitives/surface'; export type MoreMenuSection = { label?: string @@ -115,7 +101,7 @@ export default function MoreMenu({ onCloseAutoFocus={e => e.preventDefault()} align={align} sideOffset={sideOffset} - className={surfaceStyles(className)} + className={menuSurfaceStyles(className)} > {header &&
{item.items.map(item =>
diff --git a/src/components/primitives/TooltipPrimitive.tsx b/src/components/primitives/TooltipPrimitive.tsx index 4d7c652f..f090331a 100644 --- a/src/components/primitives/TooltipPrimitive.tsx +++ b/src/components/primitives/TooltipPrimitive.tsx @@ -2,7 +2,7 @@ import { ReactNode, useRef, useState, ComponentProps } from 'react'; import * as Tooltip from '@radix-ui/react-tooltip'; -import MenuSurface from './MenuSurface'; +import ComponentSurface from './surface/ComponentSurface'; import clsx from 'clsx/lite'; import useClickInsideOutside from '@/utility/useClickInsideOutside'; import KeyCommand from './KeyCommand'; @@ -31,7 +31,7 @@ export default function TooltipPrimitive({ children: ReactNode className?: string classNameTrigger?: string - color?: ComponentProps['color'] + color?: ComponentProps['color'] keyCommand?: string keyCommandModifier?: ComponentProps['modifier'] supportMobile?: boolean @@ -126,9 +126,9 @@ export default function TooltipPrimitive({ )} > {content && - + {content} - } + } diff --git a/src/components/primitives/MenuSurface.tsx b/src/components/primitives/surface/ComponentSurface.tsx similarity index 94% rename from src/components/primitives/MenuSurface.tsx rename to src/components/primitives/surface/ComponentSurface.tsx index f34480f1..5c339d06 100644 --- a/src/components/primitives/MenuSurface.tsx +++ b/src/components/primitives/surface/ComponentSurface.tsx @@ -1,7 +1,7 @@ import { ReactNode, RefObject } from 'react'; import clsx from 'clsx/lite'; -export default function MenuSurface({ +export default function ComponentSurface({ ref, children, className, diff --git a/src/components/primitives/surface/index.ts b/src/components/primitives/surface/index.ts new file mode 100644 index 00000000..b086f784 --- /dev/null +++ b/src/components/primitives/surface/index.ts @@ -0,0 +1,16 @@ +import clsx from 'clsx/lite'; + +export const menuSurfaceStyles = (className?: string) => clsx( + 'z-10', + 'min-w-[8rem]', + 'component-surface', + 'py-1', + 'not-dark:shadow-lg not-dark:shadow-gray-900/10', + 'data-[side=top]:dark:shadow-[0_0px_40px_rgba(0,0,0,0.6)]', + 'data-[side=bottom]:dark:shadow-[0_10px_40px_rgba(0,0,0,0.6)]', + 'data-[side=right]:dark:shadow-[0_10px_40px_rgba(0,0,0,0.6)]', + 'data-[side=top]:animate-fade-in-from-bottom', + 'data-[side=bottom]:animate-fade-in-from-top', + 'data-[side=right]:animate-fade-in-from-top', + className, +); diff --git a/src/components/shared-hover/SharedHoverProvider.tsx b/src/components/shared-hover/SharedHoverProvider.tsx index 837eb526..d089e7d6 100644 --- a/src/components/shared-hover/SharedHoverProvider.tsx +++ b/src/components/shared-hover/SharedHoverProvider.tsx @@ -10,7 +10,7 @@ import { } from 'react'; import { SharedHoverContext, SharedHoverProps } from './state'; import { AnimatePresence, motion } from 'framer-motion'; -import MenuSurface from '../primitives/MenuSurface'; +import ComponentSurface from '../primitives/surface/ComponentSurface'; import clsx from 'clsx/lite'; const WINDOW_CHANGE_EVENTS = ['mouseup', 'mousewheel', 'resize']; @@ -133,7 +133,7 @@ export default function SharedHoverProvider({ className="fixed" style={hoverStyle} > - @@ -158,7 +158,7 @@ export default function SharedHoverProvider({ : 'border-medium', )} />
- + }
diff --git a/src/components/shared-hover/state.ts b/src/components/shared-hover/state.ts index 50fa08cb..b9d95778 100644 --- a/src/components/shared-hover/state.ts +++ b/src/components/shared-hover/state.ts @@ -6,7 +6,7 @@ import { SetStateAction, use, } from 'react'; -import MenuSurface from '../primitives/MenuSurface'; +import ComponentSurface from '../primitives/surface/ComponentSurface'; export type SharedHoverProps = { key: string @@ -14,7 +14,7 @@ export type SharedHoverProps = { height: number offsetAbove: number offsetBelow: number - color?: ComponentProps['color'] + color?: ComponentProps['color'] } export type SharedHoverState = { diff --git a/src/feed/index.ts b/src/feed/index.ts index 059ad6d8..1c5f662e 100644 --- a/src/feed/index.ts +++ b/src/feed/index.ts @@ -13,21 +13,23 @@ const FEED_BASE_QUERY_OPTIONS: PhotoQueryOptions = { // PAGE FEED QUERY OPTIONS -export const getFeedQueryOptions = ({ +export const feedQueryOptions = ({ isGrid, sortBy = USER_DEFAULT_SORT_OPTIONS.sortBy, sortWithPriority = USER_DEFAULT_SORT_OPTIONS.sortWithPriority, + ...options }: { isGrid: boolean, sortBy?: SortBy, sortWithPriority?: boolean, -}): PhotoQueryOptions => ({ +} & PhotoQueryOptions): PhotoQueryOptions => ({ ...FEED_BASE_QUERY_OPTIONS, sortBy, sortWithPriority, limit: isGrid ? INFINITE_SCROLL_GRID_INITIAL : INFINITE_SCROLL_FULL_INITIAL, + ...options, }); export const FEED_META_QUERY_OPTIONS: PhotoQueryOptions = { diff --git a/src/photo/FieldsetPhotoChooser.tsx b/src/photo/form/FieldsetPhotoChooser.tsx similarity index 71% rename from src/photo/FieldsetPhotoChooser.tsx rename to src/photo/form/FieldsetPhotoChooser.tsx index e841db54..0ee6c141 100644 --- a/src/photo/FieldsetPhotoChooser.tsx +++ b/src/photo/form/FieldsetPhotoChooser.tsx @@ -1,9 +1,10 @@ import FieldsetWithStatus from '@/components/FieldsetWithStatus'; -import { altTextForPhoto, doesPhotoNeedBlurCompatibility, Photo } from '.'; +import { altTextForPhoto, doesPhotoNeedBlurCompatibility, Photo } from '..'; import clsx from 'clsx/lite'; import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; import ImageMedium from '@/components/image/ImageMedium'; -import PhotoGridInfinite from './PhotoGridInfinite'; +import PhotoGridInfinite from '../PhotoGridInfinite'; +import { menuSurfaceStyles } from '@/components/primitives/surface'; export default function FieldsetPhotoChooser({ label, @@ -24,7 +25,7 @@ export default function FieldsetPhotoChooser({