mirror of
https://github.com/samsonjs/immich.git
synced 2026-04-27 15:07:45 +00:00
fix: reset and unsaved change states in editor (#25588)
This commit is contained in:
parent
3ace578fc0
commit
1a04caee29
4 changed files with 22 additions and 11 deletions
|
|
@ -194,9 +194,7 @@
|
||||||
|
|
||||||
const closeEditor = async () => {
|
const closeEditor = async () => {
|
||||||
if (editManager.hasAppliedEdits) {
|
if (editManager.hasAppliedEdits) {
|
||||||
console.log(asset);
|
|
||||||
const refreshedAsset = await getAssetInfo({ id: asset.id });
|
const refreshedAsset = await getAssetInfo({ id: asset.id });
|
||||||
console.log(refreshedAsset);
|
|
||||||
onAssetChange?.(refreshedAsset);
|
onAssetChange?.(refreshedAsset);
|
||||||
assetViewingStore.setAsset(refreshedAsset);
|
assetViewingStore.setAsset(refreshedAsset);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onclick={() => editManager.resetAllChanges()}
|
onclick={() => editManager.resetAllChanges()}
|
||||||
disabled={!editManager.hasChanges}
|
disabled={!editManager.canReset}
|
||||||
class="self-start"
|
class="self-start"
|
||||||
shape="round"
|
shape="round"
|
||||||
size="small"
|
size="small"
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ export interface EditToolManager {
|
||||||
onDeactivate: () => void;
|
onDeactivate: () => void;
|
||||||
resetAllChanges: () => Promise<void>;
|
resetAllChanges: () => Promise<void>;
|
||||||
hasChanges: boolean;
|
hasChanges: boolean;
|
||||||
|
canReset: boolean;
|
||||||
edits: EditAction[];
|
edits: EditAction[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,19 +42,22 @@ export class EditManager {
|
||||||
|
|
||||||
currentAsset = $state<AssetResponseDto | null>(null);
|
currentAsset = $state<AssetResponseDto | null>(null);
|
||||||
selectedTool = $state<EditTool | null>(null);
|
selectedTool = $state<EditTool | null>(null);
|
||||||
hasChanges = $derived(this.tools.some((t) => t.manager.hasChanges));
|
|
||||||
|
|
||||||
// used to disable multiple confirm dialogs and mouse events while one is open
|
// used to disable multiple confirm dialogs and mouse events while one is open
|
||||||
isShowingConfirmDialog = $state(false);
|
isShowingConfirmDialog = $state(false);
|
||||||
isApplyingEdits = $state(false);
|
isApplyingEdits = $state(false);
|
||||||
hasAppliedEdits = $state(false);
|
hasAppliedEdits = $state(false);
|
||||||
|
|
||||||
|
hasUnsavedChanges = $derived(this.tools.some((t) => t.manager.hasChanges) && !this.hasAppliedEdits);
|
||||||
|
canReset = $derived(this.tools.some((t) => t.manager.canReset));
|
||||||
|
|
||||||
async closeConfirm(): Promise<boolean> {
|
async closeConfirm(): Promise<boolean> {
|
||||||
// Prevent multiple dialogs (usually happens with rapid escape key presses)
|
// Prevent multiple dialogs (usually happens with rapid escape key presses)
|
||||||
if (this.isShowingConfirmDialog) {
|
if (this.isShowingConfirmDialog) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!this.hasChanges || this.hasAppliedEdits) {
|
|
||||||
|
if (!this.hasUnsavedChanges) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,8 @@ type RegionConvertParams = {
|
||||||
};
|
};
|
||||||
|
|
||||||
class TransformManager implements EditToolManager {
|
class TransformManager implements EditToolManager {
|
||||||
hasChanges: boolean = $derived.by(() => this.checkEdits());
|
canReset: boolean = $derived.by(() => this.checkEdits());
|
||||||
|
hasChanges: boolean = $state(false);
|
||||||
|
|
||||||
darkenLevel = $state(0.65);
|
darkenLevel = $state(0.65);
|
||||||
isInteracting = $state(false);
|
isInteracting = $state(false);
|
||||||
|
|
@ -56,7 +57,7 @@ class TransformManager implements EditToolManager {
|
||||||
cropAspectRatio = $state('free');
|
cropAspectRatio = $state('free');
|
||||||
originalImageSize = $state<ImageDimensions>({ width: 1000, height: 1000 });
|
originalImageSize = $state<ImageDimensions>({ width: 1000, height: 1000 });
|
||||||
region = $state({ x: 0, y: 0, width: 100, height: 100 });
|
region = $state({ x: 0, y: 0, width: 100, height: 100 });
|
||||||
preveiwImgSize = $derived({
|
previewImageSize = $derived({
|
||||||
width: this.cropImageSize.width * this.cropImageScale,
|
width: this.cropImageSize.width * this.cropImageScale,
|
||||||
height: this.cropImageSize.height * this.cropImageScale,
|
height: this.cropImageSize.height * this.cropImageScale,
|
||||||
});
|
});
|
||||||
|
|
@ -73,6 +74,7 @@ class TransformManager implements EditToolManager {
|
||||||
edits = $derived.by(() => this.getEdits());
|
edits = $derived.by(() => this.getEdits());
|
||||||
|
|
||||||
setAspectRatio(aspectRatio: string) {
|
setAspectRatio(aspectRatio: string) {
|
||||||
|
this.hasChanges = true;
|
||||||
this.cropAspectRatio = aspectRatio;
|
this.cropAspectRatio = aspectRatio;
|
||||||
|
|
||||||
if (!this.imgElement || !this.cropAreaEl) {
|
if (!this.imgElement || !this.cropAreaEl) {
|
||||||
|
|
@ -88,8 +90,8 @@ class TransformManager implements EditToolManager {
|
||||||
|
|
||||||
checkEdits() {
|
checkEdits() {
|
||||||
return (
|
return (
|
||||||
Math.abs(this.preveiwImgSize.width - this.region.width) > 2 ||
|
Math.abs(this.previewImageSize.width - this.region.width) > 2 ||
|
||||||
Math.abs(this.preveiwImgSize.height - this.region.height) > 2 ||
|
Math.abs(this.previewImageSize.height - this.region.height) > 2 ||
|
||||||
this.mirrorHorizontal ||
|
this.mirrorHorizontal ||
|
||||||
this.mirrorVertical ||
|
this.mirrorVertical ||
|
||||||
this.normalizedRotation !== 0
|
this.normalizedRotation !== 0
|
||||||
|
|
@ -98,8 +100,8 @@ class TransformManager implements EditToolManager {
|
||||||
|
|
||||||
checkCropEdits() {
|
checkCropEdits() {
|
||||||
return (
|
return (
|
||||||
Math.abs(this.preveiwImgSize.width - this.region.width) > 2 ||
|
Math.abs(this.previewImageSize.width - this.region.width) > 2 ||
|
||||||
Math.abs(this.preveiwImgSize.height - this.region.height) > 2
|
Math.abs(this.previewImageSize.height - this.region.height) > 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -232,9 +234,12 @@ class TransformManager implements EditToolManager {
|
||||||
this.originalImageSize = { width: 1000, height: 1000 };
|
this.originalImageSize = { width: 1000, height: 1000 };
|
||||||
this.cropImageScale = 1;
|
this.cropImageScale = 1;
|
||||||
this.cropAspectRatio = 'free';
|
this.cropAspectRatio = 'free';
|
||||||
|
this.hasChanges = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mirror(axis: 'horizontal' | 'vertical') {
|
mirror(axis: 'horizontal' | 'vertical') {
|
||||||
|
this.hasChanges = true;
|
||||||
|
|
||||||
if (this.imageRotation % 180 !== 0) {
|
if (this.imageRotation % 180 !== 0) {
|
||||||
axis = axis === 'horizontal' ? 'vertical' : 'horizontal';
|
axis = axis === 'horizontal' ? 'vertical' : 'horizontal';
|
||||||
}
|
}
|
||||||
|
|
@ -247,6 +252,8 @@ class TransformManager implements EditToolManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async rotate(angle: number) {
|
async rotate(angle: number) {
|
||||||
|
this.hasChanges = true;
|
||||||
|
|
||||||
this.imageRotation += angle;
|
this.imageRotation += angle;
|
||||||
await tick();
|
await tick();
|
||||||
this.onImageLoad();
|
this.onImageLoad();
|
||||||
|
|
@ -760,6 +767,7 @@ class TransformManager implements EditToolManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.hasChanges = true;
|
||||||
const newX = Math.max(0, Math.min(mouseX - this.dragOffset.x, cropArea.clientWidth - this.region.width));
|
const newX = Math.max(0, Math.min(mouseX - this.dragOffset.x, cropArea.clientWidth - this.region.width));
|
||||||
const newY = Math.max(0, Math.min(mouseY - this.dragOffset.y, cropArea.clientHeight - this.region.height));
|
const newY = Math.max(0, Math.min(mouseY - this.dragOffset.y, cropArea.clientHeight - this.region.height));
|
||||||
|
|
||||||
|
|
@ -781,6 +789,7 @@ class TransformManager implements EditToolManager {
|
||||||
}
|
}
|
||||||
this.fadeOverlay(false);
|
this.fadeOverlay(false);
|
||||||
|
|
||||||
|
this.hasChanges = true;
|
||||||
const { x, y, width, height } = crop;
|
const { x, y, width, height } = crop;
|
||||||
const minSize = 50;
|
const minSize = 50;
|
||||||
let newRegion = { ...crop };
|
let newRegion = { ...crop };
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue