Add photo count to /grid sidebar

This commit is contained in:
Sam Becker 2023-10-21 13:11:37 -05:00
parent 068a0638a0
commit a6c1a76cc9
6 changed files with 64 additions and 37 deletions

View File

@ -4,27 +4,23 @@ import {
getUniqueCamerasCached,
getUniqueTagsCached,
} from '@/cache';
import HeaderList from '@/components/HeaderList';
import SiteGrid from '@/components/SiteGrid';
import { generateOgImageMetaForPhotos } from '@/photo';
import PhotoCamera from '@/camera/PhotoCamera';
import PhotoGrid from '@/photo/PhotoGrid';
import PhotosEmptyState from '@/photo/PhotosEmptyState';
import { MAX_PHOTOS_TO_SHOW_HOME } from '@/photo/image-response';
import { MAX_PHOTOS_TO_SHOW_OG } from '@/photo/image-response';
import { pathForGrid } from '@/site/paths';
import PhotoTag from '@/tag/PhotoTag';
import { Metadata } from 'next';
import { FaTag } from 'react-icons/fa';
import { IoMdCamera } from 'react-icons/io';
import {
PaginationParams,
getPaginationForSearchParams,
} from '@/site/pagination';
import PhotoGridSidebar from '@/photo/PhotoGridSidebar';
export const runtime = 'edge';
export async function generateMetadata(): Promise<Metadata> {
const photos = await getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_HOME});
const photos = await getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG });
return generateOgImageMetaForPhotos(photos);
}
@ -33,7 +29,7 @@ export default async function GridPage({ searchParams }: PaginationParams) {
const [
photos,
count,
photosCount,
tags,
cameras,
] = await Promise.all([
@ -43,7 +39,7 @@ export default async function GridPage({ searchParams }: PaginationParams) {
getUniqueCamerasCached(),
]);
const showMorePath = count > photos.length
const showMorePath = photosCount > photos.length
? pathForGrid(offset + 1)
: undefined;
@ -52,27 +48,7 @@ export default async function GridPage({ searchParams }: PaginationParams) {
? <SiteGrid
contentMain={<PhotoGrid {...{ photos, showMorePath }} />}
contentSide={<div className="sticky top-4 space-y-4">
{tags.length > 0 && <HeaderList
title='Tags'
icon={<FaTag size={12} />}
items={tags.map(tag =>
<PhotoTag
key={tag}
tag={tag}
showIcon={false}
/>)}
/>}
{cameras.length > 0 && <HeaderList
title="Cameras"
icon={<IoMdCamera size={13} />}
items={cameras.map(({ cameraKey, camera }) =>
<PhotoCamera
key={cameraKey}
camera={camera}
showIcon={false}
hideApple
/>)}
/>}
<PhotoGridSidebar {...{ tags, cameras, photosCount }} />
</div>}
sideHiddenOnMobile
/>

View File

@ -2,7 +2,7 @@ import { auth } from '@/auth';
import { getImageCacheHeadersForAuth, getPhotosCached } from '@/cache';
import {
IMAGE_OG_SMALL_SIZE,
MAX_PHOTOS_TO_SHOW_HOME,
MAX_PHOTOS_TO_SHOW_OG,
} from '@/photo/image-response';
import HomeImageResponse from '@/photo/image-response/HomeImageResponse';
import { getIBMPlexMonoMedium } from '@/site/font';
@ -16,7 +16,7 @@ export async function GET() {
headers,
{ fontFamily, fonts },
] = await Promise.all([
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_HOME }),
getPhotosCached({ limit: MAX_PHOTOS_TO_SHOW_OG }),
getImageCacheHeadersForAuth(await auth()),
getIBMPlexMonoMedium(),
]);

View File

@ -8,6 +8,11 @@ export type Camera = {
model: string
};
export type Cameras = {
cameraKey: string
camera: Camera
}[];
export const createCameraKey = ({ make, model }: Camera) =>
parameterize(`${make}-${model}`);

View File

@ -0,0 +1,47 @@
import { Cameras } from '@/camera';
import PhotoCamera from '@/camera/PhotoCamera';
import HeaderList from '@/components/HeaderList';
import PhotoTag from '@/tag/PhotoTag';
import { FaTag } from 'react-icons/fa';
import { IoMdCamera } from 'react-icons/io';
import { photoQuantityText } from '.';
export default function PhotoGridSidebar({
tags,
cameras,
photosCount,
}: {
tags: string[]
cameras: Cameras
photosCount: number
}) {
return (
<>
{tags.length > 0 && <HeaderList
title='Tags'
icon={<FaTag size={12} />}
items={tags.map(tag =>
<PhotoTag
key={tag}
tag={tag}
showIcon={false}
/>)}
/>}
{cameras.length > 0 && <HeaderList
title="Cameras"
icon={<IoMdCamera size={13} />}
items={cameras.map(({ cameraKey, camera }) =>
<PhotoCamera
key={cameraKey}
camera={camera}
showIcon={false}
hideApple
/>)}
/>}
{photosCount > 0 &&
<div className="text-dim uppercase">
{photoQuantityText(photosCount, false)}
</div>}
</>
);
}

View File

@ -1,6 +1,6 @@
import { NextImageSize } from '@/utility/image';
export const MAX_PHOTOS_TO_SHOW_HOME = 12;
export const MAX_PHOTOS_TO_SHOW_OG = 12;
export const MAX_PHOTOS_TO_SHOW_PER_TAG = 6;
export const MAX_PHOTOS_TO_SHOW_TEMPLATE = 16;
export const MAX_PHOTOS_TO_SHOW_TEMPLATE_TIGHT = 12;

View File

@ -7,7 +7,7 @@ import {
Photo,
PhotoDateRange,
} from '@/photo';
import { Camera, createCameraKey } from '@/camera';
import { Camera, Cameras, createCameraKey } from '@/camera';
import { parameterize } from '@/utility/string';
const PHOTO_DEFAULT_LIMIT = 100;
@ -300,14 +300,13 @@ const sqlGetUniqueTagsWithCount = async () => sql`
count: parseInt(row.count, 10),
})));
const sqlGetUniqueCameras = async () => sql`
SELECT DISTINCT make||' '||model as camera, make, model FROM photos
WHERE hidden IS NOT TRUE
ORDER BY camera ASC
`.then(({ rows }) => rows.map(({ make, model }) => ({
`.then(({ rows }): Cameras => rows.map(({ make, model }) => ({
cameraKey: createCameraKey({ make, model }),
camera: { make, model } as Camera,
camera: { make, model },
})));
export type GetPhotosOptions = {