cleaned up album selection behavior, context menu now closes when clicking outside of it
This commit is contained in:
@@ -64,6 +64,7 @@ export class AlbumDropdown extends LitElement {
|
|||||||
static override styles = css`
|
static override styles = css`
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
|
margin-top: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.album-dropdown {
|
.album-dropdown {
|
||||||
@@ -76,12 +77,12 @@ export class AlbumDropdown extends LitElement {
|
|||||||
|
|
||||||
.carat {
|
.carat {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -8px;
|
top: -10px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
border-left: 9px solid transparent;
|
border-left: 11px solid transparent;
|
||||||
border-right: 9px solid transparent;
|
border-right: 11px solid transparent;
|
||||||
border-bottom: 8px solid var(--yj-bg-elevated, #343a40);
|
border-bottom: 10px solid var(--yj-bg-elevated, #343a40);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-tracks {
|
.dropdown-tracks {
|
||||||
@@ -343,21 +344,21 @@ export class AlbumDropdown extends LitElement {
|
|||||||
class=${classes}
|
class=${classes}
|
||||||
draggable="true"
|
draggable="true"
|
||||||
@click=${(e: MouseEvent) =>
|
@click=${(e: MouseEvent) =>
|
||||||
this.onTrackClick(e, track, index)}
|
this.onTrackClick(e, track, index)}
|
||||||
@dblclick=${(e: MouseEvent) =>
|
@dblclick=${(e: MouseEvent) =>
|
||||||
this.onTrackDblClick(
|
this.onTrackDblClick(
|
||||||
e,
|
e,
|
||||||
track,
|
track,
|
||||||
index,
|
index,
|
||||||
)}
|
)}
|
||||||
@contextmenu=${(e: MouseEvent) =>
|
@contextmenu=${(e: MouseEvent) =>
|
||||||
this.onTrackContextMenu(e, track)}
|
this.onTrackContextMenu(e, track)}
|
||||||
@dragstart=${(e: DragEvent) =>
|
@dragstart=${(e: DragEvent) =>
|
||||||
this.onTrackDragStart(
|
this.onTrackDragStart(
|
||||||
e,
|
e,
|
||||||
track,
|
track,
|
||||||
index,
|
index,
|
||||||
)}
|
)}
|
||||||
@dragend=${() => this.onTrackDragEnd()}
|
@dragend=${() => this.onTrackDragEnd()}
|
||||||
>
|
>
|
||||||
<span class="track-number">
|
<span class="track-number">
|
||||||
@@ -371,8 +372,8 @@ export class AlbumDropdown extends LitElement {
|
|||||||
</span>
|
</span>
|
||||||
<span class="track-duration">
|
<span class="track-duration">
|
||||||
${formatMilliseconds(
|
${formatMilliseconds(
|
||||||
track.TrackLength,
|
track.TrackLength,
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
@@ -393,9 +394,9 @@ export class AlbumDropdown extends LitElement {
|
|||||||
style="height:${this.tracksHeight}px;column-count:${this.columnCount}"
|
style="height:${this.tracksHeight}px;column-count:${this.columnCount}"
|
||||||
>
|
>
|
||||||
${this.tracks.map(
|
${this.tracks.map(
|
||||||
(track, i) =>
|
(track, i) =>
|
||||||
this.renderTrackRow(track, i),
|
this.renderTrackRow(track, i),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -81,11 +81,23 @@ export class CoverGrid extends LitElement {
|
|||||||
|
|
||||||
private closeHandler = () => this.closeContextMenu();
|
private closeHandler = () => this.closeContextMenu();
|
||||||
|
|
||||||
|
private mousedownCloseHandler = (
|
||||||
|
e: MouseEvent,
|
||||||
|
) => {
|
||||||
|
const path = e.composedPath();
|
||||||
|
const popup = this.contextMenuPopup;
|
||||||
|
const submenu = this.playlistSubmenuPopup;
|
||||||
|
|
||||||
|
if (popup && path.includes(popup)) return;
|
||||||
|
if (submenu && path.includes(submenu)) return;
|
||||||
|
|
||||||
|
this.closeContextMenu();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When true, the next split→single transition
|
* When true, the next split→single transition
|
||||||
* skips the expensive overlay capture and scroll
|
* skips the expensive overlay capture and scroll
|
||||||
* restore. Used by the select-toggle checkbox
|
* restore.
|
||||||
* so closing the dropdown is instant.
|
|
||||||
*/
|
*/
|
||||||
private skipOverlay = false;
|
private skipOverlay = false;
|
||||||
|
|
||||||
@@ -233,11 +245,6 @@ export class CoverGrid extends LitElement {
|
|||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.album-card.expanded {
|
|
||||||
background-color: var(--yj-bg-elevated, #343a40);
|
|
||||||
border-radius: 8px 8px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.album-card:focus-visible {
|
.album-card:focus-visible {
|
||||||
outline: 2px solid var(--yj-accent, #ffd43b);
|
outline: 2px solid var(--yj-accent, #ffd43b);
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
@@ -257,45 +264,6 @@ export class CoverGrid extends LitElement {
|
|||||||
scale: 0.95;
|
scale: 0.95;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================
|
|
||||||
* Selection checkbox overlay
|
|
||||||
* ======================================== */
|
|
||||||
|
|
||||||
.select-toggle {
|
|
||||||
position: absolute;
|
|
||||||
top: 6px;
|
|
||||||
left: 6px;
|
|
||||||
width: 22px;
|
|
||||||
height: 22px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 2px solid rgba(255, 255, 255, 0.8);
|
|
||||||
background-color: rgba(0, 0, 0, 0.4);
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.15s ease;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.album-card:hover .select-toggle {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-toggle.checked {
|
|
||||||
opacity: 1;
|
|
||||||
background-color: var(--yj-accent, #ffd43b);
|
|
||||||
border-color: var(--yj-accent, #ffd43b);
|
|
||||||
}
|
|
||||||
|
|
||||||
.check-icon {
|
|
||||||
color: #000;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cover-image {
|
.cover-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -564,6 +532,10 @@ export class CoverGrid extends LitElement {
|
|||||||
'contextmenu',
|
'contextmenu',
|
||||||
this.closeHandler,
|
this.closeHandler,
|
||||||
);
|
);
|
||||||
|
document.addEventListener(
|
||||||
|
'mousedown',
|
||||||
|
this.mousedownCloseHandler,
|
||||||
|
);
|
||||||
|
|
||||||
// error events do not bubble — use capture
|
// error events do not bubble — use capture
|
||||||
// phase to catch <img> load failures.
|
// phase to catch <img> load failures.
|
||||||
@@ -585,6 +557,10 @@ export class CoverGrid extends LitElement {
|
|||||||
'contextmenu',
|
'contextmenu',
|
||||||
this.closeHandler,
|
this.closeHandler,
|
||||||
);
|
);
|
||||||
|
document.removeEventListener(
|
||||||
|
'mousedown',
|
||||||
|
this.mousedownCloseHandler,
|
||||||
|
);
|
||||||
this.removeEventListener(
|
this.removeEventListener(
|
||||||
'error',
|
'error',
|
||||||
this.onGridImageError,
|
this.onGridImageError,
|
||||||
@@ -2104,28 +2080,36 @@ export class CoverGrid extends LitElement {
|
|||||||
* Dropdown (expand/collapse)
|
* Dropdown (expand/collapse)
|
||||||
* ==================================================================== */
|
* ==================================================================== */
|
||||||
|
|
||||||
private async toggleDropdown(
|
/** Close the dropdown if one is open. */
|
||||||
|
private closeDropdown() {
|
||||||
|
if (this.expandedAlbumId === null) return;
|
||||||
|
|
||||||
|
this.expandedAlbumId = null;
|
||||||
|
this.expandedTracks = [];
|
||||||
|
this.selectedTracks = new Set();
|
||||||
|
this.lastSelectedTrackIndex = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open (or switch to) the given album's
|
||||||
|
* dropdown. If the dropdown is already open
|
||||||
|
* for the same album this is a no-op.
|
||||||
|
*/
|
||||||
|
private async openDropdown(
|
||||||
album: library.Album,
|
album: library.Album,
|
||||||
) {
|
) {
|
||||||
if (this.expandedAlbumId === album.ID) {
|
if (this.expandedAlbumId === album.ID) return;
|
||||||
// Close
|
|
||||||
this.expandedAlbumId = null;
|
|
||||||
this.expandedTracks = [];
|
|
||||||
this.selectedTracks = new Set();
|
|
||||||
this.lastSelectedTrackIndex = null;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open (or switch)
|
|
||||||
this.expandedAlbumId = album.ID;
|
this.expandedAlbumId = album.ID;
|
||||||
this.expandedTracks = [];
|
this.expandedTracks = [];
|
||||||
this.selectedTracks = new Set();
|
this.selectedTracks = new Set();
|
||||||
this.lastSelectedTrackIndex = null;
|
this.lastSelectedTrackIndex = null;
|
||||||
try {
|
|
||||||
const tracks = await GetAlbumTracks(album.ID);
|
|
||||||
|
|
||||||
// Only apply if still the same album
|
try {
|
||||||
|
const tracks = await GetAlbumTracks(
|
||||||
|
album.ID,
|
||||||
|
);
|
||||||
|
|
||||||
if (this.expandedAlbumId === album.ID) {
|
if (this.expandedAlbumId === album.ID) {
|
||||||
this.expandedTracks = tracks;
|
this.expandedTracks = tracks;
|
||||||
}
|
}
|
||||||
@@ -2137,14 +2121,25 @@ export class CoverGrid extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Close the dropdown if one is open. */
|
/**
|
||||||
private closeDropdown() {
|
* Synchronise the dropdown to the current
|
||||||
if (this.expandedAlbumId === null) return;
|
* selection: open the sole selected album's
|
||||||
|
* dropdown, or close it when zero or many
|
||||||
|
* albums are selected.
|
||||||
|
*/
|
||||||
|
private syncDropdownToSelection() {
|
||||||
|
if (this.selectedAlbums.size === 1) {
|
||||||
|
const [albumId] = this.selectedAlbums;
|
||||||
|
const album = this.filteredAlbums.find(
|
||||||
|
(a) => a.ID === albumId,
|
||||||
|
);
|
||||||
|
|
||||||
this.expandedAlbumId = null;
|
if (album) {
|
||||||
this.expandedTracks = [];
|
void this.openDropdown(album);
|
||||||
this.selectedTracks = new Set();
|
}
|
||||||
this.lastSelectedTrackIndex = null;
|
} else {
|
||||||
|
this.closeDropdown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
@@ -2211,7 +2206,7 @@ export class CoverGrid extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.selectedAlbums = next;
|
this.selectedAlbums = next;
|
||||||
this.closeDropdown();
|
this.syncDropdownToSelection();
|
||||||
void this.warmAlbumFilePathCache();
|
void this.warmAlbumFilePathCache();
|
||||||
} else if (isCtrl) {
|
} else if (isCtrl) {
|
||||||
const next = new Set(this.selectedAlbums);
|
const next = new Set(this.selectedAlbums);
|
||||||
@@ -2224,12 +2219,28 @@ export class CoverGrid extends LitElement {
|
|||||||
|
|
||||||
this.selectedAlbums = next;
|
this.selectedAlbums = next;
|
||||||
this.lastSelectedAlbumIndex = index;
|
this.lastSelectedAlbumIndex = index;
|
||||||
this.closeDropdown();
|
this.syncDropdownToSelection();
|
||||||
void this.warmAlbumFilePathCache();
|
void this.warmAlbumFilePathCache();
|
||||||
} else {
|
} else {
|
||||||
this.selectedAlbums = new Set();
|
// Plain click: if this album is the
|
||||||
void this.toggleDropdown(album);
|
// sole selection, deselect + close.
|
||||||
|
// Otherwise select only this album
|
||||||
|
// and open its dropdown.
|
||||||
|
if (
|
||||||
|
this.selectedAlbums.size === 1 &&
|
||||||
|
this.selectedAlbums.has(album.ID)
|
||||||
|
) {
|
||||||
|
this.selectedAlbums = new Set();
|
||||||
|
this.closeDropdown();
|
||||||
|
} else {
|
||||||
|
this.selectedAlbums = new Set([
|
||||||
|
album.ID,
|
||||||
|
]);
|
||||||
|
void this.openDropdown(album);
|
||||||
|
}
|
||||||
|
|
||||||
this.lastSelectedAlbumIndex = index;
|
this.lastSelectedAlbumIndex = index;
|
||||||
|
void this.warmAlbumFilePathCache();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2247,6 +2258,7 @@ export class CoverGrid extends LitElement {
|
|||||||
if (filePaths.length === 0) return;
|
if (filePaths.length === 0) return;
|
||||||
|
|
||||||
this.selectedAlbums = new Set();
|
this.selectedAlbums = new Set();
|
||||||
|
this.closeDropdown();
|
||||||
queueStore.setQueue(filePaths, 0);
|
queueStore.setQueue(filePaths, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2260,8 +2272,24 @@ export class CoverGrid extends LitElement {
|
|||||||
if (!hit) return;
|
if (!hit) return;
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
void this.toggleDropdown(hit.album);
|
|
||||||
this.lastSelectedAlbumIndex = hit.index;
|
const { album, index } = hit;
|
||||||
|
|
||||||
|
// Mirror plain-click behaviour: toggle
|
||||||
|
// sole selection, or select and open.
|
||||||
|
if (
|
||||||
|
this.selectedAlbums.size === 1 &&
|
||||||
|
this.selectedAlbums.has(album.ID)
|
||||||
|
) {
|
||||||
|
this.selectedAlbums = new Set();
|
||||||
|
this.closeDropdown();
|
||||||
|
} else {
|
||||||
|
this.selectedAlbums = new Set([album.ID]);
|
||||||
|
void this.openDropdown(album);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lastSelectedAlbumIndex = index;
|
||||||
|
void this.warmAlbumFilePathCache();
|
||||||
};
|
};
|
||||||
|
|
||||||
private onGridAlbumContextMenu = (
|
private onGridAlbumContextMenu = (
|
||||||
@@ -2278,6 +2306,7 @@ export class CoverGrid extends LitElement {
|
|||||||
this.selectedAlbums = new Set([
|
this.selectedAlbums = new Set([
|
||||||
hit.album.ID,
|
hit.album.ID,
|
||||||
]);
|
]);
|
||||||
|
this.syncDropdownToSelection();
|
||||||
void this.warmAlbumFilePathCache();
|
void this.warmAlbumFilePathCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2285,48 +2314,6 @@ export class CoverGrid extends LitElement {
|
|||||||
this.openContextMenuAt(e.clientX, e.clientY);
|
this.openContextMenuAt(e.clientX, e.clientY);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection checkbox toggle on album cards.
|
|
||||||
* Stops propagation so that the card click
|
|
||||||
* handler (which toggles the dropdown) does
|
|
||||||
* not fire.
|
|
||||||
*/
|
|
||||||
private onSelectToggleClick = (
|
|
||||||
e: MouseEvent,
|
|
||||||
) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
const hit = this.resolveAlbumFromEvent(e);
|
|
||||||
|
|
||||||
if (!hit) return;
|
|
||||||
|
|
||||||
const { album, index } = hit;
|
|
||||||
const next = new Set(this.selectedAlbums);
|
|
||||||
|
|
||||||
if (next.has(album.ID)) {
|
|
||||||
next.delete(album.ID);
|
|
||||||
} else {
|
|
||||||
next.add(album.ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectedAlbums = next;
|
|
||||||
this.lastSelectedAlbumIndex = index;
|
|
||||||
|
|
||||||
// Lightweight dropdown close: set the
|
|
||||||
// skipOverlay flag so willUpdate skips
|
|
||||||
// the expensive overlay capture and
|
|
||||||
// scroll-restore machinery.
|
|
||||||
if (this.expandedAlbumId !== null) {
|
|
||||||
this.skipOverlay = true;
|
|
||||||
this.expandedAlbumId = null;
|
|
||||||
this.expandedTracks = [];
|
|
||||||
this.selectedTracks = new Set();
|
|
||||||
this.lastSelectedTrackIndex = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void this.warmAlbumFilePathCache();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegated image error handler — falls back from
|
* Delegated image error handler — falls back from
|
||||||
* thumbnail to full-size cover art.
|
* thumbnail to full-size cover art.
|
||||||
@@ -2869,18 +2856,6 @@ export class CoverGrid extends LitElement {
|
|||||||
>
|
>
|
||||||
${this.getAlbumInitial(album.Name)}
|
${this.getAlbumInitial(album.Name)}
|
||||||
</div>`}
|
</div>`}
|
||||||
<div
|
|
||||||
class="select-toggle ${selected ? 'checked' : ''}"
|
|
||||||
@click=${this.onSelectToggleClick}
|
|
||||||
>
|
|
||||||
${selected
|
|
||||||
? html`<span
|
|
||||||
class="check-icon"
|
|
||||||
>
|
|
||||||
✓
|
|
||||||
</span>`
|
|
||||||
: nothing}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="album-info">
|
<div class="album-info">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -182,6 +182,23 @@ export class PlaylistView
|
|||||||
this.closePlaylistContextMenu();
|
this.closePlaylistContextMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private mousedownCloseHandler = (
|
||||||
|
e: MouseEvent,
|
||||||
|
) => {
|
||||||
|
const path = e.composedPath();
|
||||||
|
const popup = this.contextMenuPopup;
|
||||||
|
const submenu = this.playlistSubmenuPopup;
|
||||||
|
const plPopup =
|
||||||
|
this.playlistContextMenuPopup;
|
||||||
|
|
||||||
|
if (popup && path.includes(popup)) return;
|
||||||
|
if (submenu && path.includes(submenu)) return;
|
||||||
|
if (plPopup && path.includes(plPopup)) return;
|
||||||
|
|
||||||
|
this.closeContextMenu();
|
||||||
|
this.closePlaylistContextMenu();
|
||||||
|
};
|
||||||
|
|
||||||
private clearSelectionHandler = (e: MouseEvent) => {
|
private clearSelectionHandler = (e: MouseEvent) => {
|
||||||
const path = e.composedPath();
|
const path = e.composedPath();
|
||||||
const isTrackClick = path.some(
|
const isTrackClick = path.some(
|
||||||
@@ -664,6 +681,10 @@ export class PlaylistView
|
|||||||
'contextmenu',
|
'contextmenu',
|
||||||
this.closeContextMenuHandler,
|
this.closeContextMenuHandler,
|
||||||
);
|
);
|
||||||
|
document.addEventListener(
|
||||||
|
'mousedown',
|
||||||
|
this.mousedownCloseHandler,
|
||||||
|
);
|
||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
'click',
|
'click',
|
||||||
this.clearSelectionHandler,
|
this.clearSelectionHandler,
|
||||||
@@ -687,6 +708,10 @@ export class PlaylistView
|
|||||||
'contextmenu',
|
'contextmenu',
|
||||||
this.closeContextMenuHandler,
|
this.closeContextMenuHandler,
|
||||||
);
|
);
|
||||||
|
document.removeEventListener(
|
||||||
|
'mousedown',
|
||||||
|
this.mousedownCloseHandler,
|
||||||
|
);
|
||||||
document.removeEventListener(
|
document.removeEventListener(
|
||||||
'click',
|
'click',
|
||||||
this.clearSelectionHandler,
|
this.clearSelectionHandler,
|
||||||
|
|||||||
@@ -97,6 +97,17 @@ export class QueuePanel
|
|||||||
private closeContextMenuHandler = () =>
|
private closeContextMenuHandler = () =>
|
||||||
this.closeContextMenu();
|
this.closeContextMenu();
|
||||||
|
|
||||||
|
private mousedownCloseHandler = (e: MouseEvent) => {
|
||||||
|
const path = e.composedPath();
|
||||||
|
const popup = this.contextMenuPopup;
|
||||||
|
const submenu = this.playlistSubmenuPopup;
|
||||||
|
|
||||||
|
if (popup && path.includes(popup)) return;
|
||||||
|
if (submenu && path.includes(submenu)) return;
|
||||||
|
|
||||||
|
this.closeContextMenu();
|
||||||
|
};
|
||||||
|
|
||||||
private clearSelectionHandler = (e: MouseEvent) => {
|
private clearSelectionHandler = (e: MouseEvent) => {
|
||||||
const path = e.composedPath();
|
const path = e.composedPath();
|
||||||
const isTrackClick = path.some(
|
const isTrackClick = path.some(
|
||||||
@@ -453,6 +464,10 @@ export class QueuePanel
|
|||||||
'contextmenu',
|
'contextmenu',
|
||||||
this.closeContextMenuHandler,
|
this.closeContextMenuHandler,
|
||||||
);
|
);
|
||||||
|
document.addEventListener(
|
||||||
|
'mousedown',
|
||||||
|
this.mousedownCloseHandler,
|
||||||
|
);
|
||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
'click',
|
'click',
|
||||||
this.clearSelectionHandler,
|
this.clearSelectionHandler,
|
||||||
@@ -485,6 +500,10 @@ export class QueuePanel
|
|||||||
'contextmenu',
|
'contextmenu',
|
||||||
this.closeContextMenuHandler,
|
this.closeContextMenuHandler,
|
||||||
);
|
);
|
||||||
|
document.removeEventListener(
|
||||||
|
'mousedown',
|
||||||
|
this.mousedownCloseHandler,
|
||||||
|
);
|
||||||
document.removeEventListener(
|
document.removeEventListener(
|
||||||
'click',
|
'click',
|
||||||
this.clearSelectionHandler,
|
this.clearSelectionHandler,
|
||||||
|
|||||||
@@ -66,6 +66,19 @@ export class TrackList extends LitElement implements SelectionHost {
|
|||||||
|
|
||||||
private closeHandler = () => this.closeContextMenu();
|
private closeHandler = () => this.closeContextMenu();
|
||||||
|
|
||||||
|
private mousedownCloseHandler = (
|
||||||
|
e: MouseEvent,
|
||||||
|
) => {
|
||||||
|
const path = e.composedPath();
|
||||||
|
const popup = this.contextMenuPopup;
|
||||||
|
const submenu = this.playlistSubmenuPopup;
|
||||||
|
|
||||||
|
if (popup && path.includes(popup)) return;
|
||||||
|
if (submenu && path.includes(submenu)) return;
|
||||||
|
|
||||||
|
this.closeContextMenu();
|
||||||
|
};
|
||||||
|
|
||||||
private clearSelectionHandler = (e: MouseEvent) => {
|
private clearSelectionHandler = (e: MouseEvent) => {
|
||||||
const path = e.composedPath();
|
const path = e.composedPath();
|
||||||
const isTrackClick = path.some(
|
const isTrackClick = path.some(
|
||||||
@@ -437,6 +450,7 @@ export class TrackList extends LitElement implements SelectionHost {
|
|||||||
);
|
);
|
||||||
document.addEventListener('click', this.closeHandler);
|
document.addEventListener('click', this.closeHandler);
|
||||||
document.addEventListener('contextmenu', this.closeHandler);
|
document.addEventListener('contextmenu', this.closeHandler);
|
||||||
|
document.addEventListener('mousedown', this.mousedownCloseHandler);
|
||||||
document.addEventListener('click', this.clearSelectionHandler);
|
document.addEventListener('click', this.clearSelectionHandler);
|
||||||
document.addEventListener('mousemove', this.onColResizeMove);
|
document.addEventListener('mousemove', this.onColResizeMove);
|
||||||
document.addEventListener('mouseup', this.onColResizeEnd);
|
document.addEventListener('mouseup', this.onColResizeEnd);
|
||||||
@@ -458,6 +472,7 @@ export class TrackList extends LitElement implements SelectionHost {
|
|||||||
this.cancelScanComplete?.();
|
this.cancelScanComplete?.();
|
||||||
document.removeEventListener('click', this.closeHandler);
|
document.removeEventListener('click', this.closeHandler);
|
||||||
document.removeEventListener('contextmenu', this.closeHandler);
|
document.removeEventListener('contextmenu', this.closeHandler);
|
||||||
|
document.removeEventListener('mousedown', this.mousedownCloseHandler);
|
||||||
document.removeEventListener('click', this.clearSelectionHandler);
|
document.removeEventListener('click', this.clearSelectionHandler);
|
||||||
document.removeEventListener('mousemove', this.onColResizeMove);
|
document.removeEventListener('mousemove', this.onColResizeMove);
|
||||||
document.removeEventListener('mouseup', this.onColResizeEnd);
|
document.removeEventListener('mouseup', this.onColResizeEnd);
|
||||||
|
|||||||
Reference in New Issue
Block a user