161 lines
4.6 KiB
Svelte
161 lines
4.6 KiB
Svelte
<!-- Context menu for tracks -->
|
|
<script lang="ts">
|
|
import LL from "$i18n/i18n-svelte";
|
|
import {
|
|
mdiPlaylistPlay,
|
|
mdiPlaylistPlus,
|
|
mdiAccountMusic,
|
|
mdiAlbum,
|
|
mdiText,
|
|
mdiHeartOutline,
|
|
mdiPlaylistMusic,
|
|
mdiMenuRight,
|
|
mdiShare,
|
|
mdiContentCopy,
|
|
mdiDownload,
|
|
mdiTrashCan,
|
|
mdiSwapVertical,
|
|
mdiArrowUp,
|
|
mdiArrowDown,
|
|
} from "@mdi/js";
|
|
import { melt } from "@melt-ui/svelte";
|
|
import { createEventDispatcher } from "svelte";
|
|
|
|
import { POSITIONING_SUBMENU } from "$lib/util/constants";
|
|
import type { ItemMoveData, Track } from "$lib/util/types";
|
|
|
|
import Icon from "$lib/components/ui/Icon.svelte";
|
|
import AddPlaylistMenu from "./AddPlaylistMenu.svelte";
|
|
|
|
import "./ctxmenu.css";
|
|
|
|
export let tracks: Track[];
|
|
export let playlistIndex: number | undefined = undefined;
|
|
|
|
export let open: boolean;
|
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
export let menu: any;
|
|
export let item: any;
|
|
export let createSubmenu: any;
|
|
/* eslint-enable */
|
|
|
|
const dispatch = createEventDispatcher();
|
|
|
|
$: single = tracks.length === 1;
|
|
|
|
const {
|
|
elements: { subMenu: playlistMenu, subTrigger: playlistMenuTrigger },
|
|
states: { subOpen: playlistMenuOpen },
|
|
} = createSubmenu({
|
|
arrowSize: 0,
|
|
positioning: POSITIONING_SUBMENU,
|
|
disableTypeahead: true,
|
|
});
|
|
|
|
const {
|
|
elements: { subMenu: moveMenu, subTrigger: moveMenuTrigger },
|
|
} = createSubmenu({ arrowSize: 0, positioning: POSITIONING_SUBMENU });
|
|
|
|
const {
|
|
elements: { subMenu: shareMenu, subTrigger: shareMenuTrigger },
|
|
} = createSubmenu({ arrowSize: 0, positioning: POSITIONING_SUBMENU });
|
|
|
|
function moveItem(target: number) {
|
|
if (playlistIndex === undefined) return;
|
|
dispatch("moveTracks", {
|
|
position: single ? playlistIndex : null,
|
|
target,
|
|
} satisfies ItemMoveData);
|
|
}
|
|
</script>
|
|
|
|
{#if open}
|
|
<div class="ctxmenu" use:melt={menu}>
|
|
{#if !single}
|
|
<div class="item item-sm item-primary">
|
|
<span>{$LL.n_tracks(tracks.length)}</span>
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Queue -->
|
|
<div class="item" use:melt={item}>
|
|
<Icon path={mdiPlaylistPlay} size={1.4} />
|
|
<span>{$LL.play_next()}</span>
|
|
</div>
|
|
<div class="item" use:melt={item}>
|
|
<Icon path={mdiPlaylistPlus} size={1.4} />
|
|
<span>{$LL.add_to_queue()}</span>
|
|
</div>
|
|
|
|
<!-- Track details -->
|
|
{#if single}
|
|
<div class="item sep" use:melt={item}>
|
|
<Icon path={mdiAccountMusic} size={1.4} />
|
|
<span>{$LL.view_artist()}</span>
|
|
</div>
|
|
<div class="item" use:melt={item}>
|
|
<Icon path={mdiAlbum} size={1.4} />
|
|
<span>{$LL.view_album()}</span>
|
|
</div>
|
|
<div class="item" use:melt={item}>
|
|
<Icon path={mdiText} size={1.4} />
|
|
<span>{$LL.view_track_info()}</span>
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- User library -->
|
|
<div class="item sep" use:melt={item}>
|
|
<Icon path={mdiHeartOutline} size={1.4} />
|
|
<span>{$LL.library_add()}</span>
|
|
</div>
|
|
<div class="item" use:melt={$playlistMenuTrigger}>
|
|
<Icon path={mdiPlaylistMusic} size={1.4} />
|
|
<span>{$LL.playlist_add()}</span>
|
|
<div class="icon-r"><Icon path={mdiMenuRight} /></div>
|
|
</div>
|
|
|
|
<!-- Playlist modification -->
|
|
{#if playlistIndex !== undefined}
|
|
<div class="item sep" use:melt={item}>
|
|
<Icon path={mdiTrashCan} size={1.4} />
|
|
<span>{$LL.playlist_remove()}</span>
|
|
</div>
|
|
<div class="item" use:melt={$moveMenuTrigger}>
|
|
<Icon path={mdiSwapVertical} size={1.4} />
|
|
<span>{$LL.move()}</span>
|
|
<div class="icon-r"><Icon path={mdiMenuRight} /></div>
|
|
</div>
|
|
{/if}
|
|
|
|
<!-- Share -->
|
|
<div class="item sep" use:melt={$shareMenuTrigger}>
|
|
<Icon path={mdiShare} size={1.4} />
|
|
<span>{$LL.share()}</span>
|
|
<div class="icon-r"><Icon path={mdiMenuRight} /></div>
|
|
</div>
|
|
</div>
|
|
|
|
<AddPlaylistMenu menu={$playlistMenu} {item} open={$playlistMenuOpen} />
|
|
|
|
<div class="ctxmenu" use:melt={$moveMenu}>
|
|
<div class="item" use:melt={item} on:m-click={() => moveItem(0)}>
|
|
<Icon path={mdiArrowUp} size={1.4} />
|
|
<span>To the top</span>
|
|
</div>
|
|
<div class="item" use:melt={item} on:m-click={() => moveItem(-1)}>
|
|
<Icon path={mdiArrowDown} size={1.4} />
|
|
<span>To the bottom</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ctxmenu" use:melt={$shareMenu}>
|
|
<div class="item" use:melt={item}>
|
|
<Icon path={mdiContentCopy} size={1.4} />
|
|
<span>{single ? $LL.copy_url() : $LL.copy_urls()}</span>
|
|
</div>
|
|
<div class="item" use:melt={item}>
|
|
<Icon path={mdiDownload} size={1.4} />
|
|
<span>{single ? $LL.download_audio_file() : $LL.download_audio_files()}</span>
|
|
</div>
|
|
</div>
|
|
{/if}
|