From fe3c73ccfdd38067644ca5c0770bc935159d92b6 Mon Sep 17 00:00:00 2001 From: Pavel Laptev Date: Fri, 30 Aug 2024 13:11:23 +0200 Subject: [PATCH] FileListItem fix (#4799) * show lock icons and lock tooltip * replace state with derived * allow to drag files --- apps/desktop/src/lib/file/FileListItem.svelte | 44 +++++++++++++++++-- packages/ui/src/lib/file/FileListItem.svelte | 10 +---- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/apps/desktop/src/lib/file/FileListItem.svelte b/apps/desktop/src/lib/file/FileListItem.svelte index fb26f5174..b81300281 100644 --- a/apps/desktop/src/lib/file/FileListItem.svelte +++ b/apps/desktop/src/lib/file/FileListItem.svelte @@ -4,11 +4,14 @@ import { DraggableFile } from '$lib/dragging/draggables'; import { getContext, maybeGetContextStore } from '$lib/utils/context'; import { computeFileStatus } from '$lib/utils/fileStatus'; + import { getLocalCommits, getLocalAndRemoteCommits } from '$lib/vbranches/contexts'; import { getCommitStore } from '$lib/vbranches/contexts'; import { FileIdSelection } from '$lib/vbranches/fileIdSelection'; import { Ownership } from '$lib/vbranches/ownership'; - import { VirtualBranch, type AnyFile } from '$lib/vbranches/types'; + import { getLockText } from '$lib/vbranches/tooltip'; + import { VirtualBranch, type AnyFile, LocalFile } from '$lib/vbranches/types'; import FileListItem from '@gitbutler/ui/file/FileListItem.svelte'; + import { onDestroy } from 'svelte'; import type { Writable } from 'svelte/store'; interface Props { @@ -29,6 +32,16 @@ const fileIdSelection = getContext(FileIdSelection); const commit = getCommitStore(); + // TODO: Refactor this into something more meaningful. + const localCommits = file instanceof LocalFile ? getLocalCommits() : undefined; + const remoteCommits = file instanceof LocalFile ? getLocalAndRemoteCommits() : undefined; + let lockedIds = file.lockedIds; + let lockText = $derived( + lockedIds.length > 0 && $localCommits + ? getLockText(lockedIds, ($localCommits || []).concat($remoteCommits || [])) + : '' + ); + const selectedFiles = fileIdSelection.files; let contextMenu: FileContextMenu; @@ -75,6 +88,7 @@ { const isChecked = e.currentTarget.checked; lastCheckboxDetail = isChecked; @@ -125,21 +141,43 @@ } const files = await $selectedFiles; + let animationEndHandler: () => void; + + function addAnimationEndListener(element: HTMLElement) { + animationEndHandler = () => { + element.classList.remove('locked-file-animation'); + element.removeEventListener('animationend', animationEndHandler); + }; + element.addEventListener('animationend', animationEndHandler); + }; if (files.length > 0) { files.forEach((f) => { if (f.locked) { const lockedElement = document.getElementById(`file-${f.id}`); - if (lockedElement) { - // add a class to the locked file lockedElement.classList.add('locked-file-animation'); + addAnimationEndListener(lockedElement); } } }); } else if (file.locked) { draggableEl?.classList.add('locked-file-animation'); + draggableEl && addAnimationEndListener(draggableEl); } + + onDestroy(() => { + // Ensure any listeners are removed if the component is destroyed before animation ends + if (draggableEl && animationEndHandler) { + draggableEl.removeEventListener('animationend', animationEndHandler); + } + files.forEach((f) => { + const lockedElement = document.getElementById(`file-${f.id}`); + if (lockedElement && animationEndHandler) { + lockedElement.removeEventListener('animationend', animationEndHandler); + } + }); + }); }} oncontextmenu={async (e) => { if (fileIdSelection.has(file.id, $commit?.id)) { diff --git a/packages/ui/src/lib/file/FileListItem.svelte b/packages/ui/src/lib/file/FileListItem.svelte index 2caae3d1a..7a389c15a 100644 --- a/packages/ui/src/lib/file/FileListItem.svelte +++ b/packages/ui/src/lib/file/FileListItem.svelte @@ -76,12 +76,6 @@ }} ondragstart={(e) => { if (draggable) { - if (locked) { - e.preventDefault(); - console.log('Cannot drag locked file'); - return; - } - ondragstart?.(e); } }} @@ -100,8 +94,8 @@
- {#if lockText} -
+ {#if locked} +
{/if}