release: v0.20.0

This commit is contained in:
Ralksta
2026-10-02 18:14:23 +02:00
committed by GitHub
parent 81ce886b01
commit 5f831f719a
209 changed files with 13807 additions and 803 deletions

View File

@@ -25,6 +25,13 @@ export interface SubpageConfig {
*/
coverGrid?: Partial<GridConfig>;
proofing?: boolean;
/** Lightbox zoom for the albums here, over the site setting (#467). */
zoom?: boolean;
/**
* Album zoom overrides written on this page's album entries (sections
* included). They apply on this page only; see resolveZoom().
*/
albumZoom?: Record<string, boolean>;
essayFile?: string;
essayText?: string;
enabled?: boolean;
@@ -40,6 +47,8 @@ export interface SubpageObjectValue {
/** Album-cover tiles only; falls back to `grid` when unset (#523). */
coverGrid?: Partial<GridConfig>;
proofing?: boolean;
/** Lightbox zoom for the albums here, over the site setting (#467). */
zoom?: boolean;
essayFile?: string;
essayText?: string;
enabled?: boolean;
@@ -279,6 +288,11 @@ export interface AppConfig {
email?: string;
};
aboutEnabled: boolean;
/**
* Lightbox zoom to full resolution, site-wide (`zoom` in settings.yaml,
* off by default). Subpages and albums override it; see resolveZoom() (#467).
*/
zoom: boolean;
albumOverrides: Record<string, string>;
albumDescriptions: Record<string, string>;
albumPasswords: Record<string, string>;
@@ -293,6 +307,12 @@ export interface AppConfig {
albumCoverPositions: Record<string, string>;
/** Albums whose originals may be downloaded. Absent means no (#475). */
albumDownloads: Record<string, boolean>;
/**
* Lightbox zoom overrides on the standalone album entries, either way.
* Absent means inherit (#467). Entries inside a subpage are kept on that
* subpage (`SubpageConfig.albumZoom`), so each route answers for itself.
*/
standaloneAlbumZoom: Record<string, boolean>;
/** Per-album map precision. Absent means `exact` (#469). */
albumLocationPrecision: Record<string, LocationPrecision>;
/** EXPERIMENTAL: external links appended to the header navigation. */
@@ -338,6 +358,33 @@ export interface AppConfig {
};
}
/**
* Whether the lightbox offers zoom to full resolution for an album on one
* route (#467): the album standalone (no subpage), or on a given subpage.
*
* Most specific wins, in either direction: the album entry's own `zoom:` on
* that route, then the subpage, then `zoom` in settings.yaml (off by default).
* The same `??` chain as resolveProofing(), one level deeper — `zoom: false` on
* an album has to beat a subpage's `true`.
*
* The album override is per route on purpose. An album listed on an open page
* with `zoom: false` and on a password page with `zoom: true` must not become
* zoomable on the open one because the other entry happened to be read last.
*
* The page, the zoom route (isAlbumZoomReachable in lib/auth.ts) and the
* admin drawer (which edits the entry in its place) all read the same value.
* Lives here rather than in lib/config/index.ts so client-safe and test code
* that stubs the config barrel can still reach it.
*/
export function resolveZoom(
config: Pick<AppConfig, 'zoom' | 'standaloneAlbumZoom'>,
albumId: string,
subpage?: { zoom?: boolean; albumZoom?: Record<string, boolean> },
): boolean {
if (subpage) return subpage.albumZoom?.[albumId] ?? subpage.zoom ?? config.zoom;
return config.standaloneAlbumZoom?.[albumId] ?? config.zoom;
}
export interface AlbumEntryObject {
/** Optional: an entry may carry only a sort mode and no title override. */
title?: string;
@@ -357,6 +404,11 @@ export interface AlbumEntryObject {
coverPosition?: string;
/** Offer the original file for download from the lightbox (#475). Off by default. */
download?: boolean;
/**
* Lightbox zoom to full resolution for this album, over the subpage and
* site setting in either direction (#467). Absent inherits.
*/
zoom?: boolean;
/**
* How precisely this album's photographs may be placed on the map:
* `exact` (default), `city`, `country` or `hidden`. Narrowed to
@@ -403,6 +455,8 @@ export interface GallerySubpageYaml {
}>;
password?: string;
proofing?: boolean;
/** Lightbox zoom for every album here that does not set its own (#467). */
zoom?: boolean;
essayFile?: string;
essayText?: string;
enabled?: boolean;
@@ -447,6 +501,8 @@ export interface SettingsYaml {
transitions?: boolean;
scrollToTop?: boolean;
analytics?: boolean;
/** Lightbox zoom to full resolution; off unless set (#467). */
zoom?: boolean;
proofing?: {
enabled?: boolean;
allowMailto?: boolean;