funkwhale/front/public/embed.html

222 wiersze
6.8 KiB
HTML
Czysty Zwykły widok Historia

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="generator" content="Funkwhale">
<link rel="icon" href="/favicon.png">
<title>Funkwhale Widget</title>
<link rel="stylesheet" href="embed.css">
<script type="module">
import { createApp, reactive } from 'https://unpkg.com/petite-vue@0.4.1?module'
const params = new URL(location.href).searchParams
const type = params.get('type')
const id = params.get('id')
// Duration
const ZERO_DATE = +new Date('2022-01-01T00:00:00.000')
const intl = new Intl.DateTimeFormat('en', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hourCycle: 'h23'
})
const tracks = [
{
id: 8,
title: 'Song name',
artist: {
name: 'Artist name'
},
sources: [{ duration: 6666 }]
},
{
id: 9,
title: 'Another song name',
artist: {
name: 'Another artist name'
},
album: {
title: 'Another album title'
},
sources: [{ duration: 666 }]
}
]
// Player
const player = reactive({
playing: false,
current: 0,
seek: 0,
play (index) {
this.current = index
},
togglePlay () {
this.playing = !this.playing
}
})
// Volume
const DEFAULT_VOLUME = 75
const volume = reactive({
level: DEFAULT_VOLUME,
lastLevel: DEFAULT_VOLUME,
mute () {
if (this.lastLevel === 0) {
this.lastLevel = DEFAULT_VOLUME
}
const lastLevel = this.level
this.level = lastLevel === 0
? this.lastLevel
: 0
this.lastLevel = lastLevel
}
})
// Application
const app = createApp({
coverUrl: '',
type,
id,
player,
volume,
tracks,
formatDuration (duration) {
const time = intl.format(new Date(ZERO_DATE + duration * 1e3))
return time.replace(/^00:/, '')
}
})
app.directive('range', (ctx) => {
ctx.effect(() => {
ctx.el.style.setProperty('--value', ctx.get())
})
})
app.mount()
</script>
</head>
<template id="track-entry">
</template>
<body>
<noscript>
<strong>We're sorry but this widget doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<main v-scope v-cloak>
<div class="player">
<img :src="coverUrl" class="cover-image" />
<div class="player-content">
<h1>{{ tracks[player.current].title }}</h1>
<h2>{{ tracks[player.current].artist.name }}</h2>
</div>
<div class="player-controls">
<button>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-skip-start-fill" viewBox="0 0 16 16">
<path d="M4 4a.5.5 0 0 1 1 0v3.248l6.267-3.636c.54-.313 1.232.066 1.232.696v7.384c0 .63-.692 1.01-1.232.697L5 8.753V12a.5.5 0 0 1-1 0V4z"/>
</svg>
</button>
<button @click="player.togglePlay" class="play">
<svg v-if="!player.playing" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play-fill" viewBox="0 0 16 16">
<path d="m11.596 8.697-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z"/>
</svg>
<svg v-else xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pause-fill" viewBox="0 0 16 16">
<path d="M5.5 3.5A1.5 1.5 0 0 1 7 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5zm5 0A1.5 1.5 0 0 1 12 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5z"/>
</svg>
</button>
<button>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-skip-end-fill" viewBox="0 0 16 16">
<path d="M12.5 4a.5.5 0 0 0-1 0v3.248L5.233 3.612C4.693 3.3 4 3.678 4 4.308v7.384c0 .63.692 1.01 1.233.697L11.5 8.753V12a.5.5 0 0 0 1 0V4z"/>
</svg>
</button>
<input
v-model.number="player.seek"
v-range="player.seek"
type="range"
step="0.1"
/>
<button @click="volume.mute">
<svg v-if="volume.level === 0" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-volume-mute-fill" viewBox="0 0 16 16">
<path d="M6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06zm7.137 2.096a.5.5 0 0 1 0 .708L12.207 8l1.647 1.646a.5.5 0 0 1-.708.708L11.5 8.707l-1.646 1.647a.5.5 0 0 1-.708-.708L10.793 8 9.146 6.354a.5.5 0 1 1 .708-.708L11.5 7.293l1.646-1.647a.5.5 0 0 1 .708 0z"/>
</svg>
<svg v-else xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-volume-up-fill" viewBox="0 0 16 16">
<path d="M11.536 14.01A8.473 8.473 0 0 0 14.026 8a8.473 8.473 0 0 0-2.49-6.01l-.708.707A7.476 7.476 0 0 1 13.025 8c0 2.071-.84 3.946-2.197 5.303l.708.707z"/>
<path d="M10.121 12.596A6.48 6.48 0 0 0 12.025 8a6.48 6.48 0 0 0-1.904-4.596l-.707.707A5.483 5.483 0 0 1 11.025 8a5.483 5.483 0 0 1-1.61 3.89l.706.706z"/>
<path d="M8.707 11.182A4.486 4.486 0 0 0 10.025 8a4.486 4.486 0 0 0-1.318-3.182L8 5.525A3.489 3.489 0 0 1 9.025 8 3.49 3.49 0 0 1 8 10.475l.707.707zM6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06z"/>
</svg>
</button>
<input
v-model.number="volume.level"
v-range="volume.level"
type="range"
step="0.1"
/>
</div>
<a
title="Funkwhale"
href="https://funkwhale.audio"
target="_blank"
rel="noopener noreferrer"
class="logo-link"
>
<img src="logo-white.svg" />
</a>
</div>
<div class="track-list">
<table>
<tr
v-for="(track, index) in tracks"
:id="'queue-item-' + index"
:key="track.id"
role="button"
:class="{ 'current': player.current === index }"
@click="player.play(index)"
>
<td>
{{ index + 1 }}
</td>
<td :title="track.title">
{{ track.title }}
</td>
<td :title="track.artist.name">
{{ track.artist.name }}
</td>
<td :title="track.album?.title">
{{ track.album?.title }}
</td>
<td>
{{ formatDuration(track.sources[0].duration) }}
</td>
</tr>
</table>
</div>
</main>
</body>
</html>