feat: full player basic ui

This commit is contained in:
Araozu 2024-10-18 22:54:31 -05:00
parent fdfde86360
commit da39b305c8
4 changed files with 292 additions and 83 deletions

View File

@ -15,6 +15,7 @@ type ClientSong struct {
Title string `json:"title"`
Artist string `json:"artist"`
AlbumId string `json:"albumId"`
Album string `json:"album"`
SongId string `json:"songId"`
}
@ -30,21 +31,10 @@ func allAlbumsPage(c echo.Context) error {
// if there's a search query, do that
searchQuery := c.QueryParam("s")
isHtmxRequest := c.Request().Header.Get("HX-Request") == "true"
// get the first 10 albums
token, server := utils.Credentials(c)
var (
albums []utils.Album
err error
)
if searchQuery != "" {
// search for the requested albums
albums, err = searchAlbums(token, searchQuery, server, 0, 20)
} else {
// get 10 random albums
albums, err = loadAlbums(token, server, 0, 30)
}
// if searchQuery is empty, this will get the first 30 albums
albums, err := searchAlbums(token, searchQuery, server, 0, 30)
if err != nil {
return err
@ -105,6 +95,7 @@ func albumPage(c echo.Context) error {
Title: song.Title,
Artist: song.Artist,
AlbumId: album.ID,
Album: album.Name,
SongId: song.ID,
}
}

View File

@ -33,28 +33,6 @@ func searchAlbums(token, query, server string, start, end int) ([]utils.Album, e
return albums, nil
}
func loadAlbums(token, server string, start, end int) ([]utils.Album, error) {
var albums []utils.Album
var error utils.NavError
client := resty.New()
response, err := client.R().
SetHeader("x-nd-authorization", fmt.Sprintf("Bearer %s", token)).
SetResult(&albums).
SetError(&error).
Get(fmt.Sprintf("%s/api/album?_start=%d&_end=%d&_sort=name&_order=ASC", server, start, end))
if err != nil {
return nil, err
}
if !response.IsSuccess() {
return nil, errors.New(error.Error)
}
return albums, nil
}
func loadAlbum(token, server, albumId string) (*utils.Album, error) {
var album utils.Album
var error utils.NavError

View File

@ -33,10 +33,16 @@ templ MusicPlayer() {
class="fixed bottom-0 left-0 w-screen border-t border-sky-500 grid grid-cols-[3rem_auto_3rem_3rem] gap-2 p-1 bg-white"
x-data="player"
>
<div class="h-12 bg-sky-200 rounded">
<div
class="h-12 bg-sky-200 rounded"
_="on click toggle .hidden on #full-music-player"
>
<img class="rounded" id="music-player-img" :src="queue[idx]? `/covers/${queue[idx]?.albumId}` : ''"/>
</div>
<div class="w-full overflow-hidden">
<div
class="w-full overflow-hidden"
_="on click toggle .hidden on #full-music-player"
>
<p
id="music-player-title"
class="overflow-hidden overflow-ellipsis whitespace-nowrap w-full"
@ -68,6 +74,7 @@ templ MusicPlayer() {
>
@skipForwardIcon(24)
</button>
@fullMusicPlayer()
<script>
document.addEventListener('alpine:init', () => {
Alpine.data("player", () => ({
@ -196,6 +203,46 @@ templ MusicPlayer() {
</div>
}
templ fullMusicPlayer() {
<div id="full-music-player" class="fixed top-0 left-0 w-screen h-screen bg-white hidden">
<div class="flex justify-center py-6">
<div class="bg-sky-200 rounded w-[20rem] h-[20rem]">
<img
class="rounded inline-block w-full"
id="full-music-player-img"
:src="queue[idx]? `/covers/${queue[idx]?.albumId}` : ''"
/>
</div>
</div>
<div class="text-center">
<div
class="font-bold text-2xl"
x-text="queue[idx]?.title ?? '-'"
></div>
<div
class="text-lg"
x-text="queue[idx]?.album ?? '-'"
></div>
<div
class="text-sm opacity-75"
x-text="queue[idx]?.artist ?? '-'"
></div>
</div>
<div class="absolute bottom-0 w-full grid grid-cols-2 bg-sky-50">
<button type="button" class="inline-block text-center py-4">
@playlistIcon(24)
</button>
<button
type="button"
class="inline-block text-center py-4"
_="on click toggle .hidden on #full-music-player"
>
@caretDoubleDownIcon(24)
</button>
</div>
</div>
}
templ playIcon(size int) {
<svg
id="play-icon"
@ -251,3 +298,33 @@ templ circleNotchIcon(size int) {
<path d="M232,128a104,104,0,0,1-208,0c0-41,23.81-78.36,60.66-95.27a8,8,0,0,1,6.68,14.54C60.15,61.59,40,93.27,40,128a88,88,0,0,0,176,0c0-34.73-20.15-66.41-51.34-80.73a8,8,0,0,1,6.68-14.54C208.19,49.64,232,87,232,128Z"></path>
</svg>
}
templ playlistIcon(size int) {
<svg
class="inline-block"
xmlns="http://www.w3.org/2000/svg"
fill="#000000"
viewBox="0 0 256 256"
style="--darkreader-inline-fill: #000000;"
data-darkreader-inline-fill=""
width={ strconv.Itoa(size) }
height={ strconv.Itoa(size) }
>
<path d="M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm8,72H160a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16Zm72,48H40a8,8,0,0,0,0,16h72a8,8,0,0,0,0-16Zm135.66-57.7a8,8,0,0,1-10,5.36L208,122.75V192a32.05,32.05,0,1,1-16-27.69V112a8,8,0,0,1,10.3-7.66l40,12A8,8,0,0,1,247.66,126.3ZM192,192a16,16,0,1,0-16,16A16,16,0,0,0,192,192Z"></path>
</svg>
}
templ caretDoubleDownIcon(size int) {
<svg
class="inline-block"
xmlns="http://www.w3.org/2000/svg"
fill="#000000"
viewBox="0 0 256 256"
style="--darkreader-inline-fill: #000000;"
data-darkreader-inline-fill=""
width={ strconv.Itoa(size) }
height={ strconv.Itoa(size) }
>
<path d="M213.66,130.34a8,8,0,0,1,0,11.32l-80,80a8,8,0,0,1-11.32,0l-80-80a8,8,0,0,1,11.32-11.32L128,204.69l74.34-74.35A8,8,0,0,1,213.66,130.34Zm-91.32,11.32a8,8,0,0,0,11.32,0l80-80a8,8,0,0,0-11.32-11.32L128,124.69,53.66,50.34A8,8,0,0,0,42.34,61.66Z"></path>
</svg>
}

View File

@ -68,7 +68,7 @@ func MusicPlayer() templ.Component {
templ_7745c5c3_Var2 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div id=\"music-player\" class=\"fixed bottom-0 left-0 w-screen border-t border-sky-500 grid grid-cols-[3rem_auto_3rem_3rem] gap-2 p-1 bg-white\" x-data=\"player\"><div class=\"h-12 bg-sky-200 rounded\"><img class=\"rounded\" id=\"music-player-img\" :src=\"queue[idx]? `/covers/${queue[idx]?.albumId}` : &#39;&#39;\"></div><div class=\"w-full overflow-hidden\"><p id=\"music-player-title\" class=\"overflow-hidden overflow-ellipsis whitespace-nowrap w-full\" x-text=\"queue[idx]?.title ?? &#39;-&#39;\">-</p><p id=\"music-player-artist\" class=\"text-sm opacity-75 overflow-hidden overflow-ellipsis whitespace-nowrap w-full\" x-text=\"queue[idx]?.artist ?? &#39;-&#39;\">-</p></div><div class=\"flex items-center justify-center cursor-pointer relative\" @click=\"togglePlayPause\">")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div id=\"music-player\" class=\"fixed bottom-0 left-0 w-screen border-t border-sky-500 grid grid-cols-[3rem_auto_3rem_3rem] gap-2 p-1 bg-white\" x-data=\"player\"><div class=\"h-12 bg-sky-200 rounded\" _=\"on click toggle .hidden on #full-music-player\"><img class=\"rounded\" id=\"music-player-img\" :src=\"queue[idx]? `/covers/${queue[idx]?.albumId}` : &#39;&#39;\"></div><div class=\"w-full overflow-hidden\" _=\"on click toggle .hidden on #full-music-player\"><p id=\"music-player-title\" class=\"overflow-hidden overflow-ellipsis whitespace-nowrap w-full\" x-text=\"queue[idx]?.title ?? &#39;-&#39;\">-</p><p id=\"music-player-artist\" class=\"text-sm opacity-75 overflow-hidden overflow-ellipsis whitespace-nowrap w-full\" x-text=\"queue[idx]?.artist ?? &#39;-&#39;\">-</p></div><div class=\"flex items-center justify-center cursor-pointer relative\" @click=\"togglePlayPause\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -92,7 +92,60 @@ func MusicPlayer() templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button><script>\n\t\tdocument.addEventListener('alpine:init', () => {\n\t\t\tAlpine.data(\"player\", () => ({\n\t\t\t\tinit() {\n\t\t\t\t\twindow.replaceQueueAndPlayAt = (...params) => this.replaceQueueAndPlayAt(...params);\n\t\t\t\t},\n\t\t\t\tqueue: [],\n\t\t\t\tidx: 0,\n\t\t\t\tcurrentSound: null,\n\t\t\t\tnextSound: null,\n\t\t\t\tvolume: 0.1,\n\t\t\t\tplaying: false,\n\t\t\t\tloading: false,\n\n\t\t\t\treplaceQueueAndPlayAt(queue, idx) {\n\t\t\t\t\tthis.queue = queue;\n\t\t\t\t\tthis.idx = idx;\n\t\t\t\t\tthis.play();\n\t\t\t\t},\n\t\t\t\t// Plays the song at the current position\n\t\t\t\tasync play() {\n\t\t\t\t\tconst songId = this.queue[this.idx].songId;\n\n\t\t\t\t\tif (this.currentSound !== null) {\n\t\t\t\t\t\tthis.currentSound.fade(this.volume, 0.0, 250);\n\t\t\t\t\t\tawait wait(250);\n\t\t\t\t\t\tthis.currentSound.unload();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst sound = new Howl({\n\t\t\t\t\t\tsrc: `https://navidrome.araozu.dev/rest/stream.view?id=${songId}&v=1.13.0&c=music-to-go&u=fernando&s=49805d&t=4148cd1c83ae1bd01334facf4e70a947`,\n\t\t\t\t\t\thtml5: true,\n\t\t\t\t\t\tvolume: this.volume,\n\t\t\t\t\t})\n\t\t\t\t\tthis.loading = true;\n\t\t\t\t\tsound.play();\n\t\t\t\t\tlet preloadInterval;\n\t\t\t\t\tsound.once(\"load\", () => {\n\t\t\t\t\t\tconst length = sound.duration();\n\t\t\t\t\t\tconst targetLength = length - 5;\n\t\t\t\t\t\tpreloadInterval = setInterval(() => {\n\t\t\t\t\t\t\tconst pos = sound.seek();\n\t\t\t\t\t\t\tif (pos > targetLength) {\n\t\t\t\t\t\t\t\tthis.preload();\n\t\t\t\t\t\t\t\tclearInterval(preloadInterval);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 1000);\n\t\t\t\t\t\tthis.loading = false;\n\t\t\t\t\t\tthis.playing = true;\n\t\t\t\t\t});\n\t\t\t\t\tsound.once(\"end\", () => {\n\t\t\t\t\t\tthis.playing = false;\n\t\t\t\t\t\tthis.next();\n\t\t\t\t\t});\n\t\t\t\t\tthis.currentSound = sound;\n\t\t\t\t},\n\t\t\t\tasync playNext() {\n\t\t\t\t\tthis.currentSound?.unload();\n\t\t\t\t\tthis.nextSound.play();\n\t\t\t\t\tthis.playing = true;\n\t\t\t\t\tthis.currentSound = this.nextSound;\n\t\t\t\t\tthis.nextSound = null;\n\t\t\t\t},\n\t\t\t\ttogglePlayPause() {\n\t\t\t\t\tif (this.playing === true) {\n\t\t\t\t\t\tthis.playing = false;\n\t\t\t\t\t\tthis.currentSound?.pause();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.playing = true;\n\t\t\t\t\t\tthis.currentSound?.play();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnext() {\n\t\t\t\t\tif (this.idx + 1 < this.queue.length) {\n\t\t\t\t\t\tthis.idx += 1;\n\t\t\t\t\t\tthis.playNext();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tpreload() {\n\t\t\t\t\tconsole.log(\"preloading\");\n\t\t\t\t\tif (!(this.idx + 1 < this.queue.length)) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nextSongId = this.queue[this.idx + 1].songId;\n\t\t\t\t\tconst nextSound = new Howl({\n\t\t\t\t\t\tsrc: `https://navidrome.araozu.dev/rest/stream.view?id=${nextSongId}&v=1.13.0&c=music-to-go&u=fernando&s=49805d&t=4148cd1c83ae1bd01334facf4e70a947`,\n\t\t\t\t\t\thtml5: true,\n\t\t\t\t\t\tvolume: 0,\n\t\t\t\t\t\tpreload: true,\n\t\t\t\t\t});\n\t\t\t\t\t// Attempt to play immediately the song, immediately pause it, rewind it and set volume back up\n\t\t\t\t\tnextSound.play();\n\n\t\t\t\t\tlet preloadInterval;\n\t\t\t\t\tnextSound.once(\"load\", () => {\n\t\t\t\t\t\tnextSound.pause();\n\t\t\t\t\t\tnextSound.seek(0);\n\t\t\t\t\t\tnextSound.volume(this.volume);\n\n\t\t\t\t\t\tconst length = nextSound.duration();\n\t\t\t\t\t\tconst targetLength = length - 5;\n\t\t\t\t\t\tpreloadInterval = setInterval(() => {\n\t\t\t\t\t\t\tconst pos = nextSound.seek();\n\t\t\t\t\t\t\tif (pos > targetLength) {\n\t\t\t\t\t\t\t\tthis.preload();\n\t\t\t\t\t\t\t\tclearInterval(preloadInterval);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 1000);\n\t\t\t\t\t\tthis.loading = false;\n\t\t\t\t\t\tthis.playing = true;\n\t\t\t\t\t});\n\t\t\t\t\tnextSound.once(\"end\", () => {\n\t\t\t\t\t\tthis.playing = false;\n\t\t\t\t\t\tthis.next();\n\t\t\t\t\t});\n\t\t\t\t\tthis.nextSound = nextSound;\n\t\t\t\t}\n\t\t\t}));\n\t\t})\n\n\t\tfunction wait(ms) {\n\t\t\treturn new Promise(r => setTimeout(r, ms));\n\t\t}\n\t\t</script></div>")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = fullMusicPlayer().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n\t\tdocument.addEventListener('alpine:init', () => {\n\t\t\tAlpine.data(\"player\", () => ({\n\t\t\t\tinit() {\n\t\t\t\t\twindow.replaceQueueAndPlayAt = (...params) => this.replaceQueueAndPlayAt(...params);\n\t\t\t\t},\n\t\t\t\tqueue: [],\n\t\t\t\tidx: 0,\n\t\t\t\tcurrentSound: null,\n\t\t\t\tnextSound: null,\n\t\t\t\tvolume: 0.1,\n\t\t\t\tplaying: false,\n\t\t\t\tloading: false,\n\n\t\t\t\treplaceQueueAndPlayAt(queue, idx) {\n\t\t\t\t\tthis.queue = queue;\n\t\t\t\t\tthis.idx = idx;\n\t\t\t\t\tthis.play();\n\t\t\t\t},\n\t\t\t\t// Plays the song at the current position\n\t\t\t\tasync play() {\n\t\t\t\t\tconst songId = this.queue[this.idx].songId;\n\n\t\t\t\t\tif (this.currentSound !== null) {\n\t\t\t\t\t\tthis.currentSound.fade(this.volume, 0.0, 250);\n\t\t\t\t\t\tawait wait(250);\n\t\t\t\t\t\tthis.currentSound.unload();\n\t\t\t\t\t}\n\n\t\t\t\t\tconst sound = new Howl({\n\t\t\t\t\t\tsrc: `https://navidrome.araozu.dev/rest/stream.view?id=${songId}&v=1.13.0&c=music-to-go&u=fernando&s=49805d&t=4148cd1c83ae1bd01334facf4e70a947`,\n\t\t\t\t\t\thtml5: true,\n\t\t\t\t\t\tvolume: this.volume,\n\t\t\t\t\t})\n\t\t\t\t\tthis.loading = true;\n\t\t\t\t\tsound.play();\n\t\t\t\t\tlet preloadInterval;\n\t\t\t\t\tsound.once(\"load\", () => {\n\t\t\t\t\t\tconst length = sound.duration();\n\t\t\t\t\t\tconst targetLength = length - 5;\n\t\t\t\t\t\tpreloadInterval = setInterval(() => {\n\t\t\t\t\t\t\tconst pos = sound.seek();\n\t\t\t\t\t\t\tif (pos > targetLength) {\n\t\t\t\t\t\t\t\tthis.preload();\n\t\t\t\t\t\t\t\tclearInterval(preloadInterval);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 1000);\n\t\t\t\t\t\tthis.loading = false;\n\t\t\t\t\t\tthis.playing = true;\n\t\t\t\t\t});\n\t\t\t\t\tsound.once(\"end\", () => {\n\t\t\t\t\t\tthis.playing = false;\n\t\t\t\t\t\tthis.next();\n\t\t\t\t\t});\n\t\t\t\t\tthis.currentSound = sound;\n\t\t\t\t},\n\t\t\t\tasync playNext() {\n\t\t\t\t\tthis.currentSound?.unload();\n\t\t\t\t\tthis.nextSound.play();\n\t\t\t\t\tthis.playing = true;\n\t\t\t\t\tthis.currentSound = this.nextSound;\n\t\t\t\t\tthis.nextSound = null;\n\t\t\t\t},\n\t\t\t\ttogglePlayPause() {\n\t\t\t\t\tif (this.playing === true) {\n\t\t\t\t\t\tthis.playing = false;\n\t\t\t\t\t\tthis.currentSound?.pause();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.playing = true;\n\t\t\t\t\t\tthis.currentSound?.play();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnext() {\n\t\t\t\t\tif (this.idx + 1 < this.queue.length) {\n\t\t\t\t\t\tthis.idx += 1;\n\t\t\t\t\t\tthis.playNext();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tpreload() {\n\t\t\t\t\tconsole.log(\"preloading\");\n\t\t\t\t\tif (!(this.idx + 1 < this.queue.length)) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nextSongId = this.queue[this.idx + 1].songId;\n\t\t\t\t\tconst nextSound = new Howl({\n\t\t\t\t\t\tsrc: `https://navidrome.araozu.dev/rest/stream.view?id=${nextSongId}&v=1.13.0&c=music-to-go&u=fernando&s=49805d&t=4148cd1c83ae1bd01334facf4e70a947`,\n\t\t\t\t\t\thtml5: true,\n\t\t\t\t\t\tvolume: 0,\n\t\t\t\t\t\tpreload: true,\n\t\t\t\t\t});\n\t\t\t\t\t// Attempt to play immediately the song, immediately pause it, rewind it and set volume back up\n\t\t\t\t\tnextSound.play();\n\n\t\t\t\t\tlet preloadInterval;\n\t\t\t\t\tnextSound.once(\"load\", () => {\n\t\t\t\t\t\tnextSound.pause();\n\t\t\t\t\t\tnextSound.seek(0);\n\t\t\t\t\t\tnextSound.volume(this.volume);\n\n\t\t\t\t\t\tconst length = nextSound.duration();\n\t\t\t\t\t\tconst targetLength = length - 5;\n\t\t\t\t\t\tpreloadInterval = setInterval(() => {\n\t\t\t\t\t\t\tconst pos = nextSound.seek();\n\t\t\t\t\t\t\tif (pos > targetLength) {\n\t\t\t\t\t\t\t\tthis.preload();\n\t\t\t\t\t\t\t\tclearInterval(preloadInterval);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}, 1000);\n\t\t\t\t\t\tthis.loading = false;\n\t\t\t\t\t\tthis.playing = true;\n\t\t\t\t\t});\n\t\t\t\t\tnextSound.once(\"end\", () => {\n\t\t\t\t\t\tthis.playing = false;\n\t\t\t\t\t\tthis.next();\n\t\t\t\t\t});\n\t\t\t\t\tthis.nextSound = nextSound;\n\t\t\t\t}\n\t\t\t}));\n\t\t})\n\n\t\tfunction wait(ms) {\n\t\t\treturn new Promise(r => setTimeout(r, ms));\n\t\t}\n\t\t</script></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func fullMusicPlayer() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div id=\"full-music-player\" class=\"fixed top-0 left-0 w-screen h-screen bg-white hidden\"><div class=\"flex justify-center py-6\"><div class=\"bg-sky-200 rounded w-[20rem] h-[20rem]\"><img class=\"rounded inline-block w-full\" id=\"full-music-player-img\" :src=\"queue[idx]? `/covers/${queue[idx]?.albumId}` : &#39;&#39;\"></div></div><div class=\"text-center\"><div class=\"font-bold text-2xl\" x-text=\"queue[idx]?.title ?? &#39;-&#39;\"></div><div class=\"text-lg\" x-text=\"queue[idx]?.album ?? &#39;-&#39;\"></div><div class=\"text-sm opacity-75\" x-text=\"queue[idx]?.artist ?? &#39;-&#39;\"></div></div><div class=\"absolute bottom-0 w-full grid grid-cols-2 bg-sky-50\"><button type=\"button\" class=\"inline-block text-center py-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = playlistIcon(24).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button> <button type=\"button\" class=\"inline-block text-center py-4\" _=\"on click toggle .hidden on #full-music-player\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = caretDoubleDownIcon(24).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -116,21 +169,21 @@ func playIcon(size int) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
if templ_7745c5c3_Var3 == nil {
templ_7745c5c3_Var3 = templ.NopComponent
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
if templ_7745c5c3_Var4 == nil {
templ_7745c5c3_Var4 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<svg id=\"play-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 203, Col: 28}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 250, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -138,12 +191,12 @@ func playIcon(size int) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 204, Col: 29}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 251, Col: 29}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -171,21 +224,21 @@ func pauseIcon(size int) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var6 := templ.GetChildren(ctx)
if templ_7745c5c3_Var6 == nil {
templ_7745c5c3_Var6 = templ.NopComponent
templ_7745c5c3_Var7 := templ.GetChildren(ctx)
if templ_7745c5c3_Var7 == nil {
templ_7745c5c3_Var7 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<svg id=\"pause-icon\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"#000000\" viewBox=\"0 0 256 256\" style=\"--darkreader-inline-fill: #000000;\" data-darkreader-inline-fill=\"\" class=\"hidden\" width=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 224, Col: 28}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 271, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -193,12 +246,12 @@ func pauseIcon(size int) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
var templ_7745c5c3_Var9 string
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 225, Col: 29}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 272, Col: 29}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -226,21 +279,21 @@ func skipForwardIcon(size int) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
if templ_7745c5c3_Var9 == nil {
templ_7745c5c3_Var9 = templ.NopComponent
templ_7745c5c3_Var10 := templ.GetChildren(ctx)
if templ_7745c5c3_Var10 == nil {
templ_7745c5c3_Var10 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 233, Col: 67}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 280, Col: 67}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -248,12 +301,12 @@ func skipForwardIcon(size int) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 233, Col: 97}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 280, Col: 97}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -281,21 +334,21 @@ func circleNotchIcon(size int) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var12 := templ.GetChildren(ctx)
if templ_7745c5c3_Var12 == nil {
templ_7745c5c3_Var12 = templ.NopComponent
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
if templ_7745c5c3_Var13 == nil {
templ_7745c5c3_Var13 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<svg id=\"spinner\" :style=\"{display: loading? &#39;inline-block&#39;: &#39;none&#39;}\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"#000000\" viewBox=\"0 0 256 256\" style=\"--darkreader-inline-fill: #000000;\" data-darkreader-inline-fill=\"\" width=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 247, Col: 28}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 294, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -303,12 +356,12 @@ func circleNotchIcon(size int) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 248, Col: 29}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 295, Col: 29}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -320,4 +373,114 @@ func circleNotchIcon(size int) templ.Component {
})
}
func playlistIcon(size int) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var16 := templ.GetChildren(ctx)
if templ_7745c5c3_Var16 == nil {
templ_7745c5c3_Var16 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<svg class=\"inline-block\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"#000000\" viewBox=\"0 0 256 256\" style=\"--darkreader-inline-fill: #000000;\" data-darkreader-inline-fill=\"\" width=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 310, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" height=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 311, Col: 29}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><path d=\"M32,64a8,8,0,0,1,8-8H216a8,8,0,0,1,0,16H40A8,8,0,0,1,32,64Zm8,72H160a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16Zm72,48H40a8,8,0,0,0,0,16h72a8,8,0,0,0,0-16Zm135.66-57.7a8,8,0,0,1-10,5.36L208,122.75V192a32.05,32.05,0,1,1-16-27.69V112a8,8,0,0,1,10.3-7.66l40,12A8,8,0,0,1,247.66,126.3ZM192,192a16,16,0,1,0-16,16A16,16,0,0,0,192,192Z\"></path></svg>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func caretDoubleDownIcon(size int) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var19 := templ.GetChildren(ctx)
if templ_7745c5c3_Var19 == nil {
templ_7745c5c3_Var19 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<svg class=\"inline-block\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"#000000\" viewBox=\"0 0 256 256\" style=\"--darkreader-inline-fill: #000000;\" data-darkreader-inline-fill=\"\" width=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var20 string
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 325, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" height=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(size))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `src/utils/utils.templ`, Line: 326, Col: 29}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><path d=\"M213.66,130.34a8,8,0,0,1,0,11.32l-80,80a8,8,0,0,1-11.32,0l-80-80a8,8,0,0,1,11.32-11.32L128,204.69l74.34-74.35A8,8,0,0,1,213.66,130.34Zm-91.32,11.32a8,8,0,0,0,11.32,0l80-80a8,8,0,0,0-11.32-11.32L128,124.69,53.66,50.34A8,8,0,0,0,42.34,61.66Z\"></path></svg>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
var _ = templruntime.GeneratedTemplate