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 @@