Skip to content

Commit 9010812

Browse files
committed
chore: 3-loop maintenance pass — i18n coverage, dead-code cleanup, JSON-LD locale fix
Loop 1 — dead code & i18n base: - Remove empty src/lib/hooks/ directory. - Delete unused public/images/samples/example.jpg (~158KB) and public/scenes/thumbnails/* (6 files, ~70KB) — DofScene `thumbnail` field was defined but never read in any UI. - Drop the dead `thumbnail` field from DofScene. - i18n LanguageSwitcher's "Change language" / "Select language" aria-labels (shown on every page in every locale). - i18n the perspective-compression simulator's "Sensor" aria-label. Loop 2 — i18n templates, dead fields, JSON-LD locale awareness: - Add ICU-templated controls aria-labels (apertureValue, focalLengthValue, subjectDistanceValue, sweetSpotValue) and wire them into ApertureField, FocalLengthField, and CompressionControls — replaces hardcoded "Aperture: f/2.8" / "Focal length: 50mm" / "Subject distance: 12.5 ft" / "Sweet spot: f/8" templates. - Remove the dead `altText` field from Scene (and its test) — it was never read by any consumer. - Fix glossary FAQPage JSON-LD: was generating hardcoded English "What is X in photography?" for every locale; now uses a translatable `questionTemplate` and adds the missing `inLanguage` field. Mirror the fix on privacy/terms/about/contact JSON-LD — they now include `inLanguage` and a locale-prefixed `url`, preventing every locale's structured data from claiming the English `/privacy` URL. - Add `apsh` (APS-H) translation key — was a missing sensor falling through to the English fallback name. - AdUnit: drop a redundant `if (ins)` guard after an early-return null check on the same ref. Loop 3 — final i18n + memory leak: - i18n the FaqSection heading "Frequently Asked Questions" — high- impact since it renders on every tool page in every locale. - Add `loading="lazy"` + `decoding="async"` to exposure-simulator scene thumbnails. - Fix a small blob URL leak in frame-studio: `URL.createObjectURL` was created on each handleFile call and never revoked, so each upload after the first leaked the previous URL until GC. Now we revoke once the Image has decoded. All 872 unit tests, 122 chromium smoke specs, and 85 chromium tool e2e specs pass. Type-check and lint clean. Translation coverage verified across all 31 locales; no hard English leaks introduced.
1 parent a9b49e5 commit 9010812

85 files changed

Lines changed: 514 additions & 65 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

public/images/samples/example.jpg

-154 KB
Binary file not shown.
-4.63 KB
Binary file not shown.

public/scenes/thumbnails/cafe.jpg

-4.39 KB
Binary file not shown.
-4.47 KB
Binary file not shown.

public/scenes/thumbnails/macro.jpg

-3.85 KB
Binary file not shown.
-5.1 KB
Binary file not shown.
-4.8 KB
Binary file not shown.

src/app/[locale]/about/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export default async function AboutPage({ params }: { params: Promise<{ locale:
3333
'@context': 'https://schema.org',
3434
'@type': 'AboutPage',
3535
name: t('title'),
36-
url: 'https://www.phototools.io/about',
36+
url: `https://www.phototools.io/${locale}/about`,
37+
inLanguage: locale,
3738
}
3839

3940
return (

src/app/[locale]/contact/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ export default async function ContactPage({ params }: { params: Promise<{ locale
2525
'@context': 'https://schema.org',
2626
'@type': 'ContactPage',
2727
name: t('title'),
28-
url: 'https://www.phototools.io/contact',
28+
url: `https://www.phototools.io/${locale}/contact`,
29+
inLanguage: locale,
2930
}
3031

3132
return (

src/app/[locale]/exposure-simulator/_components/ExposurePreview.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export function ExposurePreview({ aperture, shutterSpeed, iso }: ExposurePreview
4747
alt={label}
4848
width={48}
4949
height={32}
50+
loading="lazy"
51+
decoding="async"
5052
/>
5153
</button>
5254
)
@@ -62,6 +64,7 @@ export function ExposurePreview({ aperture, shutterSpeed, iso }: ExposurePreview
6264
src={currentScene.assets.photo}
6365
alt={t(currentScene.labelKey as Parameters<typeof t>[0])}
6466
className={styles.fallbackImg}
67+
decoding="async"
6568
/>
6669
<p>{error}. {t('imageEffectsUnavailable')}</p>
6770
</div>

0 commit comments

Comments
 (0)