feat: traefik config
This commit is contained in:
parent
f262e92e09
commit
004d3de8d7
@ -7,4 +7,19 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "8007:8007"
|
- "8007:8007"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- proxy
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.music.rule=Host(`music.araozu.dev`)"
|
||||||
|
- "traefik.http.routers.music.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.music.tls=true"
|
||||||
|
- "traefik.http.routers.music.tls.certresolver=araozu-wildcard"
|
||||||
|
- "traefik.http.routers.music.tls.domains[0].main=araozu.dev"
|
||||||
|
- "traefik.http.routers.music.tls.domains[0].sans=*.araozu.dev"
|
||||||
|
|
||||||
|
|
||||||
|
networks:
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ func allAlbumsPage(c echo.Context) error {
|
|||||||
|
|
||||||
func albumPage(c echo.Context) error {
|
func albumPage(c echo.Context) error {
|
||||||
token, server := utils.Credentials(c)
|
token, server := utils.Credentials(c)
|
||||||
|
isHtmxRequest := c.Request().Header.Get("HX-Request") == "true"
|
||||||
albumId := c.Param("id")
|
albumId := c.Param("id")
|
||||||
|
|
||||||
// load album info and song list on the background
|
// load album info and song list on the background
|
||||||
@ -110,5 +111,9 @@ func albumPage(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
clientSongsJson := buff.String()
|
clientSongsJson := buff.String()
|
||||||
|
|
||||||
|
if isHtmxRequest {
|
||||||
|
return utils.RenderTempl(c, http.StatusOK, albumTemplFragment(albumId, album, songs, string(clientSongsJson)))
|
||||||
|
} else {
|
||||||
return utils.RenderTempl(c, http.StatusOK, albumTempl(albumId, album, songs, string(clientSongsJson)))
|
return utils.RenderTempl(c, http.StatusOK, albumTempl(albumId, album, songs, string(clientSongsJson)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -59,6 +59,12 @@ templ albumsFragment(albums []utils.Album) {
|
|||||||
// Renders the page of a single Album
|
// Renders the page of a single Album
|
||||||
templ albumTempl(albumId string, album *utils.Album, songs []utils.Song, songsJson string) {
|
templ albumTempl(albumId string, album *utils.Album, songs []utils.Song, songsJson string) {
|
||||||
@utils.SkeletonTempl() {
|
@utils.SkeletonTempl() {
|
||||||
|
@albumTemplFragment(albumId, album, songs, songsJson)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renders the page of a single album, but as a fragment without a skeleton
|
||||||
|
templ albumTemplFragment(albumId string, album *utils.Album, songs []utils.Song, songsJson string) {
|
||||||
<div
|
<div
|
||||||
class="text-center"
|
class="text-center"
|
||||||
_={ fmt.Sprintf("init set $songsJson to %s", songsJson) }
|
_={ fmt.Sprintf("init set $songsJson to %s", songsJson) }
|
||||||
@ -84,6 +90,4 @@ templ albumTempl(albumId string, album *utils.Album, songs []utils.Song, songsJs
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@utils.MusicPlayer()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ templ IndexTempl(albums []utils.Album) {
|
|||||||
@AlbumCard(album)
|
@AlbumCard(album)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@utils.MusicPlayer()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,13 +16,15 @@ templ SkeletonTempl() {
|
|||||||
<script src="/public/js/htmx.min.js" defer></script>
|
<script src="/public/js/htmx.min.js" defer></script>
|
||||||
<script src="/public/js/_hyperscript.min.js" defer></script>
|
<script src="/public/js/_hyperscript.min.js" defer></script>
|
||||||
<script src="/public/js/howler.min.js" defer></script>
|
<script src="/public/js/howler.min.js" defer></script>
|
||||||
|
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.x.x/dist/cdn.min.js"></script>
|
||||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||||
<script src="https://unpkg.com/htmx-ext-response-targets@2.0.0/response-targets.js" defer></script>
|
<script src="https://unpkg.com/htmx-ext-response-targets@2.0.0/response-targets.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="pb-16">
|
<main hx-boost="true" hx-target="this" hx-swap="innerHTML" id="boost-target" class="pb-16">
|
||||||
{ children... }
|
{ children... }
|
||||||
</main>
|
</main>
|
||||||
|
@MusicPlayer()
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
}
|
}
|
||||||
@ -31,6 +33,7 @@ templ MusicPlayer() {
|
|||||||
<div
|
<div
|
||||||
id="music-player"
|
id="music-player"
|
||||||
class="fixed bottom-0 left-0 w-screen border-t bg-c-bg text-c-on-bg border-sky-500 grid grid-cols-[3rem_auto_3rem_3rem] gap-2 p-1"
|
class="fixed bottom-0 left-0 w-screen border-t bg-c-bg text-c-on-bg border-sky-500 grid grid-cols-[3rem_auto_3rem_3rem] gap-2 p-1"
|
||||||
|
hx-preserve
|
||||||
x-data="player"
|
x-data="player"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@ -76,20 +79,27 @@ templ MusicPlayer() {
|
|||||||
</button>
|
</button>
|
||||||
@fullMusicPlayer()
|
@fullMusicPlayer()
|
||||||
<script>
|
<script>
|
||||||
|
console.log("I'm being re-run :o");
|
||||||
document.addEventListener('alpine:init', () => {
|
document.addEventListener('alpine:init', () => {
|
||||||
Alpine.data("player", () => ({
|
Alpine.data("player", function() {
|
||||||
init() {
|
return {
|
||||||
window.replaceQueueAndPlayAt = (...params) => this.replaceQueueAndPlayAt(...params);
|
queue: this.$persist([]),
|
||||||
},
|
idx: this.$persist(0),
|
||||||
queue: [],
|
volume: this.$persist(0.1),
|
||||||
idx: 0,
|
playing: this.$persist(false),
|
||||||
currentSound: null,
|
loading: this.$persist(false),
|
||||||
nextSound: null,
|
progress: this.$persist(0),
|
||||||
volume: 0.1,
|
// These cannot be persisted because they cannot be stored in localstorage
|
||||||
playing: false,
|
|
||||||
loading: false,
|
|
||||||
progress: 0,
|
|
||||||
listenerInterval: 0,
|
listenerInterval: 0,
|
||||||
|
//currentSound: null,
|
||||||
|
//nextSound: null,
|
||||||
|
|
||||||
|
init() {
|
||||||
|
console.log("calling alpine init method...")
|
||||||
|
window.replaceQueueAndPlayAt = (...params) => this.replaceQueueAndPlayAt(...params);
|
||||||
|
window.currentSound = null;
|
||||||
|
window.nextSound = null;
|
||||||
|
},
|
||||||
|
|
||||||
// sets the queue, and plays the song at idx
|
// sets the queue, and plays the song at idx
|
||||||
replaceQueueAndPlayAt(queue, idx) {
|
replaceQueueAndPlayAt(queue, idx) {
|
||||||
@ -109,30 +119,30 @@ templ MusicPlayer() {
|
|||||||
// If preloaded=true, this function will assume that it is the
|
// If preloaded=true, this function will assume that it is the
|
||||||
// next song. It will trust that idx is correct.
|
// next song. It will trust that idx is correct.
|
||||||
async play(idx) {
|
async play(idx) {
|
||||||
const preloaded = this.nextSound !== null && idx === this.idx + 1;
|
const preloaded = window.nextSound !== null && idx === this.idx + 1;
|
||||||
|
|
||||||
// if a song is currently playing
|
// if a song is currently playing
|
||||||
// then fade it out before playing the next sound
|
// then fade it out before playing the next sound
|
||||||
if (this.playing === true
|
if (this.playing === true
|
||||||
&& this.currentSound !== null
|
&& window.currentSound !== null
|
||||||
) {
|
) {
|
||||||
// this will not trigger when next() is called,
|
// this will not trigger when next() is called,
|
||||||
// because next() sets this.playing=false
|
// because next() sets this.playing=false
|
||||||
|
|
||||||
this.currentSound.fade(this.volume, 0.0, 250);
|
window.currentSound.fade(this.volume, 0.0, 250);
|
||||||
await wait(250);
|
await wait(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentSound?.unload?.();
|
window.currentSound?.unload?.();
|
||||||
this.playing = false;
|
this.playing = false;
|
||||||
this.currentSound = null;
|
window.currentSound = null;
|
||||||
this.idx = idx;
|
this.idx = idx;
|
||||||
|
|
||||||
// if a song is preloaded, assume it's the next song and play it
|
// if a song is preloaded, assume it's the next song and play it
|
||||||
if (preloaded === true && this.nextSound !== null) {
|
if (preloaded === true && window.nextSound !== null) {
|
||||||
this.currentSound = this.nextSound;
|
window.currentSound = window.nextSound;
|
||||||
this.nextSound = null;
|
window.nextSound = null;
|
||||||
this.currentSound.play();
|
window.currentSound.play();
|
||||||
this.playing = true;
|
this.playing = true;
|
||||||
} else {
|
} else {
|
||||||
// otherwise, load the song at idx and play it
|
// otherwise, load the song at idx and play it
|
||||||
@ -143,7 +153,7 @@ templ MusicPlayer() {
|
|||||||
html5: true,
|
html5: true,
|
||||||
volume: this.volume,
|
volume: this.volume,
|
||||||
});
|
});
|
||||||
this.currentSound = sound;
|
window.currentSound = sound;
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
sound.play();
|
sound.play();
|
||||||
sound.once("load", () => {
|
sound.once("load", () => {
|
||||||
@ -153,7 +163,7 @@ templ MusicPlayer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set-up preloading for the next song
|
// set-up preloading for the next song
|
||||||
const sound = this.currentSound;
|
const sound = window.currentSound;
|
||||||
sound.once("play", () => {
|
sound.once("play", () => {
|
||||||
const length = sound.duration();
|
const length = sound.duration();
|
||||||
const targetLength = length - 5;
|
const targetLength = length - 5;
|
||||||
@ -172,14 +182,14 @@ templ MusicPlayer() {
|
|||||||
this.playing = false;
|
this.playing = false;
|
||||||
this.next();
|
this.next();
|
||||||
});
|
});
|
||||||
this.currentSound = sound;
|
window.currentSound = sound;
|
||||||
},
|
},
|
||||||
|
|
||||||
// checks the duration of the playing song and:
|
// checks the duration of the playing song and:
|
||||||
// - updates the song progress (0-100%)
|
// - updates the song progress (0-100%)
|
||||||
// - begins preloading
|
// - begins preloading
|
||||||
checkDuration() {
|
checkDuration() {
|
||||||
const sound = this.currentSound;
|
const sound = window.currentSound;
|
||||||
if (this.playing) {
|
if (this.playing) {
|
||||||
const length = sound.duration();
|
const length = sound.duration();
|
||||||
if (length <= 0) return;
|
if (length <= 0) return;
|
||||||
@ -187,7 +197,7 @@ templ MusicPlayer() {
|
|||||||
const position = sound.seek();
|
const position = sound.seek();
|
||||||
|
|
||||||
// preload 5s before the song ends
|
// preload 5s before the song ends
|
||||||
if (position >= length - 5 && this.nextSound === null) {
|
if (position >= length - 5 && window.nextSound === null) {
|
||||||
this.preload();
|
this.preload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,10 +209,10 @@ templ MusicPlayer() {
|
|||||||
togglePlayPause() {
|
togglePlayPause() {
|
||||||
if (this.playing === true) {
|
if (this.playing === true) {
|
||||||
this.playing = false;
|
this.playing = false;
|
||||||
this.currentSound?.pause();
|
window.currentSound?.pause();
|
||||||
} else {
|
} else {
|
||||||
this.playing = true;
|
this.playing = true;
|
||||||
this.currentSound?.play();
|
window.currentSound?.play();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
next() {
|
next() {
|
||||||
@ -236,9 +246,10 @@ templ MusicPlayer() {
|
|||||||
nextSound.seek(0);
|
nextSound.seek(0);
|
||||||
nextSound.volume(this.volume);
|
nextSound.volume(this.volume);
|
||||||
});
|
});
|
||||||
this.nextSound = nextSound;
|
window.nextSound = nextSound;
|
||||||
}
|
}
|
||||||
}));
|
}
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
function wait(ms) {
|
function wait(ms) {
|
||||||
|
Loading…
Reference in New Issue
Block a user