mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 04:23:01 +00:00
[client] create a queue store
This commit is contained in:
@@ -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 = <Track>{
|
||||
title: "Nothing played yet",
|
||||
artists: ["Alice"],
|
||||
trackid: "",
|
||||
image: "",
|
||||
};
|
||||
|
||||
export default defineStore("Queue", {
|
||||
state: () => ({
|
||||
progressElem: HTMLElement,
|
||||
audio: new Audio(),
|
||||
current: <Track>{},
|
||||
playing: false,
|
||||
current_time: 0,
|
||||
next: <Track>{},
|
||||
prev: <Track>{},
|
||||
from: <fromFolder>{} || <fromAlbum>{} || <fromPlaylist>{},
|
||||
tracks: <Track[]>[],
|
||||
}),
|
||||
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 = <fromFolder>{
|
||||
type: FromOptions.folder,
|
||||
path: fpath,
|
||||
};
|
||||
|
||||
this.setNewQueue(current, tracks);
|
||||
},
|
||||
playFromAlbum(
|
||||
aname: string,
|
||||
albumartist: string,
|
||||
tracks: Track[],
|
||||
current: Track
|
||||
) {
|
||||
this.from = <fromAlbum>{
|
||||
type: FromOptions.album,
|
||||
name: aname,
|
||||
albumartist: albumartist,
|
||||
};
|
||||
|
||||
this.setNewQueue(current, tracks);
|
||||
},
|
||||
playFromPlaylist(
|
||||
pname: string,
|
||||
pid: string,
|
||||
tracks: Track[],
|
||||
current: Track
|
||||
) {
|
||||
this.from = <fromPlaylist>{
|
||||
type: FromOptions.playlist,
|
||||
name: pname,
|
||||
playlistid: pid,
|
||||
};
|
||||
|
||||
this.setNewQueue(current, tracks);
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user