Compare commits

...

2 Commits

Author SHA1 Message Date
Mees Frensel
5a79195e4f fix(web): handle deletion from asset viewer on map page 2026-01-20 16:28:32 +01:00
Min Idzelis
ca0d4b283a feat: zoom image improvements for reactive prop handlings (#25286) 2026-01-20 13:18:54 +01:00
4 changed files with 53 additions and 25 deletions

View File

@@ -1,48 +1,42 @@
import { photoZoomState } from '$lib/stores/zoom-image.store';
import { useZoomImageWheel } from '@zoom-image/svelte';
import { createZoomImageWheel } from '@zoom-image/core';
import { get } from 'svelte/store';
export const zoomImageAction = (node: HTMLElement, options?: { disabled?: boolean }) => {
const { createZoomImage, zoomImageState, setZoomImageState } = useZoomImageWheel();
createZoomImage(node, {
const state = get(photoZoomState);
const zoomInstance = createZoomImageWheel(node, {
maxZoom: 10,
initialState: state,
});
const state = get(photoZoomState);
if (state) {
setZoomImageState(state);
}
const unsubscribes = [
photoZoomState.subscribe((state) => zoomInstance.setState(state)),
zoomInstance.subscribe(({ state }) => {
photoZoomState.set(state);
}),
];
// Store original event handlers so we can prevent them when disabled
const wheelHandler = (event: WheelEvent) => {
const stopIfDisabled = (event: Event) => {
if (options?.disabled) {
event.stopImmediatePropagation();
}
};
const pointerDownHandler = (event: PointerEvent) => {
if (options?.disabled) {
event.stopImmediatePropagation();
}
};
// Add handlers at capture phase with higher priority
node.addEventListener('wheel', wheelHandler, { capture: true });
node.addEventListener('pointerdown', pointerDownHandler, { capture: true });
const unsubscribes = [photoZoomState.subscribe(setZoomImageState), zoomImageState.subscribe(photoZoomState.set)];
node.addEventListener('wheel', stopIfDisabled, { capture: true });
node.addEventListener('pointerdown', stopIfDisabled, { capture: true });
node.style.overflow = 'visible';
return {
update(newOptions?: { disabled?: boolean }) {
options = newOptions;
},
destroy() {
node.removeEventListener('wheel', wheelHandler, { capture: true });
node.removeEventListener('pointerdown', pointerDownHandler, { capture: true });
for (const unsubscribe of unsubscribes) {
unsubscribe();
}
node.removeEventListener('wheel', stopIfDisabled, { capture: true });
node.removeEventListener('pointerdown', stopIfDisabled, { capture: true });
zoomInstance.cleanup();
},
};
};

View File

@@ -11,6 +11,7 @@
import { assetViewerManager } from '$lib/managers/asset-viewer-manager.svelte';
import { authManager } from '$lib/managers/auth-manager.svelte';
import { editManager, EditToolType } from '$lib/managers/edit/edit-manager.svelte';
import { eventManager } from '$lib/managers/event-manager.svelte';
import { preloadManager } from '$lib/managers/PreloadManager.svelte';
import { Route } from '$lib/route';
import { assetViewingStore } from '$lib/stores/asset-viewing.store';
@@ -321,6 +322,11 @@
await handleGetAllAlbums();
break;
}
case AssetAction.DELETE:
case AssetAction.TRASH: {
eventManager.emit('AssetsDelete', [asset.id]);
break;
}
case AssetAction.REMOVE_ASSET_FROM_STACK: {
stack = action.stack;
if (stack) {

View File

@@ -10,6 +10,7 @@
<script lang="ts">
import { afterNavigate } from '$app/navigation';
import OnEvents from '$lib/components/OnEvents.svelte';
import { Theme } from '$lib/constants';
import { serverConfigManager } from '$lib/managers/server-config-manager.svelte';
import { themeManager } from '$lib/managers/theme-manager.svelte';
@@ -292,8 +293,14 @@
untrack(() => map?.jumpTo({ center, zoom }));
});
const onAssetsDelete = async () => {
mapMarkers = await loadMapMarkers();
};
</script>
<OnEvents {onAssetsDelete} />
<!-- We handle style loading ourselves so we set style blank here -->
<MapLibre
{hash}

View File

@@ -1,4 +1,25 @@
import type { ZoomImageWheelState } from '@zoom-image/core';
import { writable } from 'svelte/store';
import { derived, writable } from 'svelte/store';
export const photoZoomState = writable<ZoomImageWheelState>();
export const photoZoomState = writable<ZoomImageWheelState>({
currentRotation: 0,
currentZoom: 1,
enable: true,
currentPositionX: 0,
currentPositionY: 0,
});
export const photoZoomTransform = derived(
photoZoomState,
($state) => `translate(${$state.currentPositionX}px,${$state.currentPositionY}px) scale(${$state.currentZoom})`,
);
export const resetZoomState = () => {
photoZoomState.set({
currentRotation: 0,
currentZoom: 1,
enable: true,
currentPositionX: 0,
currentPositionY: 0,
});
};