TirayaFrontend/src/lib/components/player/Playerbar.svelte

167 lines
4.6 KiB
Svelte

<script lang="ts">
import LL from "$i18n/i18n-svelte";
import {
mdiPlay,
mdiSkipPrevious,
mdiSkipNext,
mdiShuffle,
mdiRepeat,
mdiDotsVertical,
mdiFullscreen,
mdiRepeatOnce,
mdiPause,
mdiPlaylistPlay,
} from "@mdi/js";
import { createDropdownMenu } from "@melt-ui/svelte";
import IconButton from "$lib/components/ui/IconButton.svelte";
import Slider from "$lib/components/ui/Slider.svelte";
import CurrentCover from "./CurrentCover.svelte";
import TrackName from "./TrackName.svelte";
import VolumeControl from "./VolumeControl.svelte";
import LikeButton from "$lib/components/ui/LikeButton.svelte";
import IconToggle from "$lib/components/ui/IconToggle.svelte";
import IconToggleMulti from "$lib/components/ui/IconToggleMulti.svelte";
import IconButtonTrigger from "$lib/components/ui/IconButtonTrigger.svelte";
import TrackMenu from "$lib/components/contextmenu/TrackMenu.svelte";
import { clientState, toggleShowQueue } from "$lib/stores/clientState";
import { formatDuration } from "$lib/util/functions";
import { testTrack } from "$lib/util/testdata";
import { POSITIONING_DROPDOWN } from "$lib/util/constants";
let position = 81;
let displayPosition = position;
let length = 195;
let track = testTrack;
const {
elements: { trigger, menu, item },
builders: { createSubmenu },
states: { open: ddnOpen },
} = createDropdownMenu({ positioning: POSITIONING_DROPDOWN });
</script>
<div id="playerbar">
<div class="px-4" class:pl-4={!$clientState.currentCoverLarge}>
<!-- current track -->
<div class="track">
<div
class="flex items-center justify-start"
aria-label={$LL.now_playing({
title: track.name,
artist: track.artists[0].name,
})}
>
<CurrentCover />
<TrackName {track} />
<LikeButton />
</div>
</div>
<!-- controls -->
<div class="control">
<div class="flex flex-col justify-center items-center space-y-1">
<div class="flex w-full space-x-2 justify-center items-center">
<IconToggle
iconOn={mdiShuffle}
ariaLabelOn={$LL.shuffle_enable()}
ariaLabelOff={$LL.shuffle_disable()}
/>
<IconButton path={mdiSkipPrevious} size="md" ariaLabel={$LL.previous()} />
<IconToggle
iconOn={mdiPause}
iconOff={mdiPlay}
size="md"
color="primary"
iColorOn=""
ariaLabelOn={$LL.play()}
ariaLabelOff={$LL.pause()}
/>
<IconButton path={mdiSkipNext} size="md" ariaLabel={$LL.next()} />
<IconToggleMulti
icons={[mdiRepeat, mdiRepeat, mdiRepeatOnce]}
ariaLabels={[$LL.repeat_disable(), $LL.repeat_queue(), $LL.repeat_track()]}
/>
</div>
<div
class="flex items-center justify-between w-full text-sm text-base-content text-opacity-70"
>
<span class="w-12 text-right"
>{formatDuration(Math.round(displayPosition))}</span
>
<Slider
min={0}
max={length}
bind:value={position}
bind:displayValue={displayPosition}
ariaLabel={$LL.seek_bar()}
/>
<span class="w-12">{formatDuration(length)}</span>
</div>
</div>
</div>
<!-- options -->
<div class="options">
<div class="flex justify-end items-center flex-grow space-x-1">
<IconToggle
iconOn={mdiPlaylistPlay}
value={$clientState.showQueue}
ariaLabelOn={$LL.queue_show()}
ariaLabelOff={$LL.queue_hide()}
on:change={toggleShowQueue}
/>
<VolumeControl />
<IconButton path={mdiFullscreen} ariaLabel={$LL.fullscreen_player()} />
<IconButtonTrigger
path={mdiDotsVertical}
ariaLabel={$LL.track_options()}
trigger={$trigger}
/>
</div>
</div>
</div>
</div>
<TrackMenu
menu={$menu}
item={$item}
open={$ddnOpen}
{createSubmenu}
tracks={[testTrack]}
/>
<style lang="postcss">
#playerbar {
@apply bg-base-200;
grid-area: player / player / player / player;
width: 100%;
min-width: 768px;
& > div {
min-width: 620px;
height: 90px;
display: flex;
justify-content: space-between;
align-items: center;
}
}
.track {
min-width: 180px;
width: 30%;
}
.control {
max-width: 722px;
width: 40%;
}
.options {
display: flex;
justify-content: flex-end;
min-width: 180px;
width: 30%;
}
</style>