mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-07-28 21:51:41 +00:00
265 lines
6.4 KiB
TypeScript
265 lines
6.4 KiB
TypeScript
import { defineStore } from "pinia";
|
|
import state from "../composables/state";
|
|
import { NotifType, useNotifStore } from "./notification";
|
|
|
|
import { FromOptions } from "../composables/enums";
|
|
import notif from "../composables/mediaNotification";
|
|
import {
|
|
fromAlbum,
|
|
fromFolder,
|
|
fromPlaylist,
|
|
fromSearch,
|
|
Track,
|
|
} from "../interfaces";
|
|
|
|
function writeQueue(
|
|
from: fromFolder | fromAlbum | fromPlaylist,
|
|
tracks: Track[]
|
|
) {
|
|
localStorage.setItem(
|
|
"queue",
|
|
JSON.stringify({
|
|
from: from,
|
|
tracks: tracks,
|
|
})
|
|
);
|
|
}
|
|
|
|
function writeCurrent(index: number) {
|
|
localStorage.setItem("current", JSON.stringify(index));
|
|
}
|
|
|
|
function readCurrent(): number {
|
|
const current = localStorage.getItem("current");
|
|
|
|
if (current) {
|
|
return JSON.parse(current);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const defaultTrack = <Track>{
|
|
title: "Nothing played yet",
|
|
albumhash: " ",
|
|
artists: ["Alice"],
|
|
trackid: "",
|
|
image: "meh",
|
|
};
|
|
|
|
type From = fromFolder | fromAlbum | fromPlaylist | fromSearch;
|
|
|
|
export default defineStore("Queue", {
|
|
state: () => ({
|
|
progressElem: HTMLElement,
|
|
audio: new Audio(),
|
|
duration: {
|
|
current: 0,
|
|
full: 0,
|
|
},
|
|
indexes: {
|
|
current: 0,
|
|
next: 0,
|
|
previous: 0,
|
|
},
|
|
current: 0,
|
|
next: 0,
|
|
prev: 0,
|
|
currentid: "",
|
|
playing: false,
|
|
from: {} as From,
|
|
currenttrack: {} as Track,
|
|
tracklist: [defaultTrack] as Track[],
|
|
}),
|
|
actions: {
|
|
play(index: number = 0) {
|
|
this.current = index;
|
|
const track = this.tracklist[index];
|
|
this.currentid = track.trackid;
|
|
const uri = state.settings.uri + "/file/" + track.trackid;
|
|
const elem = document.getElementById("progress");
|
|
this.updateCurrent(index);
|
|
|
|
new Promise((resolve, reject) => {
|
|
this.audio.autoplay = true;
|
|
this.audio.src = uri;
|
|
this.audio.oncanplaythrough = resolve;
|
|
this.audio.onerror = reject;
|
|
})
|
|
.then(() => {
|
|
this.duration.full = this.audio.duration;
|
|
this.audio.play().then(() => {
|
|
this.playing = true;
|
|
notif(track, this.playPause, this.playNext, this.playPrev);
|
|
|
|
this.audio.ontimeupdate = () => {
|
|
this.duration.current = this.audio.currentTime;
|
|
const bg_size =
|
|
(this.audio.currentTime / this.audio.duration) * 100;
|
|
elem.style.backgroundSize = `${bg_size}% 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();
|
|
this.playing = true;
|
|
} else {
|
|
this.audio.pause();
|
|
this.playing = false;
|
|
}
|
|
},
|
|
playNext() {
|
|
this.play(this.next);
|
|
},
|
|
playPrev() {
|
|
this.play(this.prev);
|
|
},
|
|
seek(pos: number) {
|
|
try {
|
|
this.audio.currentTime = pos;
|
|
} catch (error) {
|
|
if (error instanceof TypeError) {
|
|
console.error("Seek error: no audio");
|
|
}
|
|
}
|
|
},
|
|
readQueue() {
|
|
const queue = localStorage.getItem("queue");
|
|
|
|
if (queue) {
|
|
const parsed = JSON.parse(queue);
|
|
this.from = parsed.from;
|
|
this.tracklist = parsed.tracks;
|
|
}
|
|
|
|
this.updateCurrent(readCurrent());
|
|
},
|
|
updateCurrent(index: number) {
|
|
this.setCurrent(index);
|
|
this.updateNext(index);
|
|
this.updatePrev(index);
|
|
|
|
writeCurrent(index);
|
|
},
|
|
updateNext(index: number) {
|
|
if (index == this.tracklist.length - 1) {
|
|
this.next = 0;
|
|
return;
|
|
}
|
|
|
|
this.next = index + 1;
|
|
},
|
|
updatePrev(index: number) {
|
|
if (index === 0) {
|
|
this.prev = this.tracklist.length - 1;
|
|
return;
|
|
}
|
|
|
|
this.prev = index - 1;
|
|
},
|
|
setCurrent(index: number) {
|
|
const track = this.tracklist[index];
|
|
|
|
this.currenttrack = track;
|
|
this.current = index;
|
|
this.currentid = track.trackid;
|
|
this.duration.full = track.length;
|
|
},
|
|
setNewQueue(tracklist: Track[]) {
|
|
if (this.tracklist !== tracklist) {
|
|
this.tracklist = [];
|
|
this.tracklist.push(...tracklist);
|
|
writeQueue(this.from, this.tracklist);
|
|
}
|
|
},
|
|
playFromFolder(fpath: string, tracks: Track[]) {
|
|
this.from = <fromFolder>{
|
|
type: FromOptions.folder,
|
|
path: fpath,
|
|
name: fpath.split("/").splice(-1).join(""),
|
|
};
|
|
this.setNewQueue(tracks);
|
|
},
|
|
playFromAlbum(
|
|
aname: string,
|
|
albumartist: string,
|
|
albumhash: string,
|
|
tracks: Track[]
|
|
) {
|
|
this.from = <fromAlbum>{
|
|
type: FromOptions.album,
|
|
name: aname,
|
|
hash: albumhash,
|
|
albumartist: albumartist,
|
|
};
|
|
|
|
this.setNewQueue(tracks);
|
|
},
|
|
playFromPlaylist(pname: string, pid: string, tracks: Track[]) {
|
|
this.from = <fromPlaylist>{
|
|
type: FromOptions.playlist,
|
|
name: pname,
|
|
playlistid: pid,
|
|
};
|
|
|
|
this.setNewQueue(tracks);
|
|
},
|
|
playFromSearch(query: string, tracks: Track[]) {
|
|
this.from = <fromSearch>{
|
|
type: FromOptions.search,
|
|
query: query,
|
|
};
|
|
|
|
this.setNewQueue(tracks);
|
|
},
|
|
addTrackToQueue(track: Track) {
|
|
this.tracklist.push(track);
|
|
writeQueue(this.from, this.tracklist);
|
|
this.updateNext(this.current);
|
|
},
|
|
playTrackNext(track: Track) {
|
|
const Toast = useNotifStore();
|
|
if (this.current == this.tracklist.length - 1) {
|
|
this.tracklist.push(track);
|
|
} else {
|
|
const nextindex = this.current + 1;
|
|
const next: Track = this.tracklist[nextindex];
|
|
|
|
if (next.trackid === track.trackid) {
|
|
Toast.showNotification("Track is already queued", NotifType.Info);
|
|
return;
|
|
}
|
|
}
|
|
|
|
this.tracklist.splice(this.current + 1, 0, track);
|
|
this.updateNext(this.current);
|
|
Toast.showNotification(
|
|
`Added ${track.title} to queue`,
|
|
NotifType.Success
|
|
);
|
|
writeQueue(this.from, this.tracklist);
|
|
},
|
|
clearQueue() {
|
|
this.tracklist = [defaultTrack] as Track[];
|
|
this.current = 0;
|
|
this.currentid = "";
|
|
this.next = 0;
|
|
this.prev = 0;
|
|
this.from = <From>{};
|
|
|
|
writeQueue(this.from, [defaultTrack] as Track[]);
|
|
writeCurrent(0);
|
|
},
|
|
},
|
|
});
|