- A Default layout or Thumbnail size saved in System now reaches the next Images visit in an open tab (this tab or another): the last visit records the defaults it started from, and a value its toolbar never changed follows newer defaults. A toolbar choice stays the current view's own. - Images opens in Masonry when the browser has no stored Default layout (gallery-settings.js DEFAULT_SETTINGS.workspaceLayout); stored choices are kept. - Grid/List card art, Library card art, the inspector cover and the Tag image preview crop with object-position 50% 20%, so portrait images keep their top. - D157 in TESTING.md; concept comparisons start from the concept's stored Grid.
99 lines
5.0 KiB
JavaScript
99 lines
5.0 KiB
JavaScript
/**
|
|
* Gallery display settings: defaults, validation of what localStorage holds,
|
|
* and the grid template for a chosen column count.
|
|
*
|
|
* Settings are per browser (localStorage key "gallerySettings"). Anything
|
|
* stored can be stale or hand-edited, so every value is checked before use.
|
|
* The workspace shares this object ("One display configuration", #249 System
|
|
* S3): it adds workspaceLayout and workspaceDensity, and every key either page
|
|
* does not know is kept.
|
|
*
|
|
* Loadable in the browser (window.GallerySettings) and in Node for tests.
|
|
*/
|
|
(function (root) {
|
|
"use strict";
|
|
|
|
const VIEW_MODES = ["grid", "list"];
|
|
// The workspace Images defaults; the legacy gallery's defaultViewMode has no masonry.
|
|
const WORKSPACE_LAYOUTS = ["grid", "list", "masonry"];
|
|
const WORKSPACE_DENSITIES = ["comfortable", "large", "compact"];
|
|
const LIMIT_OPTIONS = [50, 100, 200, 500];
|
|
const MIN_COLUMNS = 2;
|
|
const MAX_COLUMNS = 12;
|
|
|
|
const DEFAULT_SETTINGS = Object.freeze({
|
|
lazyLoading: true,
|
|
imageQuality: "medium",
|
|
defaultViewMode: "grid",
|
|
defaultLimit: 100,
|
|
gridColumns: 8,
|
|
showImageInfo: true,
|
|
autoLoadMetadata: true,
|
|
cacheMetadata: true,
|
|
showFilePaths: true,
|
|
sidebarCollapsedByDefault: false,
|
|
infiniteScroll: false,
|
|
debugMode: false,
|
|
apiTimeout: 30,
|
|
thumbnailsGenerated: false,
|
|
checkThumbnailsAtStartup: true,
|
|
videoAutoplay: false,
|
|
videoMute: true,
|
|
videoLoop: true,
|
|
// #451: Images opens in Masonry unless this browser chose another layout.
|
|
workspaceLayout: "masonry",
|
|
workspaceDensity: "comfortable",
|
|
});
|
|
|
|
function toInt(value) {
|
|
const n = typeof value === "string" ? Number(value.trim()) : value;
|
|
return typeof n === "number" && Number.isInteger(n) ? n : null;
|
|
}
|
|
|
|
function bool(value, fallback) {
|
|
return typeof value === "boolean" ? value : fallback;
|
|
}
|
|
|
|
/** Merge stored settings over the defaults, replacing anything invalid. */
|
|
function normalizeGallerySettings(raw) {
|
|
const stored = raw && typeof raw === "object" ? raw : {};
|
|
const merged = { ...DEFAULT_SETTINGS, ...stored };
|
|
const limit = toInt(merged.defaultLimit);
|
|
const columns = toInt(merged.gridColumns);
|
|
const timeout = toInt(merged.apiTimeout);
|
|
return {
|
|
...merged,
|
|
defaultViewMode: VIEW_MODES.includes(merged.defaultViewMode) ? merged.defaultViewMode : DEFAULT_SETTINGS.defaultViewMode,
|
|
defaultLimit: limit !== null && LIMIT_OPTIONS.includes(limit) ? limit : DEFAULT_SETTINGS.defaultLimit,
|
|
gridColumns: columns === null ? DEFAULT_SETTINGS.gridColumns : Math.min(MAX_COLUMNS, Math.max(MIN_COLUMNS, columns)),
|
|
apiTimeout: timeout !== null && timeout > 0 ? timeout : DEFAULT_SETTINGS.apiTimeout,
|
|
imageQuality: ["low", "medium", "high"].includes(merged.imageQuality) ? merged.imageQuality : DEFAULT_SETTINGS.imageQuality,
|
|
lazyLoading: bool(merged.lazyLoading, DEFAULT_SETTINGS.lazyLoading),
|
|
showImageInfo: bool(merged.showImageInfo, DEFAULT_SETTINGS.showImageInfo),
|
|
autoLoadMetadata: bool(merged.autoLoadMetadata, DEFAULT_SETTINGS.autoLoadMetadata),
|
|
cacheMetadata: bool(merged.cacheMetadata, DEFAULT_SETTINGS.cacheMetadata),
|
|
showFilePaths: bool(merged.showFilePaths, DEFAULT_SETTINGS.showFilePaths),
|
|
sidebarCollapsedByDefault: bool(merged.sidebarCollapsedByDefault, DEFAULT_SETTINGS.sidebarCollapsedByDefault),
|
|
infiniteScroll: bool(merged.infiniteScroll, DEFAULT_SETTINGS.infiniteScroll),
|
|
debugMode: bool(merged.debugMode, DEFAULT_SETTINGS.debugMode),
|
|
thumbnailsGenerated: bool(merged.thumbnailsGenerated, DEFAULT_SETTINGS.thumbnailsGenerated),
|
|
checkThumbnailsAtStartup: bool(merged.checkThumbnailsAtStartup, DEFAULT_SETTINGS.checkThumbnailsAtStartup),
|
|
videoAutoplay: bool(merged.videoAutoplay, DEFAULT_SETTINGS.videoAutoplay),
|
|
videoMute: bool(merged.videoMute, DEFAULT_SETTINGS.videoMute),
|
|
videoLoop: bool(merged.videoLoop, DEFAULT_SETTINGS.videoLoop),
|
|
workspaceLayout: WORKSPACE_LAYOUTS.includes(merged.workspaceLayout) ? merged.workspaceLayout : DEFAULT_SETTINGS.workspaceLayout,
|
|
workspaceDensity: WORKSPACE_DENSITIES.includes(merged.workspaceDensity) ? merged.workspaceDensity : DEFAULT_SETTINGS.workspaceDensity,
|
|
};
|
|
}
|
|
|
|
/** CSS grid-template-columns for the desktop grid. */
|
|
function gridColumnsStyle(columns) {
|
|
const n = normalizeGallerySettings({ gridColumns: columns }).gridColumns;
|
|
return `repeat(${n}, minmax(0, 1fr))`;
|
|
}
|
|
|
|
const api = { DEFAULT_SETTINGS, LIMIT_OPTIONS, VIEW_MODES, WORKSPACE_LAYOUTS, WORKSPACE_DENSITIES, normalizeGallerySettings, gridColumnsStyle };
|
|
if (typeof module !== "undefined" && module.exports) module.exports = api;
|
|
else root.GallerySettings = api;
|
|
})(typeof window !== "undefined" ? window : globalThis);
|