refactor queu store to use play track using index

- this allows to have duplicate tracks in queue safely
- store indexes in localstorage instead of track objects.
This commit is contained in:
geoffrey45
2022-07-02 18:13:54 +03:00
committed by Mungai Geoffrey
parent f0d3c1c663
commit c9830842ed
10 changed files with 62 additions and 89 deletions
+8 -4
View File
@@ -9,7 +9,7 @@
:index="track.index" :index="track.index"
@updateQueue="updateQueue" @updateQueue="updateQueue"
:isPlaying="queue.playing" :isPlaying="queue.playing"
:isCurrent="queue.current.trackid == track.trackid" :isCurrent="queue.currentid == track.trackid"
/> />
</div> </div>
</div> </div>
@@ -47,18 +47,22 @@ let route = useRoute().name;
* @param track Track object * @param track Track object
*/ */
function updateQueue(track: Track) { function updateQueue(track: Track) {
const index = props.tracks.findIndex(
(t: Track) => t.trackid === track.trackid
);
switch (route) { switch (route) {
case "FolderView": case "FolderView":
queue.playFromFolder(props.path, props.tracks); queue.playFromFolder(props.path, props.tracks);
queue.play(track); queue.play(index);
break; break;
case "AlbumView": case "AlbumView":
queue.playFromAlbum(track.album, track.albumartist, props.tracks); queue.playFromAlbum(track.album, track.albumartist, props.tracks);
queue.play(track); queue.play(index);
break; break;
case "PlaylistView": case "PlaylistView":
queue.playFromPlaylist(props.pname, props.playlistid, props.tracks); queue.playFromPlaylist(props.pname, props.playlistid, props.tracks);
queue.play(track); queue.play(index);
break; break;
} }
} }
+6 -3
View File
@@ -10,7 +10,7 @@
</div> </div>
<div class="separator no-border"></div> <div class="separator no-border"></div>
<div> <div>
<SongCard :track="queue.current" /> <SongCard :track="queue.tracks[queue.current]" />
<Progress /> <Progress />
<HotKeys /> <HotKeys />
</div> </div>
@@ -39,7 +39,11 @@ const showContextMenu = (e: Event) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
const menus = trackContext(queue.current, useModalStore, useQueueStore); const menus = trackContext(
queue.tracks[queue.current],
useModalStore,
useQueueStore
);
contextStore.showContextMenu(e, menus, ContextSrc.Track); contextStore.showContextMenu(e, menus, ContextSrc.Track);
context_on.value = true; context_on.value = true;
@@ -82,7 +86,6 @@ const showContextMenu = (e: Event) => {
.button { .button {
position: absolute; position: absolute;
background-size: 1.5rem;
top: $small; top: $small;
cursor: pointer; cursor: pointer;
transition: all 200ms; transition: all 200ms;
+1 -1
View File
@@ -1,6 +1,6 @@
<template> <template>
<div class="r-home"> <div class="r-home">
<UpNext :next="queue.next" :playNext="queue.playNext" /> <UpNext :next="queue.tracks[queue.next]" :playNext="queue.playNext" />
<Recommendations /> <Recommendations />
</div> </div>
</template> </template>
+4 -4
View File
@@ -1,7 +1,7 @@
<template> <template>
<div class="up-next"> <div class="up-next">
<div class="r-grid"> <div class="r-grid">
<UpNext :next="queue.next" :playNext="queue.playNext" /> <UpNext :next="queue.tracks[queue.next]" :playNext="queue.playNext" />
<div class="scrollable-r border rounded"> <div class="scrollable-r border rounded">
<div <div
class="inner" class="inner"
@@ -9,11 +9,11 @@
@mouseleave="setMouseOver(false)" @mouseleave="setMouseOver(false)"
> >
<TrackItem <TrackItem
v-for="t in queue.tracks" v-for="(t, index) in queue.tracks"
:key="t.trackid" :key="t.trackid"
:track="t" :track="t"
@playThis="queue.play(t)" @playThis="queue.play(index)"
:isCurrent="t.trackid === queue.current.trackid" :isCurrent="index === queue.current"
:isPlaying="queue.playing" :isPlaying="queue.playing"
/> />
</div> </div>
@@ -2,13 +2,13 @@
<div id="tracks-results" v-if="search.tracks.value"> <div id="tracks-results" v-if="search.tracks.value">
<TransitionGroup name="list"> <TransitionGroup name="list">
<TrackItem <TrackItem
v-for="track in search.tracks.value" v-for="(track, index) in search.tracks.value"
:key="track.trackid" :key="track.trackid"
:track="track" :track="track"
:isPlaying="queue.playing" :isPlaying="queue.playing"
:isCurrent="queue.current.trackid == track.trackid" :isCurrent="queue.currentid == track.trackid"
:isSearchTrack="true" :isSearchTrack="true"
@PlayThis="updateQueue" @PlayThis="updateQueue(index)"
/> />
</TransitionGroup> </TransitionGroup>
<LoadMore v-if="search.tracks.more" @loadMore="loadMore" /> <LoadMore v-if="search.tracks.more" @loadMore="loadMore" />
@@ -30,9 +30,9 @@ function loadMore() {
search.loadTracks(search.loadCounter.tracks); search.loadTracks(search.loadCounter.tracks);
} }
function updateQueue(track: Track) { function updateQueue(index: number) {
queue.playFromSearch(search.query, search.tracks.value); queue.playFromSearch(search.query, search.tracks.value);
queue.play(track); queue.play(index);
} }
</script> </script>
+1 -1
View File
@@ -139,7 +139,7 @@ const context = useContextStore();
.children { .children {
transform: scale(1); transform: scale(1);
transition: transform 0.2s ease-in-out; transition: transform 0.1s ease-in-out;
} }
} }
} }
+2 -2
View File
@@ -74,11 +74,11 @@ const showContextMenu = (e: Event) => {
}; };
const emit = defineEmits<{ const emit = defineEmits<{
(e: "PlayThis", track: Track): void; (e: "PlayThis"): void;
}>(); }>();
const playThis = (track: Track) => { const playThis = (track: Track) => {
emit("PlayThis", track); emit("PlayThis");
}; };
</script> </script>
-24
View File
@@ -9,29 +9,6 @@ const uris = {
artists: `${base_url}/artists?q=`, artists: `${base_url}/artists?q=`,
}; };
async function search(query: string) {
state.loading.value = true;
const url = base_url + encodeURIComponent(query.trim());
const res = await fetch(url);
if (!res.ok) {
const message = `An error has occured: ${res.status}`;
throw new Error(message);
}
const data = await res.json();
state.loading.value = false;
return {
tracks: data.data[0],
albums: data.data[1],
artists: data.data[2],
};
}
async function searchTracks(query: string) { async function searchTracks(query: string) {
const url = uris.tracks + encodeURIComponent(query.trim()); const url = uris.tracks + encodeURIComponent(query.trim());
@@ -43,7 +20,6 @@ async function searchTracks(query: string) {
} }
const data = await res.json(); const data = await res.json();
console.log(data);
return data; return data;
} }
+3 -3
View File
@@ -25,14 +25,14 @@ export default function play(
const f = store(); const f = store();
useQueue.playFromFolder(f.path, f.tracks); useQueue.playFromFolder(f.path, f.tracks);
useQueue.play(f.tracks[0]); useQueue.play();
break; break;
case playSources.album: case playSources.album:
store = store as typeof album; store = store as typeof album;
const a = store(); const a = store();
useQueue.playFromAlbum(a.info.title, a.info.artist, a.tracks); useQueue.playFromAlbum(a.info.title, a.info.artist, a.tracks);
useQueue.play(store().tracks[0]); useQueue.play();
break; break;
case playSources.playlist: case playSources.playlist:
store = store as typeof playlist; store = store as typeof playlist;
@@ -41,7 +41,7 @@ export default function play(
if (p.tracks.length === 0) return; if (p.tracks.length === 0) return;
useQueue.playFromPlaylist(p.info.name, p.info.playlistid, p.tracks); useQueue.playFromPlaylist(p.info.name, p.info.playlistid, p.tracks);
useQueue.play(store().tracks[0]); useQueue.play();
break; break;
} }
} }
+32 -42
View File
@@ -25,16 +25,17 @@ function writeQueue(
); );
} }
function writeCurrent(track: Track) { function writeCurrent(index: number) {
localStorage.setItem("current", JSON.stringify(track)); localStorage.setItem("current", JSON.stringify(index));
} }
function readCurrent(): Track { function readCurrent(): number {
const current = localStorage.getItem("current"); const current = localStorage.getItem("current");
if (current) { if (current) {
return JSON.parse(current); return JSON.parse(current);
} }
return defaultTrack; return 0;
} }
const defaultTrack = <Track>{ const defaultTrack = <Track>{
@@ -52,18 +53,22 @@ export default defineStore("Queue", {
current_time: 0, current_time: 0,
duration: 0, duration: 0,
}, },
current: <Track>{}, current: 0,
next: <Track>{}, next: 0,
prev: <Track>{}, prev: 0,
currentid: "",
playing: false, playing: false,
from: <fromFolder>{} || <fromAlbum>{} || <fromPlaylist>{}, from: <fromFolder>{} || <fromAlbum>{} || <fromPlaylist>{},
tracks: <Track[]>[defaultTrack], tracks: <Track[]>[defaultTrack],
}), }),
actions: { actions: {
play(track: Track) { play(index: number = 0) {
const track = this.tracks[index];
this.current = index;
this.currentid = track.trackid;
const uri = state.settings.uri + "/file/" + track.trackid; const uri = state.settings.uri + "/file/" + track.trackid;
const elem = document.getElementById("progress"); const elem = document.getElementById("progress");
this.updateCurrent(track); this.updateCurrent(index);
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
this.audio.autoplay = true; this.audio.autoplay = true;
@@ -130,39 +135,27 @@ export default defineStore("Queue", {
this.updateCurrent(readCurrent()); this.updateCurrent(readCurrent());
}, },
updateCurrent(track: Track) { updateCurrent(index: number) {
this.current = track; this.updateNext(index);
this.updatePrev(index);
this.updateNext(this.current); writeCurrent(index);
this.updatePrev(this.current);
writeCurrent(track);
}, },
updateNext(track: Track) { updateNext(index: number) {
const index = this.tracks.findIndex(
(t: Track) => t.trackid == track.trackid
);
if (index == this.tracks.length - 1) { if (index == this.tracks.length - 1) {
this.next = this.tracks[0]; this.next = 0;
} else if (index == 0) { return;
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
);
this.next = index + 1;
},
updatePrev(index: number) {
if (index === 0) { if (index === 0) {
this.prev = this.tracks[this.tracks.length - 1]; this.prev = this.tracks.length - 1;
} else if (index === this.tracks.length - 1) { return;
this.prev = this.tracks[index - 1];
} else {
this.prev = this.tracks[index - 1];
} }
this.prev = index - 1;
}, },
setNewQueue(tracklist: Track[]) { setNewQueue(tracklist: Track[]) {
if (this.tracks !== tracklist) { if (this.tracks !== tracklist) {
@@ -212,14 +205,11 @@ export default defineStore("Queue", {
}, },
playTrackNext(track: Track) { playTrackNext(track: Track) {
const Toast = useNotifStore(); const Toast = useNotifStore();
const currentid = this.tracks.findIndex( if (this.current == this.tracks.length - 1) {
(t: Track) => t.trackid === this.current.trackid
);
if (currentid == this.tracks.length - 1) {
this.tracks.push(track); this.tracks.push(track);
} else { } else {
const next: Track = this.tracks[currentid + 1]; const nextindex = this.current + 1;
const next: Track = this.tracks[nextindex];
if (next.trackid === track.trackid) { if (next.trackid === track.trackid) {
Toast.showNotification("Track is already queued", NotifType.Info); Toast.showNotification("Track is already queued", NotifType.Info);
@@ -227,7 +217,7 @@ export default defineStore("Queue", {
} }
} }
this.tracks.splice(currentid + 1, 0, track); this.tracks.splice(this.current + 1, 0, track);
this.updateNext(this.current); this.updateNext(this.current);
Toast.showNotification( Toast.showNotification(
`Added ${track.title} to queue`, `Added ${track.title} to queue`,