immich/web/src/lib/components/asset-viewer/editor/editor-panel.svelte
ilyaChuk 7f7fec2cea
feat(web): image editor - panel and cropping (#11074)
* cropping, panel

* fix presets

* types

* prettier

* fix lint

* fix aspect ratio, performance optimization

* improved tool selection, removed placeholder

* fix the mouse's exit from canvas

* fix error

* the "save" button and change tracking

* lint, format

* the mini functionality of the save button

* fix aspect ratio

* hide editor button on mobiles

* strict equality

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>

* Use the dollar sign syntax for stores inside components

* unobtrusive grid lines, circles at the corners

* more correct image load, handleError

* more strict equality

* fix styles. unused and tailwind

Co-Authored-By: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>

* dont store isShowEditor

* if showEditor - hide navbar & shortcuts

* crop-canvas decomposition (danger)

I could have accidentally broken something.. but I checked the work and it seems ok.

* fix lint

* fix ts

* callback function as props

* correctly disabling shortcuts

* convenient canvas borders

• you can use the mouse to go beyond the boundaries and freely change the crop.
• the circles on the corners of the canvas are not cut off.

* -the editor button for video files, -save button

* hide editor btn if panoramic || gif || live

* corners instead of circles (preview), fix lint&format

* confirm close editor without save

* vertical aspect ratios

* recovery after merge. editor's closing shortcut

* fix format

* move from canvas to html elements

* fix changes detections

* rotation

* hide detail panel if showing editor

* fix aspect ratios near min size

* fix crop area when changing image size when rotate

* fix of fix

* better layout - grouping

https://github.com/user-attachments/assets/48f15172-9666-4588-acb6-3cb5eda873a8

* hide the button

* fix i18n, format

* hide button

* hide button v2

---------

Co-authored-by: Michel Heusschen <59014050+michelheusschen@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-08-14 09:54:50 -05:00

76 lines
2.5 KiB
Svelte

<script lang="ts">
import { websocketEvents } from '$lib/stores/websocket';
import { type AssetResponseDto } from '@immich/sdk';
import { mdiClose } from '@mdi/js';
import { onMount } from 'svelte';
import CircleIconButton from '../../elements/buttons/circle-icon-button.svelte';
import { t } from 'svelte-i18n';
import { editTypes, showCancelConfirmDialog } from '$lib/stores/asset-editor.store';
import ConfirmDialog from '$lib/components/shared-components/dialog/confirm-dialog.svelte';
import { shortcut } from '$lib/actions/shortcut';
export let asset: AssetResponseDto;
onMount(() => {
return websocketEvents.on('on_asset_update', (assetUpdate) => {
if (assetUpdate.id === asset.id) {
asset = assetUpdate;
}
});
});
export let onUpdateSelectedType: (type: string) => void;
export let onClose: () => void;
let selectedType: string = editTypes[0].name;
$: selectedTypeObj = editTypes.find((t) => t.name === selectedType) || editTypes[0];
setTimeout(() => {
onUpdateSelectedType(selectedType);
}, 1);
function selectType(name: string) {
selectedType = name;
onUpdateSelectedType(selectedType);
}
</script>
<svelte:window use:shortcut={{ shortcut: { key: 'Escape' }, onShortcut: onClose }} />
<section class="relative p-2 dark:bg-immich-dark-bg dark:text-immich-dark-fg">
<div class="flex place-items-center gap-2">
<CircleIconButton icon={mdiClose} title={$t('close')} on:click={onClose} />
<p class="text-lg text-immich-fg dark:text-immich-dark-fg capitalize">{$t('editor')}</p>
</div>
<section class="px-4 py-4">
<ul class="flex w-full justify-around">
{#each editTypes as etype (etype.name)}
<li>
<CircleIconButton
color={etype.name === selectedType ? 'primary' : 'opaque'}
icon={etype.icon}
title={etype.name}
on:click={() => selectType(etype.name)}
/>
</li>
{/each}
</ul>
</section>
<section>
<svelte:component this={selectedTypeObj.component} />
</section>
</section>
{#if $showCancelConfirmDialog}
<ConfirmDialog
title={$t('editor_close_without_save_title')}
prompt={$t('editor_close_without_save_prompt')}
cancelText={$t('no')}
cancelColor="secondary"
confirmColor="red"
confirmText={$t('close')}
onCancel={() => {
$showCancelConfirmDialog = false;
}}
onConfirm={() => (typeof $showCancelConfirmDialog === 'boolean' ? null : $showCancelConfirmDialog())}
/>
{/if}