TirayaFrontend/src/lib/components/contextmenu/TrackMenu.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}