From d29f37e5d4c881cb2244e5e3f0c760a79da69fbb Mon Sep 17 00:00:00 2001 From: geoffrey45 Date: Wed, 30 Mar 2022 14:53:34 +0300 Subject: [PATCH] [client] create a queue store --- src/stores/queue.ts | 220 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 src/stores/queue.ts diff --git a/src/stores/queue.ts b/src/stores/queue.ts new file mode 100644 index 00000000..3d56fcd2 --- /dev/null +++ b/src/stores/queue.ts @@ -0,0 +1,220 @@ +import { defineStore } from "pinia"; +import state from "../composables/state"; +import { Track } from "../interfaces"; +import notif from "../composables/mediaNotification"; + +enum FromOptions { + playlist = "Playlist", + folder = "Folder", + album = "Album", + search = "Search", +} + +interface fromFolder { + type: FromOptions.folder; + path: string; +} + +interface fromAlbum { + type: FromOptions.album; + name: string; + albumartist: string; +} + +interface fromPlaylist { + type: FromOptions.playlist; + name: string; + playlistid: string; +} + +function addQToLocalStorage( + from: fromFolder | fromAlbum | fromPlaylist, + tracks: Track[] +) { + localStorage.setItem( + "queue", + JSON.stringify({ + from: from, + tracks: tracks, + }) + ); +} + +function addCurrentToLocalStorage(track: Track) { + localStorage.setItem("current", JSON.stringify(track)); +} + +function readCurrentFromLocalStorage(): Track { + const current = localStorage.getItem("current"); + if (current) { + return JSON.parse(current); + } + return defaultTrack; +} + +const defaultTrack = { + title: "Nothing played yet", + artists: ["Alice"], + trackid: "", + image: "", +}; + +export default defineStore("Queue", { + state: () => ({ + progressElem: HTMLElement, + audio: new Audio(), + current: {}, + playing: false, + current_time: 0, + next: {}, + prev: {}, + from: {} || {} || {}, + tracks: [], + }), + actions: { + play(track: Track) { + const uri = state.settings.uri + "/file/" + track.trackid; + const elem = document.getElementById("progress"); + + new Promise((resolve, reject) => { + this.audio.src = uri; + this.audio.oncanplaythrough = resolve; + this.audio.onerror = reject; + }) + .then(() => { + this.updateCurrent(track); + this.audio.play().then(() => { + this.playing = true; + notif(track, this.playPause, this.playNext, this.playPrev); + + this.audio.ontimeupdate = () => { + this.current_time = + (this.audio.currentTime / this.audio.duration) * 100; + elem.style.backgroundSize = `${this.current_time}% 100%`; + }; + + this.audio.onended = () => { + this.playNext(); + }; + }); + }) + .catch((err) => { + console.error(err); + }); + }, + playPause() { + if (this.audio.src === "") { + this.play(this.current); + } else if (this.audio.paused) { + this.audio.play(); + } else { + this.audio.pause(); + this.playing = false; + } + }, + playNext() { + this.play(this.next); + }, + playPrev() { + this.play(this.prev); + }, + seek(pos: number) { + try { + const a = (pos / 100) * this.audio.duration; + this.audio.currentTime = a; + } catch (error) { + if (error instanceof TypeError) { + console.error("Seek error: no audio"); + } + } + }, + readQueueFromLocalStorage() { + const queue = localStorage.getItem("queue"); + if (queue) { + const parsed = JSON.parse(queue); + this.from = parsed.from; + this.tracks = parsed.tracks; + } + + this.updateCurrent(readCurrentFromLocalStorage()); + }, + updateCurrent(track: Track) { + this.current = track; + + this.updateNext(this.current); + this.updatePrev(this.current); + + addCurrentToLocalStorage(track); + }, + updateNext(track: Track) { + const index = this.tracks.findIndex( + (t: Track) => t.trackid == track.trackid + ); + + if (index == this.tracks.length - 1) { + this.next = this.tracks[0]; + } else if (index == 0) { + this.next = this.tracks[1]; + } else { + this.next = this.tracks[index + 1]; + } + }, + updatePrev(track: Track) { + const index = this.tracks.findIndex( + (t: Track) => t.trackid === track.trackid + ); + + if (index === 0) { + this.prev = this.tracks[this.tracks.length - 1]; + } else if (index === this.tracks.length - 1) { + this.prev = this.tracks[index - 1]; + } else { + this.prev = this.tracks[index - 1]; + } + }, + setNewQueue(current: Track, tracklist: Track[]) { + this.play(current); + + if (this.tracks !== tracklist) { + this.tracks = tracklist; + addQToLocalStorage(this.from, this.tracks); + } + }, + playFromFolder(fpath: string, tracks: Track[], current: Track) { + this.from = { + type: FromOptions.folder, + path: fpath, + }; + + this.setNewQueue(current, tracks); + }, + playFromAlbum( + aname: string, + albumartist: string, + tracks: Track[], + current: Track + ) { + this.from = { + type: FromOptions.album, + name: aname, + albumartist: albumartist, + }; + + this.setNewQueue(current, tracks); + }, + playFromPlaylist( + pname: string, + pid: string, + tracks: Track[], + current: Track + ) { + this.from = { + type: FromOptions.playlist, + name: pname, + playlistid: pid, + }; + + this.setNewQueue(current, tracks); + }, + }, +});