single track drag-and-drop ghost
This commit is contained in:
@@ -39,6 +39,7 @@ import type { DragPayload } from '@utils/drag-controller';
|
||||
import {
|
||||
createAlbumArtDragImage,
|
||||
createDragImage,
|
||||
createTrackCardDragImage,
|
||||
removeDragImage,
|
||||
} from '@utils/drag-image';
|
||||
|
||||
@@ -2850,9 +2851,16 @@ export class CoverGrid extends LitElement {
|
||||
JSON.stringify(payload),
|
||||
);
|
||||
|
||||
this.dragImageEl = createDragImage(
|
||||
filePaths.length,
|
||||
);
|
||||
this.dragImageEl =
|
||||
filePaths.length === 1
|
||||
? createTrackCardDragImage(
|
||||
track.TrackName,
|
||||
track.ArtistName,
|
||||
track.FilePath,
|
||||
)
|
||||
: createDragImage(
|
||||
filePaths.length,
|
||||
);
|
||||
dataTransfer.setDragImage(
|
||||
this.dragImageEl,
|
||||
0,
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
} from '@utils/drag-controller';
|
||||
import {
|
||||
createDragImage,
|
||||
createTrackCardDragImage,
|
||||
removeDragImage,
|
||||
} from '@utils/drag-image';
|
||||
|
||||
@@ -1143,9 +1144,14 @@ export class PlaylistView
|
||||
sourcePlaylistId: entry.summary.ID,
|
||||
});
|
||||
|
||||
this.dragImageEl = createDragImage(
|
||||
filePaths.length,
|
||||
);
|
||||
this.dragImageEl =
|
||||
filePaths.length === 1
|
||||
? createTrackCardDragImage(
|
||||
track.Title,
|
||||
track.Artist,
|
||||
track.FilePath,
|
||||
)
|
||||
: createDragImage(filePaths.length);
|
||||
e.dataTransfer?.setDragImage(
|
||||
this.dragImageEl,
|
||||
0,
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
} from '@utils/drag-controller';
|
||||
import {
|
||||
createDragImage,
|
||||
createTrackCardDragImage,
|
||||
removeDragImage,
|
||||
} from '@utils/drag-image';
|
||||
|
||||
@@ -1096,9 +1097,21 @@ export class QueuePanel
|
||||
source: 'queue',
|
||||
});
|
||||
|
||||
this.dragImageEl = createDragImage(
|
||||
filePaths.length,
|
||||
);
|
||||
if (filePaths.length === 1) {
|
||||
const t = tracks[index]!;
|
||||
|
||||
this.dragImageEl =
|
||||
createTrackCardDragImage(
|
||||
t.title,
|
||||
t.artist,
|
||||
t.filePath,
|
||||
);
|
||||
} else {
|
||||
this.dragImageEl = createDragImage(
|
||||
filePaths.length,
|
||||
);
|
||||
}
|
||||
|
||||
e.dataTransfer?.setDragImage(
|
||||
this.dragImageEl,
|
||||
0,
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
} from '@utils/drag-controller';
|
||||
import {
|
||||
createDragImage,
|
||||
createTrackCardDragImage,
|
||||
removeDragImage,
|
||||
} from '@utils/drag-image';
|
||||
import '@lit-labs/virtualizer';
|
||||
@@ -1135,9 +1136,14 @@ export class TrackList extends LitElement implements SelectionHost {
|
||||
});
|
||||
|
||||
// Custom drag image.
|
||||
this.dragImageEl = createDragImage(
|
||||
filePaths.length,
|
||||
);
|
||||
this.dragImageEl =
|
||||
filePaths.length === 1
|
||||
? createTrackCardDragImage(
|
||||
track.TrackName,
|
||||
track.ArtistName,
|
||||
track.FilePath,
|
||||
)
|
||||
: createDragImage(filePaths.length);
|
||||
e.dataTransfer?.setDragImage(
|
||||
this.dragImageEl,
|
||||
0,
|
||||
|
||||
@@ -66,6 +66,83 @@ export function createAlbumArtDragImage(
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a drag image styled like a queue track card showing the
|
||||
* track title and artist. Used when dragging a single track.
|
||||
*
|
||||
* If `title` is empty and `filePath` is provided the filename
|
||||
* (without extension) is used as a fallback. An empty `artist`
|
||||
* falls back to "Unknown Artist".
|
||||
*/
|
||||
export function createTrackCardDragImage(
|
||||
title: string,
|
||||
artist: string,
|
||||
filePath?: string,
|
||||
): HTMLElement {
|
||||
let displayTitle = title;
|
||||
|
||||
if (!displayTitle && filePath) {
|
||||
const parts = filePath.split(/[\\/]/);
|
||||
const filename =
|
||||
parts[parts.length - 1] ?? filePath;
|
||||
|
||||
displayTitle = filename.replace(/\.[^.]+$/, '');
|
||||
}
|
||||
|
||||
if (!displayTitle) {
|
||||
displayTitle = 'Unknown Title';
|
||||
}
|
||||
|
||||
const displayArtist = artist || 'Unknown Artist';
|
||||
|
||||
const card = document.createElement('div');
|
||||
|
||||
card.style.cssText = [
|
||||
'position: fixed',
|
||||
'top: -1000px',
|
||||
'left: -1000px',
|
||||
'max-width: 220px',
|
||||
'padding: 8px 14px',
|
||||
'border-radius: 6px',
|
||||
'background: #2a2a2a',
|
||||
'box-shadow: 0 2px 8px rgba(0,0,0,0.4)',
|
||||
'pointer-events: none',
|
||||
'z-index: 9999',
|
||||
'display: flex',
|
||||
'flex-direction: column',
|
||||
'gap: 2px',
|
||||
'font-family: inherit',
|
||||
].join(';');
|
||||
|
||||
const titleEl = document.createElement('span');
|
||||
|
||||
titleEl.textContent = displayTitle;
|
||||
titleEl.style.cssText = [
|
||||
'font-size: 13px',
|
||||
'color: #fff',
|
||||
'white-space: nowrap',
|
||||
'overflow: hidden',
|
||||
'text-overflow: ellipsis',
|
||||
].join(';');
|
||||
|
||||
const artistEl = document.createElement('span');
|
||||
|
||||
artistEl.textContent = displayArtist;
|
||||
artistEl.style.cssText = [
|
||||
'font-size: 11px',
|
||||
'color: #b3b3b3',
|
||||
'white-space: nowrap',
|
||||
'overflow: hidden',
|
||||
'text-overflow: ellipsis',
|
||||
].join(';');
|
||||
|
||||
card.appendChild(titleEl);
|
||||
card.appendChild(artistEl);
|
||||
document.body.appendChild(card);
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
/** Remove a drag image element created by createDragImage. */
|
||||
export function removeDragImage(el: HTMLElement): void {
|
||||
el.remove();
|
||||
|
||||
Reference in New Issue
Block a user