refactor(web): descriptions (#6517)
* refactor: reusable autogrow * fix: remove useless autogrow * fix: correct size for album description * fix: format * fix: move to own file * refactor: album description * refactor: asset description * simplify * fix: style when no description provided * fix: switching assets * feat: update description with ctrl + enter * fix: variable name * fix: styling --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { afterNavigate, goto } from '$app/navigation';
|
||||
import EditDescriptionModal from '$lib/components/album-page/edit-description-modal.svelte';
|
||||
import ShareInfoModal from '$lib/components/album-page/share-info-modal.svelte';
|
||||
import UserSelectionModal from '$lib/components/album-page/user-selection-modal.svelte';
|
||||
import Button from '$lib/components/elements/buttons/button.svelte';
|
||||
@@ -60,6 +59,7 @@
|
||||
import AlbumOptions from '$lib/components/album-page/album-options.svelte';
|
||||
import UpdatePanel from '$lib/components/shared-components/update-panel.svelte';
|
||||
import { user } from '$lib/stores/user.store';
|
||||
import { autoGrowHeight } from '$lib/utils/autogrow';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
let { slideshowState, slideshowShuffle } = slideshowStore;
|
||||
|
||||
let album = data.album;
|
||||
let description = album.description;
|
||||
|
||||
$: album = data.album;
|
||||
|
||||
@@ -91,7 +92,6 @@
|
||||
let backUrl: string = AppRoute.ALBUMS;
|
||||
let viewMode = ViewMode.VIEW;
|
||||
let titleInput: HTMLInputElement;
|
||||
let isEditingDescription = false;
|
||||
let isCreatingSharedAlbum = false;
|
||||
let currentAlbumName = album.albumName;
|
||||
let contextMenuPosition: { x: number; y: number } = { x: 0, y: 0 };
|
||||
@@ -100,7 +100,7 @@
|
||||
let reactions: ActivityResponseDto[] = [];
|
||||
let globalWidth: number;
|
||||
let assetGridWidth: number;
|
||||
let textarea: HTMLTextAreaElement;
|
||||
let textArea: HTMLTextAreaElement;
|
||||
|
||||
const assetStore = new AssetStore({ albumId: album.id });
|
||||
const assetInteractionStore = createAssetInteractionStore();
|
||||
@@ -123,12 +123,6 @@
|
||||
$: showActivityStatus =
|
||||
album.sharedUsers.length > 0 && !$showAssetViewer && (album.isActivityEnabled || $numberOfComments > 0);
|
||||
|
||||
$: {
|
||||
if (textarea) {
|
||||
textarea.value = album.description;
|
||||
autoGrowHeight();
|
||||
}
|
||||
}
|
||||
$: afterNavigate(({ from }) => {
|
||||
assetViewingStore.showAssetViewer(false);
|
||||
|
||||
@@ -149,13 +143,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
const autoGrowHeight = () => {
|
||||
// little hack so that the height of the text area is correctly initialized
|
||||
textarea.scrollHeight;
|
||||
textarea.style.height = '5px';
|
||||
textarea.style.height = `${textarea.scrollHeight}px`;
|
||||
};
|
||||
|
||||
const handleToggleEnableActivity = async () => {
|
||||
try {
|
||||
const { data } = await api.albumApi.updateAlbumInfo({
|
||||
@@ -231,6 +218,19 @@
|
||||
}
|
||||
});
|
||||
|
||||
const handleKeypress = async (event: KeyboardEvent) => {
|
||||
if (event.target !== textArea) {
|
||||
return;
|
||||
}
|
||||
const ctrl = event.ctrlKey;
|
||||
switch (event.key) {
|
||||
case 'Enter':
|
||||
if (ctrl && event.target === textArea) {
|
||||
textArea.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleStartSlideshow = async () => {
|
||||
const asset = $slideshowShuffle ? await assetStore.getRandomAsset() : assetStore.assets[0];
|
||||
if (asset) {
|
||||
@@ -252,6 +252,14 @@
|
||||
handleCloseSelectAssets();
|
||||
return;
|
||||
}
|
||||
if (viewMode === ViewMode.LINK_SHARING) {
|
||||
viewMode = ViewMode.VIEW;
|
||||
return;
|
||||
}
|
||||
if (viewMode === ViewMode.OPTIONS) {
|
||||
viewMode = ViewMode.VIEW;
|
||||
return;
|
||||
}
|
||||
if ($showAssetViewer) {
|
||||
return;
|
||||
}
|
||||
@@ -426,7 +434,10 @@
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateDescription = async (description: string) => {
|
||||
const handleUpdateDescription = async () => {
|
||||
if (album.description === description) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await api.albumApi.updateAlbumInfo({
|
||||
id: album.id,
|
||||
@@ -436,13 +447,14 @@
|
||||
});
|
||||
|
||||
album.description = description;
|
||||
isEditingDescription = false;
|
||||
} catch (error) {
|
||||
handleError(error, 'Error updating album description');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={handleKeypress} />
|
||||
|
||||
<div class="flex overflow-hidden" bind:clientWidth={globalWidth}>
|
||||
<div class="relative w-full shrink">
|
||||
{#if $isMultiSelectState}
|
||||
@@ -640,24 +652,17 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- ALBUM DESCRIPTION -->
|
||||
{#if isOwned || album.description}
|
||||
<button
|
||||
class="mb-12 mt-6 w-full border-b-2 border-transparent pb-2 text-left text-lg font-medium transition-colors hover:border-b-2 dark:text-gray-300"
|
||||
on:click={() => (isEditingDescription = true)}
|
||||
class:hover:border-gray-400={isOwned}
|
||||
disabled={!isOwned}
|
||||
title="Edit description"
|
||||
>
|
||||
<textarea
|
||||
class="w-full bg-transparent resize-none overflow-hidden outline-none"
|
||||
bind:this={textarea}
|
||||
bind:value={album.description}
|
||||
placeholder="Add description"
|
||||
/>
|
||||
</button>
|
||||
{/if}
|
||||
<textarea
|
||||
class="w-full resize-none overflow-hidden text-black dark:text-white border-b-2 border-transparent border-gray-500 bg-transparent text-base outline-none transition-all focus:border-b-2 focus:border-immich-primary disabled:border-none dark:focus:border-immich-dark-primary hover:border-gray-400"
|
||||
bind:this={textArea}
|
||||
bind:value={description}
|
||||
disabled={!isOwned}
|
||||
on:input={() => autoGrowHeight(textArea)}
|
||||
on:focusout={handleUpdateDescription}
|
||||
use:autoGrowHeight
|
||||
placeholder="Add description"
|
||||
/>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
@@ -763,14 +768,6 @@
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if isEditingDescription}
|
||||
<EditDescriptionModal
|
||||
{album}
|
||||
on:close={() => (isEditingDescription = false)}
|
||||
on:save={({ detail: description }) => handleUpdateDescription(description)}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<UpdatePanel {assetStore} />
|
||||
|
||||
<style>
|
||||
|
||||
Reference in New Issue
Block a user