Introduce configuration preventing blur data being stored and displayed

This commit is contained in:
Sam Becker 2024-01-28 11:52:04 -06:00
parent f912f2cbb2
commit 908db18fb0
8 changed files with 54 additions and 11 deletions

View File

@ -63,6 +63,7 @@ Installation
### 6. Optional configuration
- `NEXT_PUBLIC_PRO_MODE = 1` enables higher quality image storage
- `NEXT_PUBLIC_BLUR_DISABLED = 1` prevents image blur data being stored and displayed
- `NEXT_PUBLIC_GEO_PRIVACY = 1` disables collection/display of location-based data
- `NEXT_PUBLIC_IGNORE_PRIORITY_ORDER = 1` prevents `priority_order` field affecting photo order
- `NEXT_PUBLIC_PUBLIC_API = 1` enables public API available at `/api`

View File

@ -0,0 +1,30 @@
'use client';
import { BLUR_DISABLED } from '@/site/config';
import { useTheme } from 'next-themes';
import Image, { ImageProps } from 'next/image';
// Based on bg-gray-100/50 (#f9f9fa)
// eslint-disable-next-line max-len
const BLUR_DATA_LIGHT = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAACXBIWXMAAC4jAAAuIwF4pT92AAAADElEQVQImWP4+fMXAAXbAu0I+kpzAAAAAElFTkSuQmCC';
// Based on bg-gray-900/50 (#090c14)
// eslint-disable-next-line max-len
const BLUR_DATA_DARK = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAACXBIWXMAAC4jAAAuIwF4pT92AAAADElEQVQImWPg5BEBAABLACpEF6ULAAAAAElFTkSuQmCC';
export default function ImageBlurFallback(props: ImageProps) {
const { resolvedTheme } = useTheme();
const blueFallback = resolvedTheme === 'dark'
? BLUR_DATA_DARK
: BLUR_DATA_LIGHT;
return (
// eslint-disable-next-line jsx-a11y/alt-text
<Image {...{
...props,
blurDataURL: !BLUR_DISABLED && props.blurDataURL
? props.blurDataURL
: blueFallback,
placeholder: 'blur',
}} />
);
}

View File

@ -1,6 +1,6 @@
import { IMAGE_LARGE_WIDTH } from '@/site';
import Image from 'next/image';
import Link from 'next/link';
import ImageBlurFallback from './ImageBlurFallback';
export default function ImageLarge({
className,
@ -16,7 +16,7 @@ export default function ImageLarge({
src: string
alt: string
aspectRatio: number
blurData: string
blurData?: string
priority?: boolean
}) {
return (
@ -24,13 +24,12 @@ export default function ImageLarge({
href={href}
className="active:brightness-75"
>
<Image {...{
<ImageBlurFallback {...{
className,
src,
alt,
priority,
blurDataURL: blurData,
placeholder: 'blur',
width: IMAGE_LARGE_WIDTH,
height: Math.round(IMAGE_LARGE_WIDTH / aspectRatio),
}} />

View File

@ -1,5 +1,5 @@
import { IMAGE_SMALL_WIDTH } from '@/site';
import Image from 'next/image';
import ImageBlurFallback from './ImageBlurFallback';
export default function ImageSmall({
className,
@ -12,10 +12,10 @@ export default function ImageSmall({
src: string
alt: string
aspectRatio: number
blurData: string
blurData?: string
}) {
return (
<Image {...{
<ImageBlurFallback {...{
className,
src,
alt,

View File

@ -1,5 +1,5 @@
import { IMAGE_TINY_WIDTH } from '@/site';
import Image from 'next/image';
import ImageBlurFallback from './ImageBlurFallback';
export default function ImageTiny({
className,
@ -15,7 +15,7 @@ export default function ImageTiny({
blurData?: string
}) {
return (
<Image {...{
<ImageBlurFallback {...{
className,
src,
alt,

View File

@ -9,7 +9,6 @@ import {
isFormValid,
} from './form';
import FieldSetWithStatus from '@/components/FieldSetWithStatus';
import NextImage from 'next/image';
import { createPhotoAction, updatePhotoAction } from './actions';
import SubmitButtonWithStatus from '@/components/SubmitButtonWithStatus';
import Link from 'next/link';
@ -22,6 +21,7 @@ import {
} from '@/utility/date';
import { toastSuccess, toastWarning } from '@/toast';
import { getDimensionsFromSize } from '@/utility/size';
import ImageBlurFallback from '@/components/ImageBlurFallback';
const THUMBNAIL_SIZE = 300;
@ -106,7 +106,7 @@ export default function PhotoForm({
return (
<div className="space-y-8 max-w-[38rem]">
<div className="flex gap-2">
<NextImage
<ImageBlurFallback
alt="Upload"
src={url}
className={clsx(

View File

@ -37,6 +37,7 @@ export default function SiteChecklistClient({
showFilmSimulations,
showExifInfo,
isProModeEnabled,
isBlurEnabled,
isGeoPrivacyEnabled,
isPriorityOrderEnabled,
isPublicApiEnabled,
@ -270,6 +271,16 @@ export default function SiteChecklistClient({
higher quality image storage:
{renderEnvVars(['NEXT_PUBLIC_PRO_MODE'])}
</ChecklistRow>
<ChecklistRow
title="Image Blur"
status={isBlurEnabled}
isPending={isPendingPage}
optional
>
Set environment variable to {'"1"'} to prevent
image blur data being stored and displayed
{renderEnvVars(['NEXT_PUBLIC_BLUR_DISABLED'])}
</ChecklistRow>
<ChecklistRow
title="Geo Privacy"
status={isGeoPrivacyEnabled}

View File

@ -82,6 +82,7 @@ export const CURRENT_STORAGE: StorageType =
// SETTINGS
export const PRO_MODE_ENABLED = process.env.NEXT_PUBLIC_PRO_MODE === '1';
export const BLUR_DISABLED = process.env.NEXT_PUBLIC_BLUR_DISABLED === '1';
export const GEO_PRIVACY_ENABLED = process.env.NEXT_PUBLIC_GEO_PRIVACY === '1';
export const PRIORITY_ORDER_ENABLED =
process.env.NEXT_PUBLIC_IGNORE_PRIORITY_ORDER !== '1';
@ -120,6 +121,7 @@ export const CONFIG_CHECKLIST_STATUS = {
showFilmSimulations: SHOW_FILM_SIMULATIONS,
showExifInfo: SHOW_EXIF_DATA,
isProModeEnabled: PRO_MODE_ENABLED,
isBlurEnabled: !BLUR_DISABLED,
isGeoPrivacyEnabled: GEO_PRIVACY_ENABLED,
isPriorityOrderEnabled: PRIORITY_ORDER_ENABLED,
isPublicApiEnabled: PUBLIC_API_ENABLED,