diff --git a/web/src/lib/components/album-page/edit-description-modal.svelte b/web/src/lib/components/album-page/edit-description-modal.svelte deleted file mode 100644 index e8bb68da46..0000000000 --- a/web/src/lib/components/album-page/edit-description-modal.svelte +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - Edit description - - - - - Description - - - - - - Cancel - Ok - - - - diff --git a/web/src/lib/components/asset-viewer/activity-viewer.svelte b/web/src/lib/components/asset-viewer/activity-viewer.svelte index 5749d3bb41..42fa146f85 100644 --- a/web/src/lib/components/asset-viewer/activity-viewer.svelte +++ b/web/src/lib/components/asset-viewer/activity-viewer.svelte @@ -19,6 +19,7 @@ import { NotificationType, notificationController } from '../shared-components/notification/notification'; import { getAssetType } from '$lib/utils/asset-utils'; import * as luxon from 'luxon'; + import { autoGrowHeight } from '$lib/utils/autogrow'; const units: Intl.RelativeTimeFormatUnit[] = ['year', 'month', 'week', 'day', 'hour', 'minute', 'second']; @@ -98,11 +99,6 @@ } }; - const autoGrow = () => { - textArea.style.height = '5px'; - textArea.style.height = textArea.scrollHeight + 'px'; - }; - const timeOptions = { year: 'numeric', month: '2-digit', @@ -293,7 +289,7 @@ bind:this={textArea} bind:value={message} placeholder={disabled ? 'Comments are disabled' : 'Say something'} - on:input={autoGrow} + on:input={() => autoGrowHeight(textArea)} on:keypress={handleEnter} class="h-[18px] {disabled ? 'cursor-not-allowed' diff --git a/web/src/lib/components/asset-viewer/detail-panel.svelte b/web/src/lib/components/asset-viewer/detail-panel.svelte index 81520a9acf..25fb61a30e 100644 --- a/web/src/lib/components/asset-viewer/detail-panel.svelte +++ b/web/src/lib/components/asset-viewer/detail-panel.svelte @@ -31,14 +31,17 @@ import ChangeLocation from '../shared-components/change-location.svelte'; import { handleError } from '../../utils/handle-error'; import { user } from '$lib/stores/user.store'; + import { autoGrowHeight } from '$lib/utils/autogrow'; + import { clickOutside } from '$lib/utils/click-outside'; export let asset: AssetResponseDto; export let albums: AlbumResponseDto[] = []; export let albumId: string | null = null; let showAssetPath = false; - let textarea: HTMLTextAreaElement; + let textArea: HTMLTextAreaElement; let description: string; + let originalDescription: string; let showEditFaces = false; let previousId: string; @@ -61,10 +64,10 @@ if (newAsset.id && !api.isSharedLink) { const { data } = await api.assetApi.getAssetById({ id: asset.id }); people = data?.people || []; + description = data.exifInfo?.description || ''; - textarea.value = description; - autoGrowHeight(); } + originalDescription = description; }; $: handleNewAsset(asset); @@ -99,6 +102,19 @@ closeViewer: void; }>(); + const handleKeypress = async (event: KeyboardEvent) => { + if (event.target !== textArea) { + return; + } + const ctrl = event.ctrlKey; + switch (event.key) { + case 'Enter': + if (ctrl && event.target === textArea) { + handleFocusOut(); + } + } + }; + const getMegapixel = (width: number, height: number): number | undefined => { const megapixel = Math.round((height * width) / 1_000_000); @@ -112,21 +128,21 @@ const handleRefreshPeople = async () => { await api.assetApi.getAssetById({ id: asset.id }).then((res) => { people = res.data?.people || []; - textarea.value = res.data?.exifInfo?.description || ''; + textArea.value = res.data?.exifInfo?.description || ''; }); showEditFaces = false; }; - const autoGrowHeight = () => { - textarea.style.height = 'auto'; - textarea.style.height = `${textarea.scrollHeight}px`; - }; - const handleFocusIn = () => { dispatch('descriptionFocusIn'); }; const handleFocusOut = async () => { + textArea.blur(); + if (description === originalDescription) { + return; + } + originalDescription = description; dispatch('descriptionFocusOut'); try { await api.assetApi.updateAsset({ @@ -134,7 +150,7 @@ updateAssetDto: { description }, }); } catch (error) { - console.error(error); + handleError(error, 'Cannot update the description'); } }; @@ -170,6 +186,8 @@ } + + {/if} - - {#if !isOwner || api.isSharedLink} - {description} - {:else} - + {#key asset.id} + - {/if} - + placeholder={!isOwner ? '' : 'Add a description'} + on:focusin={handleFocusIn} + on:focusout={handleFocusOut} + on:input={() => autoGrowHeight(textArea)} + bind:value={description} + use:autoGrowHeight + use:clickOutside + on:outclick={handleFocusOut} + /> + {/key} + + {/if} {#if !api.isSharedLink && people.length > 0} @@ -315,7 +337,9 @@ {:else} - DETAILS + + DETAILS + {/if} {#if asset.exifInfo?.dateTimeOriginal && !asset.isReadOnly} diff --git a/web/src/lib/utils/autogrow.ts b/web/src/lib/utils/autogrow.ts new file mode 100644 index 0000000000..787fefb9d9 --- /dev/null +++ b/web/src/lib/utils/autogrow.ts @@ -0,0 +1,5 @@ +export const autoGrowHeight = (textarea: HTMLTextAreaElement, height = 'auto') => { + textarea.scrollHeight; + textarea.style.height = height; + textarea.style.height = `${textarea.scrollHeight}px`; +}; diff --git a/web/src/routes/(user)/albums/[albumId]/+page.svelte b/web/src/routes/(user)/albums/[albumId]/+page.svelte index 0bc3f01d5d..cc73680f08 100644 --- a/web/src/routes/(user)/albums/[albumId]/+page.svelte +++ b/web/src/routes/(user)/albums/[albumId]/+page.svelte @@ -1,6 +1,5 @@ + + {#if $isMultiSelectState} @@ -640,24 +652,17 @@ {/if} {/if} - - {#if isOwned || album.description} - (isEditingDescription = true)} - class:hover:border-gray-400={isOwned} - disabled={!isOwned} - title="Edit description" - > - - - {/if} + autoGrowHeight(textArea)} + on:focusout={handleUpdateDescription} + use:autoGrowHeight + placeholder="Add description" + /> {/if} @@ -763,14 +768,6 @@ /> {/if} -{#if isEditingDescription} - (isEditingDescription = false)} - on:save={({ detail: description }) => handleUpdateDescription(description)} - /> -{/if} -
DETAILS