Add tracklist to audio player

This commit is contained in:
2024-03-15 13:59:34 +01:00
parent 13c5889a56
commit 7024648712
4 changed files with 98 additions and 63 deletions

View File

@@ -1,58 +1,47 @@
<script>
import { createEventDispatcher, onMount } from 'svelte'
import { fs_path_url } from '../FilesystemUtil';
import { onMount } from 'svelte'
import { fs_encode_path, fs_node_icon, fs_path_url } from '../FilesystemUtil';
import FileTitle from '../../file_viewer/viewers/FileTitle.svelte';
let dispatch = createEventDispatcher()
import TextBlock from '../../file_viewer/viewers/TextBlock.svelte';
export let fs_navigator
export let state
let player
let playing = false
let media_session = false
let siblings = []
const toggle_play = () => playing ? player.pause() : player.play()
// Detect when the song changes
$: update_session_meta(state.base.name)
const update_session_meta = name => {
export const update = async () => {
if (media_session) {
navigator.mediaSession.metadata = new MediaMetadata({
title: name,
title: state.base.name,
artist: "pixeldrain",
album: "unknown",
});
}
siblings = await fs_navigator.get_siblings()
}
onMount(() => {
if ('mediaSession' in navigator) {
media_session = true
update_session_meta(state.base.name)
navigator.mediaSession.setActionHandler('play', () => player.play());
navigator.mediaSession.setActionHandler('pause', () => player.pause());
navigator.mediaSession.setActionHandler('stop', () => player.stop());
navigator.mediaSession.setActionHandler('previoustrack', () => dispatch("open_sibling", -1));
navigator.mediaSession.setActionHandler('nexttrack', () => dispatch("open_sibling", 1));
navigator.mediaSession.setActionHandler('previoustrack', () => fs_navigator.open_sibling(-1));
navigator.mediaSession.setActionHandler('nexttrack', () => fs_navigator.open_sibling(1));
}
})
</script>
<slot></slot>
<div class="container">
<FileTitle title={state.base.name}/>
<button on:click={() => dispatch("open_sibling", -1) }><i class="icon">skip_previous</i></button>
<button on:click={() => player.currentTime -= 10 }><i class="icon">replay_10</i></button>
<button on:click={toggle_play}>
{#if playing}
<i class="icon">pause</i>
{:else}
<i class="icon">play_arrow</i>
{/if}
</button>
<button on:click={() => player.currentTime += 10 }><i class="icon">forward_10</i></button>
<button on:click={() => dispatch("open_sibling", 1) }><i class="icon">skip_next</i></button>
<br/><br/>
<FileTitle title={state.base.name}/>
<TextBlock>
<audio
bind:this={player}
class="player"
@@ -61,18 +50,59 @@ onMount(() => {
controls="controls"
on:pause={() => playing = false }
on:play={() => playing = true }
on:ended={() => dispatch("open_sibling", 1) }>
on:ended={() => fs_navigator.open_sibling(1) }>
<track kind="captions"/>
</audio>
</div>
<div style="text-align: center;">
<button on:click={() => fs_navigator.open_sibling(-1) }><i class="icon">skip_previous</i></button>
<button on:click={() => player.currentTime -= 10 }><i class="icon">replay_10</i></button>
<button on:click={toggle_play}>
{#if playing}
<i class="icon">pause</i>
{:else}
<i class="icon">play_arrow</i>
{/if}
</button>
<button on:click={() => player.currentTime += 10 }><i class="icon">forward_10</i></button>
<button on:click={() => fs_navigator.open_sibling(1) }><i class="icon">skip_next</i></button>
</div>
<h2>Tracklist</h2>
{#each siblings as sibling (sibling.path)}
<a
href={"/d"+fs_encode_path(sibling.path)}
on:click|preventDefault={() => fs_navigator.navigate(sibling.path, true)}
class="node"
>
{#if sibling.path === state.base.path}
<i class="play_arrow icon">play_arrow</i>
{:else}
<img src={fs_node_icon(sibling, 64, 64)} class="node_icon" alt="icon"/>
{/if}
<span>{sibling.name}</span>
<br/>
</a>
{/each}
</TextBlock>
<style>
.container {
padding: 0;
overflow-y: auto;
text-align: center;
}
.player {
width: 90%;
width: 100%;
}
.node {
display: flex;
flex-direction: row;
color: var(--body_text_color);
text-decoration: none;
align-items: center;
border-bottom: 1px solid var(--separator);
}
.node_icon {
margin: 4px;
width: 1.5em;
height: 1.5em;
}
.play_arrow {
margin: 4px;
}
</style>

View File

@@ -56,7 +56,7 @@ const state_update = async (base) => {
<CustomBanner path={state.path}/>
</FileManager>
{:else if viewer_type === "audio"}
<Audio state={state} on:open_sibling>
<Audio bind:this={viewer} fs_navigator={fs_navigator} state={state}>
<CustomBanner path={state.path}/>
</Audio>
{:else if viewer_type === "image"}