Refactor photo/menu form components
This commit is contained in:
parent
741bcf32f7
commit
dddf1f39c5
@ -1,26 +1,60 @@
|
|||||||
import AdminAboutEditPage from '@/about/AdminAboutEditPage';
|
import AdminAboutEditPage from '@/about/AdminAboutEditPage';
|
||||||
import { getAbout } from '@/about/query';
|
import { getAbout } from '@/about/query';
|
||||||
import { PRESERVE_ORIGINAL_UPLOADS } from '@/app/config';
|
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() {
|
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
|
const photoAvatar = about?.photoIdAvatar
|
||||||
? await getPhotoNoStore(about?.photoIdAvatar ?? '', true)
|
? await getPhoto(about?.photoIdAvatar ?? '', true)
|
||||||
.catch(() => undefined)
|
.catch(() => undefined)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
const photoHero = about?.photoIdHero
|
const photoHero = about?.photoIdHero
|
||||||
? await getPhotoNoStore(about?.photoIdHero ?? '', true)
|
? await getPhoto(about?.photoIdHero ?? '', true)
|
||||||
.catch(() => undefined)
|
.catch(() => undefined)
|
||||||
: 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 (
|
return (
|
||||||
<AdminAboutEditPage {...{
|
<AdminAboutEditPage {...{
|
||||||
about,
|
about,
|
||||||
photoAvatar,
|
photoAvatar,
|
||||||
photoHero,
|
photoHero,
|
||||||
|
photos,
|
||||||
|
photosCount,
|
||||||
|
photosHidden,
|
||||||
shouldResizeImages: !PRESERVE_ORIGINAL_UPLOADS,
|
shouldResizeImages: !PRESERVE_ORIGINAL_UPLOADS,
|
||||||
}} />
|
}} />
|
||||||
);
|
);
|
||||||
|
|||||||
@ -8,12 +8,12 @@ import { getPhotosMetaCached } from '@/photo/cache';
|
|||||||
import { SortProps } from '@/photo/sort';
|
import { SortProps } from '@/photo/sort';
|
||||||
import { getSortOptionsFromParams } from '@/photo/sort/path';
|
import { getSortOptionsFromParams } from '@/photo/sort/path';
|
||||||
import { PhotoQueryOptions } from '@/db';
|
import { PhotoQueryOptions } from '@/db';
|
||||||
import { FEED_META_QUERY_OPTIONS, getFeedQueryOptions } from '@/feed';
|
import { FEED_META_QUERY_OPTIONS, feedQueryOptions } from '@/feed';
|
||||||
|
|
||||||
export const maxDuration = 60;
|
export const maxDuration = 60;
|
||||||
|
|
||||||
const getPhotosCached = cache((options: PhotoQueryOptions) =>
|
const getPhotosCached = cache((options: PhotoQueryOptions) =>
|
||||||
getPhotos(getFeedQueryOptions({
|
getPhotos(feedQueryOptions({
|
||||||
isGrid: false,
|
isGrid: false,
|
||||||
...options,
|
...options,
|
||||||
})));
|
})));
|
||||||
|
|||||||
@ -6,12 +6,12 @@ import { getPhotos } from '@/photo/query';
|
|||||||
import PhotoFullPage from '@/photo/PhotoFullPage';
|
import PhotoFullPage from '@/photo/PhotoFullPage';
|
||||||
import { getPhotosMetaCached } from '@/photo/cache';
|
import { getPhotosMetaCached } from '@/photo/cache';
|
||||||
import { USER_DEFAULT_SORT_OPTIONS } from '@/app/config';
|
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 dynamic = 'force-static';
|
||||||
export const maxDuration = 60;
|
export const maxDuration = 60;
|
||||||
|
|
||||||
const getPhotosCached = cache(() => getPhotos(getFeedQueryOptions({
|
const getPhotosCached = cache(() => getPhotos(feedQueryOptions({
|
||||||
isGrid: false,
|
isGrid: false,
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
|||||||
@ -8,13 +8,13 @@ import { getDataForCategoriesCached } from '@/category/cache';
|
|||||||
import { getPhotosMetaCached } from '@/photo/cache';
|
import { getPhotosMetaCached } from '@/photo/cache';
|
||||||
import { SortProps } from '@/photo/sort';
|
import { SortProps } from '@/photo/sort';
|
||||||
import { getSortOptionsFromParams } from '@/photo/sort/path';
|
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';
|
import { PhotoQueryOptions } from '@/db';
|
||||||
|
|
||||||
export const maxDuration = 60;
|
export const maxDuration = 60;
|
||||||
|
|
||||||
const getPhotosCached = cache((options: PhotoQueryOptions) =>
|
const getPhotosCached = cache((options: PhotoQueryOptions) =>
|
||||||
getPhotos(getFeedQueryOptions({
|
getPhotos(feedQueryOptions({
|
||||||
isGrid: true,
|
isGrid: true,
|
||||||
...options,
|
...options,
|
||||||
})));
|
})));
|
||||||
|
|||||||
@ -7,12 +7,12 @@ import PhotoGridPage from '@/photo/PhotoGridPage';
|
|||||||
import { getDataForCategoriesCached } from '@/category/cache';
|
import { getDataForCategoriesCached } from '@/category/cache';
|
||||||
import { getPhotosMetaCached } from '@/photo/cache';
|
import { getPhotosMetaCached } from '@/photo/cache';
|
||||||
import { USER_DEFAULT_SORT_OPTIONS } from '@/app/config';
|
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 dynamic = 'force-static';
|
||||||
export const maxDuration = 60;
|
export const maxDuration = 60;
|
||||||
|
|
||||||
const getPhotosCached = cache(() => getPhotos(getFeedQueryOptions({
|
const getPhotosCached = cache(() => getPhotos(feedQueryOptions({
|
||||||
isGrid: true,
|
isGrid: true,
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
|||||||
@ -9,12 +9,12 @@ import PhotoFullPage from '@/photo/PhotoFullPage';
|
|||||||
import PhotoGridPage from '@/photo/PhotoGridPage';
|
import PhotoGridPage from '@/photo/PhotoGridPage';
|
||||||
import { getDataForCategoriesCached } from '@/category/cache';
|
import { getDataForCategoriesCached } from '@/category/cache';
|
||||||
import { getPhotosMetaCached } from '@/photo/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 dynamic = 'force-static';
|
||||||
export const maxDuration = 60;
|
export const maxDuration = 60;
|
||||||
|
|
||||||
const getPhotosCached = cache(() => getPhotos(getFeedQueryOptions({
|
const getPhotosCached = cache(() => getPhotos(feedQueryOptions({
|
||||||
isGrid: GRID_HOMEPAGE_ENABLED,
|
isGrid: GRID_HOMEPAGE_ENABLED,
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import PhotoMedium from '@/photo/PhotoMedium';
|
|||||||
import clsx from 'clsx/lite';
|
import clsx from 'clsx/lite';
|
||||||
import useDynamicPhoto from '@/photo/useDynamicPhoto';
|
import useDynamicPhoto from '@/photo/useDynamicPhoto';
|
||||||
import { useAppText } from '@/i18n/state/client';
|
import { useAppText } from '@/i18n/state/client';
|
||||||
|
import FieldsetPhotoChooser from '@/photo/form/FieldsetPhotoChooser';
|
||||||
|
|
||||||
export default function AdminAboutEditPage({
|
export default function AdminAboutEditPage({
|
||||||
about,
|
about,
|
||||||
@ -23,6 +24,9 @@ export default function AdminAboutEditPage({
|
|||||||
about?: About
|
about?: About
|
||||||
photoAvatar?: Photo
|
photoAvatar?: Photo
|
||||||
photoHero?: Photo
|
photoHero?: Photo
|
||||||
|
photos?: Photo[]
|
||||||
|
photosCount?: number
|
||||||
|
photosHidden?: Photo[]
|
||||||
shouldResizeImages?: boolean
|
shouldResizeImages?: boolean
|
||||||
}) {
|
}) {
|
||||||
const appText = useAppText();
|
const appText = useAppText();
|
||||||
@ -58,6 +62,13 @@ export default function AdminAboutEditPage({
|
|||||||
action={updateAboutAction}
|
action={updateAboutAction}
|
||||||
>
|
>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
<FieldsetPhotoChooser
|
||||||
|
label="Avatar Photo"
|
||||||
|
value={aboutForm?.photoIdAvatar ?? ''}
|
||||||
|
onChange={photoIdAvatar => setAboutForm(form =>
|
||||||
|
({ ...form, photoIdAvatar: convertUrlToPhotoId(photoIdAvatar) }))}
|
||||||
|
photo={photoAvatar}
|
||||||
|
/>
|
||||||
<PhotoAvatar photo={photoAvatar} />
|
<PhotoAvatar photo={photoAvatar} />
|
||||||
<FieldsetWithStatus
|
<FieldsetWithStatus
|
||||||
id="photoIdAvatar"
|
id="photoIdAvatar"
|
||||||
|
|||||||
@ -10,8 +10,8 @@ import StatusIcon from '@/components/StatusIcon';
|
|||||||
import clsx from 'clsx/lite';
|
import clsx from 'clsx/lite';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Photo } from '@/photo';
|
import { Photo } from '@/photo';
|
||||||
import FieldsetPhotoQuery from '@/photo/FieldsetPhotoQuery';
|
import FieldsetPhotoQuery from '@/photo/form/FieldsetPhotoQuery';
|
||||||
import FieldsetPhotoChooser from '@/photo/FieldsetPhotoChooser';
|
import FieldsetPhotoChooser from '@/photo/form/FieldsetPhotoChooser';
|
||||||
|
|
||||||
export default function ComponentsPageClient({
|
export default function ComponentsPageClient({
|
||||||
photo,
|
photo,
|
||||||
|
|||||||
@ -11,21 +11,7 @@ import { FiMoreHorizontal } from 'react-icons/fi';
|
|||||||
import MoreMenuItem from './MoreMenuItem';
|
import MoreMenuItem from './MoreMenuItem';
|
||||||
import { clearGlobalFocus } from '@/utility/dom';
|
import { clearGlobalFocus } from '@/utility/dom';
|
||||||
import { FaChevronRight } from 'react-icons/fa6';
|
import { FaChevronRight } from 'react-icons/fa6';
|
||||||
|
import { menuSurfaceStyles } from '../primitives/surface';
|
||||||
const surfaceStyles = (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,
|
|
||||||
);
|
|
||||||
|
|
||||||
export type MoreMenuSection = {
|
export type MoreMenuSection = {
|
||||||
label?: string
|
label?: string
|
||||||
@ -115,7 +101,7 @@ export default function MoreMenu({
|
|||||||
onCloseAutoFocus={e => e.preventDefault()}
|
onCloseAutoFocus={e => e.preventDefault()}
|
||||||
align={align}
|
align={align}
|
||||||
sideOffset={sideOffset}
|
sideOffset={sideOffset}
|
||||||
className={surfaceStyles(className)}
|
className={menuSurfaceStyles(className)}
|
||||||
>
|
>
|
||||||
{header && <div className={clsx(
|
{header && <div className={clsx(
|
||||||
'px-3 pt-3 pb-2 text-dim uppercase',
|
'px-3 pt-3 pb-2 text-dim uppercase',
|
||||||
@ -171,7 +157,7 @@ export default function MoreMenu({
|
|||||||
</DropdownMenu.SubTrigger>
|
</DropdownMenu.SubTrigger>
|
||||||
<DropdownMenu.Portal>
|
<DropdownMenu.Portal>
|
||||||
<DropdownMenu.SubContent
|
<DropdownMenu.SubContent
|
||||||
className={surfaceStyles()}
|
className={menuSurfaceStyles()}
|
||||||
>
|
>
|
||||||
{item.items.map(item =>
|
{item.items.map(item =>
|
||||||
<div key={item.label} className="px-1">
|
<div key={item.label} className="px-1">
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { ReactNode, useRef, useState, ComponentProps } from 'react';
|
import { ReactNode, useRef, useState, ComponentProps } from 'react';
|
||||||
import * as Tooltip from '@radix-ui/react-tooltip';
|
import * as Tooltip from '@radix-ui/react-tooltip';
|
||||||
import MenuSurface from './MenuSurface';
|
import ComponentSurface from './surface/ComponentSurface';
|
||||||
import clsx from 'clsx/lite';
|
import clsx from 'clsx/lite';
|
||||||
import useClickInsideOutside from '@/utility/useClickInsideOutside';
|
import useClickInsideOutside from '@/utility/useClickInsideOutside';
|
||||||
import KeyCommand from './KeyCommand';
|
import KeyCommand from './KeyCommand';
|
||||||
@ -31,7 +31,7 @@ export default function TooltipPrimitive({
|
|||||||
children: ReactNode
|
children: ReactNode
|
||||||
className?: string
|
className?: string
|
||||||
classNameTrigger?: string
|
classNameTrigger?: string
|
||||||
color?: ComponentProps<typeof MenuSurface>['color']
|
color?: ComponentProps<typeof ComponentSurface>['color']
|
||||||
keyCommand?: string
|
keyCommand?: string
|
||||||
keyCommandModifier?: ComponentProps<typeof KeyCommand>['modifier']
|
keyCommandModifier?: ComponentProps<typeof KeyCommand>['modifier']
|
||||||
supportMobile?: boolean
|
supportMobile?: boolean
|
||||||
@ -126,9 +126,9 @@ export default function TooltipPrimitive({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{content &&
|
{content &&
|
||||||
<MenuSurface {...{ color, className }}>
|
<ComponentSurface {...{ color, className }}>
|
||||||
{content}
|
{content}
|
||||||
</MenuSurface>}
|
</ComponentSurface>}
|
||||||
</Tooltip.Content>
|
</Tooltip.Content>
|
||||||
</Tooltip.Portal>
|
</Tooltip.Portal>
|
||||||
</Tooltip.Root>
|
</Tooltip.Root>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { ReactNode, RefObject } from 'react';
|
import { ReactNode, RefObject } from 'react';
|
||||||
import clsx from 'clsx/lite';
|
import clsx from 'clsx/lite';
|
||||||
|
|
||||||
export default function MenuSurface({
|
export default function ComponentSurface({
|
||||||
ref,
|
ref,
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
16
src/components/primitives/surface/index.ts
Normal file
16
src/components/primitives/surface/index.ts
Normal file
@ -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,
|
||||||
|
);
|
||||||
@ -10,7 +10,7 @@ import {
|
|||||||
} from 'react';
|
} from 'react';
|
||||||
import { SharedHoverContext, SharedHoverProps } from './state';
|
import { SharedHoverContext, SharedHoverProps } from './state';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import MenuSurface from '../primitives/MenuSurface';
|
import ComponentSurface from '../primitives/surface/ComponentSurface';
|
||||||
import clsx from 'clsx/lite';
|
import clsx from 'clsx/lite';
|
||||||
|
|
||||||
const WINDOW_CHANGE_EVENTS = ['mouseup', 'mousewheel', 'resize'];
|
const WINDOW_CHANGE_EVENTS = ['mouseup', 'mousewheel', 'resize'];
|
||||||
@ -133,7 +133,7 @@ export default function SharedHoverProvider({
|
|||||||
className="fixed"
|
className="fixed"
|
||||||
style={hoverStyle}
|
style={hoverStyle}
|
||||||
>
|
>
|
||||||
<MenuSurface
|
<ComponentSurface
|
||||||
className="max-w-none p-1!"
|
className="max-w-none p-1!"
|
||||||
color={hoverProps.color}
|
color={hoverProps.color}
|
||||||
>
|
>
|
||||||
@ -158,7 +158,7 @@ export default function SharedHoverProvider({
|
|||||||
: 'border-medium',
|
: 'border-medium',
|
||||||
)} />
|
)} />
|
||||||
</div>
|
</div>
|
||||||
</MenuSurface>
|
</ComponentSurface>
|
||||||
</motion.div>}
|
</motion.div>}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import {
|
|||||||
SetStateAction,
|
SetStateAction,
|
||||||
use,
|
use,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import MenuSurface from '../primitives/MenuSurface';
|
import ComponentSurface from '../primitives/surface/ComponentSurface';
|
||||||
|
|
||||||
export type SharedHoverProps = {
|
export type SharedHoverProps = {
|
||||||
key: string
|
key: string
|
||||||
@ -14,7 +14,7 @@ export type SharedHoverProps = {
|
|||||||
height: number
|
height: number
|
||||||
offsetAbove: number
|
offsetAbove: number
|
||||||
offsetBelow: number
|
offsetBelow: number
|
||||||
color?: ComponentProps<typeof MenuSurface>['color']
|
color?: ComponentProps<typeof ComponentSurface>['color']
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SharedHoverState = {
|
export type SharedHoverState = {
|
||||||
|
|||||||
@ -13,21 +13,23 @@ const FEED_BASE_QUERY_OPTIONS: PhotoQueryOptions = {
|
|||||||
|
|
||||||
// PAGE FEED QUERY OPTIONS
|
// PAGE FEED QUERY OPTIONS
|
||||||
|
|
||||||
export const getFeedQueryOptions = ({
|
export const feedQueryOptions = ({
|
||||||
isGrid,
|
isGrid,
|
||||||
sortBy = USER_DEFAULT_SORT_OPTIONS.sortBy,
|
sortBy = USER_DEFAULT_SORT_OPTIONS.sortBy,
|
||||||
sortWithPriority = USER_DEFAULT_SORT_OPTIONS.sortWithPriority,
|
sortWithPriority = USER_DEFAULT_SORT_OPTIONS.sortWithPriority,
|
||||||
|
...options
|
||||||
}: {
|
}: {
|
||||||
isGrid: boolean,
|
isGrid: boolean,
|
||||||
sortBy?: SortBy,
|
sortBy?: SortBy,
|
||||||
sortWithPriority?: boolean,
|
sortWithPriority?: boolean,
|
||||||
}): PhotoQueryOptions => ({
|
} & PhotoQueryOptions): PhotoQueryOptions => ({
|
||||||
...FEED_BASE_QUERY_OPTIONS,
|
...FEED_BASE_QUERY_OPTIONS,
|
||||||
sortBy,
|
sortBy,
|
||||||
sortWithPriority,
|
sortWithPriority,
|
||||||
limit: isGrid
|
limit: isGrid
|
||||||
? INFINITE_SCROLL_GRID_INITIAL
|
? INFINITE_SCROLL_GRID_INITIAL
|
||||||
: INFINITE_SCROLL_FULL_INITIAL,
|
: INFINITE_SCROLL_FULL_INITIAL,
|
||||||
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const FEED_META_QUERY_OPTIONS: PhotoQueryOptions = {
|
export const FEED_META_QUERY_OPTIONS: PhotoQueryOptions = {
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import FieldsetWithStatus from '@/components/FieldsetWithStatus';
|
import FieldsetWithStatus from '@/components/FieldsetWithStatus';
|
||||||
import { altTextForPhoto, doesPhotoNeedBlurCompatibility, Photo } from '.';
|
import { altTextForPhoto, doesPhotoNeedBlurCompatibility, Photo } from '..';
|
||||||
import clsx from 'clsx/lite';
|
import clsx from 'clsx/lite';
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
||||||
import ImageMedium from '@/components/image/ImageMedium';
|
import ImageMedium from '@/components/image/ImageMedium';
|
||||||
import PhotoGridInfinite from './PhotoGridInfinite';
|
import PhotoGridInfinite from '../PhotoGridInfinite';
|
||||||
|
import { menuSurfaceStyles } from '@/components/primitives/surface';
|
||||||
|
|
||||||
export default function FieldsetPhotoChooser({
|
export default function FieldsetPhotoChooser({
|
||||||
label,
|
label,
|
||||||
@ -24,7 +25,7 @@ export default function FieldsetPhotoChooser({
|
|||||||
<button type="button" className="p-1.5">
|
<button type="button" className="p-1.5">
|
||||||
{photo &&
|
{photo &&
|
||||||
<span className={clsx(
|
<span className={clsx(
|
||||||
'flex w-[8rem]',
|
'flex size-[6rem]',
|
||||||
'border border-medium rounded-[4px]',
|
'border border-medium rounded-[4px]',
|
||||||
'overflow-hidden select-none active:opacity-75',
|
'overflow-hidden select-none active:opacity-75',
|
||||||
)}>
|
)}>
|
||||||
@ -43,20 +44,7 @@ export default function FieldsetPhotoChooser({
|
|||||||
onCloseAutoFocus={e => e.preventDefault()}
|
onCloseAutoFocus={e => e.preventDefault()}
|
||||||
align="start"
|
align="start"
|
||||||
sideOffset={10}
|
sideOffset={10}
|
||||||
// alignOffset={-10}
|
className={menuSurfaceStyles('z-20 px-1.5 py-1.5')}>
|
||||||
className={clsx(
|
|
||||||
'z-20',
|
|
||||||
'min-w-[8rem]',
|
|
||||||
'component-surface',
|
|
||||||
'p-1.5',
|
|
||||||
'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',
|
|
||||||
)}>
|
|
||||||
<div className={clsx(
|
<div className={clsx(
|
||||||
'w-[14rem] max-h-[20rem] rounded-[3px] overflow-y-auto',
|
'w-[14rem] max-h-[20rem] rounded-[3px] overflow-y-auto',
|
||||||
'space-y-1',
|
'space-y-1',
|
||||||
@ -1,12 +1,12 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import FieldsetWithStatus from '@/components/FieldsetWithStatus';
|
import FieldsetWithStatus from '@/components/FieldsetWithStatus';
|
||||||
import { Photo } from '.';
|
import { Photo } from '..';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { AnnotatedTag } from './form';
|
import { AnnotatedTag } from '../form';
|
||||||
import { useDebounce } from 'use-debounce';
|
import { useDebounce } from 'use-debounce';
|
||||||
import PhotoSmall from './PhotoSmall';
|
import PhotoSmall from '../PhotoSmall';
|
||||||
import { getPhotosAction } from './actions';
|
import { getPhotosAction } from '../actions';
|
||||||
|
|
||||||
const convertPhotoToAnnotatedTag = (photo: Photo): AnnotatedTag => ({
|
const convertPhotoToAnnotatedTag = (photo: Photo): AnnotatedTag => ({
|
||||||
value: photo.id,
|
value: photo.id,
|
||||||
Loading…
Reference in New Issue
Block a user