diff --git a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
index 0f75f9bb830f4..0eebd7626ef73 100644
--- a/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
+++ b/web/src/lib/components/asset-viewer/asset-viewer-nav-bar.svelte
@@ -16,7 +16,7 @@
import CircleIconButton from '$lib/components/elements/buttons/circle-icon-button.svelte';
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
- import { AppRoute } from '$lib/constants';
+ import { AppRoute, ProjectionType } from '$lib/constants';
import { user } from '$lib/stores/user.store';
import { photoZoomState } from '$lib/stores/zoom-image.store';
import { getAssetJobName, getSharedLink } from '$lib/utils';
@@ -34,6 +34,7 @@
mdiContentCopy,
mdiDatabaseRefreshOutline,
mdiDotsVertical,
+ mdiImageEditOutline,
mdiImageRefreshOutline,
mdiImageSearch,
mdiMagnifyMinusOutline,
@@ -55,22 +56,22 @@
export let onRunJob: (name: AssetJobName) => void;
export let onPlaySlideshow: () => void;
export let onShowDetail: () => void;
- // export let showEditorHandler: () => void;
+ export let showEditorHandler: () => void;
export let onClose: () => void;
const sharedLink = getSharedLink();
$: isOwner = $user && asset.ownerId === $user?.id;
$: showDownloadButton = sharedLink ? sharedLink.allowDownload : !asset.isOffline;
- // $: showEditorButton =
- // isOwner &&
- // asset.type === AssetTypeEnum.Image &&
- // !(
- // asset.exifInfo?.projectionType === ProjectionType.EQUIRECTANGULAR ||
- // (asset.originalPath && asset.originalPath.toLowerCase().endsWith('.insp'))
- // ) &&
- // !(asset.originalPath && asset.originalPath.toLowerCase().endsWith('.gif')) &&
- // !asset.livePhotoVideoId;
+ $: showEditorButton =
+ isOwner &&
+ asset.type === AssetTypeEnum.Image &&
+ !(
+ asset.exifInfo?.projectionType === ProjectionType.EQUIRECTANGULAR ||
+ (asset.originalPath && asset.originalPath.toLowerCase().endsWith('.insp'))
+ ) &&
+ !(asset.originalPath && asset.originalPath.toLowerCase().endsWith('.gif')) &&
+ !asset.livePhotoVideoId;
{/if}
-
+ {/if}
{#if isOwner}
diff --git a/web/src/lib/components/asset-viewer/asset-viewer.svelte b/web/src/lib/components/asset-viewer/asset-viewer.svelte
index 69d35b9aa4593..277c4b15d694d 100644
--- a/web/src/lib/components/asset-viewer/asset-viewer.svelte
+++ b/web/src/lib/components/asset-viewer/asset-viewer.svelte
@@ -319,12 +319,12 @@
dispatch(order);
};
- // const showEditorHandler = () => {
- // if (isShowActivity) {
- // isShowActivity = false;
- // }
- // isShowEditor = !isShowEditor;
- // };
+ const showEditorHandler = () => {
+ if (isShowActivity) {
+ isShowActivity = false;
+ }
+ isShowEditor = !isShowEditor;
+ };
const handleRunJob = async (name: AssetJobName) => {
try {
@@ -415,6 +415,7 @@
{asset}
{album}
{stack}
+ {showEditorHandler}
showDetailButton={enableDetailPanel}
showSlideshow={!!assetStore}
onZoomImage={zoomToggle}
diff --git a/web/src/lib/components/asset-viewer/editor/crop-tool/crop-area.svelte b/web/src/lib/components/asset-viewer/editor/crop-tool/crop-area.svelte
index c35fd915197aa..c54aa555f8731 100644
--- a/web/src/lib/components/asset-viewer/editor/crop-tool/crop-area.svelte
+++ b/web/src/lib/components/asset-viewer/editor/crop-tool/crop-area.svelte
@@ -8,7 +8,7 @@
import { imgElement, cropAreaEl, resetCropStore, overlayEl, isResizingOrDragging, cropFrame } from './crop-store';
import { draw } from './drawing';
import { onImageLoad, resizeCanvas } from './image-loading';
- import { handleMouseDown, handleMouseMove, handleMouseUp } from './mouse-handlers';
+ import { handleMouseDown, handleMouseMove, handleMouseUp, handleWheel } from './mouse-handlers';
import { recalculateCrop, animateCropChange } from './crop-settings';
import {
changedOriention,
@@ -66,6 +66,7 @@
bind:this={$cropAreaEl}
on:mousedown={handleMouseDown}
on:mouseup={handleMouseUp}
+ on:wheel={handleWheel}
aria-label="Crop area"
type="button"
>
diff --git a/web/src/lib/components/asset-viewer/editor/crop-tool/mouse-handlers.ts b/web/src/lib/components/asset-viewer/editor/crop-tool/mouse-handlers.ts
index 656fd09294abb..9b94ec7f2abd2 100644
--- a/web/src/lib/components/asset-viewer/editor/crop-tool/mouse-handlers.ts
+++ b/web/src/lib/components/asset-viewer/editor/crop-tool/mouse-handlers.ts
@@ -79,6 +79,32 @@ export function handleMouseMove(e: MouseEvent) {
}
}
+export function handleWheel(e: WheelEvent) {
+ e.preventDefault;
+ const canvas = get(cropAreaEl);
+ if (!canvas) {
+ return;
+ }
+
+ const wheelOffset = getWheelOffset(e);
+ let scale = 1;
+
+ if (wheelOffset > 0) {
+ scale += wheelOffset * 0.1;
+ scale = Math.min(Math.max(0.125, scale), 10);
+ } else {
+ scale = -1;
+ scale += wheelOffset * 0.1;
+ scale = Math.max(Math.min(-0.125, scale), -10);
+ }
+
+ scaleCrop(scale);
+}
+
+function getWheelOffset(e: WheelEvent) {
+ return e.deltaY;
+}
+
export function handleMouseUp() {
window.removeEventListener('mouseup', handleMouseUp);
document.body.style.userSelect = '';
@@ -253,6 +279,24 @@ function moveCrop(mouseX: number, mouseY: number) {
draw(crop);
}
+function scaleCrop(scale: number) {
+ const canvas = get(cropAreaEl);
+ const crop = get(cropSettings);
+ if (!canvas) {
+ return;
+ }
+
+ const { x, y, width, height } = crop;
+ const minSize = 50;
+ fadeOverlay(false);
+
+ cropSettings.update((crop) => {
+ crop.width += scale;
+ crop.height += scale;
+ return crop;
+ });
+}
+
function resizeCrop(mouseX: number, mouseY: number) {
const canvas = get(cropAreaEl);
const crop = get(cropSettings);