Persist lightbox settings (#2406)

* Persist lightbox settings in local forage
* Add lightbox settings to backend
* Add lightbox settings to interface settings page
This commit is contained in:
WithoutPants
2022-03-23 08:18:12 +11:00
committed by GitHub
parent 4c4cdae1ed
commit 2afb467bb1
14 changed files with 382 additions and 114 deletions

View File

@@ -1,4 +1,5 @@
import React, { useEffect, useRef, useState, useCallback } from "react";
import * as GQL from "src/core/generated-graphql";
const ZOOM_STEP = 1.1;
const SCROLL_PAN_STEP = 75;
@@ -6,22 +7,11 @@ const CLASSNAME = "Lightbox";
const CLASSNAME_CAROUSEL = `${CLASSNAME}-carousel`;
const CLASSNAME_IMAGE = `${CLASSNAME_CAROUSEL}-image`;
export enum DisplayMode {
ORIGINAL = "ORIGINAL",
FIT_XY = "FIT_XY",
FIT_X = "FIT_X",
}
export enum ScrollMode {
ZOOM = "ZOOM",
PAN_Y = "PAN_Y",
}
interface IProps {
src: string;
displayMode: DisplayMode;
displayMode: GQL.ImageLightboxDisplayMode;
scaleUp: boolean;
scrollMode: ScrollMode;
scrollMode: GQL.ImageLightboxScrollMode;
resetPosition?: boolean;
zoom: number;
// set to true to align image with bottom instead of top
@@ -105,7 +95,7 @@ export const LightboxImage: React.FC<IProps> = ({
let newZoom = 1;
let newPositionY = 0;
switch (displayMode) {
case DisplayMode.FIT_XY:
case GQL.ImageLightboxDisplayMode.FitXy:
xZoom = boxWidth / width;
yZoom = boxHeight / height;
@@ -115,14 +105,14 @@ export const LightboxImage: React.FC<IProps> = ({
}
newZoom = Math.min(xZoom, yZoom);
break;
case DisplayMode.FIT_X:
case GQL.ImageLightboxDisplayMode.FitX:
newZoom = boxWidth / width;
if (!scaleUp) {
newZoom = Math.min(newZoom, 1);
}
break;
case DisplayMode.ORIGINAL:
case GQL.ImageLightboxDisplayMode.Original:
newZoom = 1;
break;
}
@@ -131,7 +121,7 @@ export const LightboxImage: React.FC<IProps> = ({
const newPositionX = Math.min((boxWidth - width) / 2, 0);
// if fitting to screen, then centre, other
if (displayMode === DisplayMode.FIT_XY) {
if (displayMode === GQL.ImageLightboxDisplayMode.FitXy) {
newPositionY = Math.min((boxHeight - height) / 2, 0);
} else {
// otherwise, align top of image with container
@@ -178,10 +168,10 @@ export const LightboxImage: React.FC<IProps> = ({
function getScrollMode(ev: React.WheelEvent<HTMLDivElement>) {
if (ev.shiftKey) {
switch (scrollMode) {
case ScrollMode.ZOOM:
return ScrollMode.PAN_Y;
case ScrollMode.PAN_Y:
return ScrollMode.ZOOM;
case GQL.ImageLightboxScrollMode.Zoom:
return GQL.ImageLightboxScrollMode.PanY;
case GQL.ImageLightboxScrollMode.PanY:
return GQL.ImageLightboxScrollMode.Zoom;
}
}
@@ -190,7 +180,7 @@ export const LightboxImage: React.FC<IProps> = ({
function onContainerScroll(ev: React.WheelEvent<HTMLDivElement>) {
// don't zoom if mouse isn't over image
if (getScrollMode(ev) === ScrollMode.PAN_Y) {
if (getScrollMode(ev) === GQL.ImageLightboxScrollMode.PanY) {
onImageScroll(ev);
}
}
@@ -244,10 +234,10 @@ export const LightboxImage: React.FC<IProps> = ({
const percent = ev.deltaY < 0 ? ZOOM_STEP : 1 / ZOOM_STEP;
switch (getScrollMode(ev)) {
case ScrollMode.ZOOM:
case GQL.ImageLightboxScrollMode.Zoom:
setZoom(zoom * percent);
break;
case ScrollMode.PAN_Y:
case GQL.ImageLightboxScrollMode.PanY:
onImageScrollPanY(ev);
break;
}