mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-07-28 13:41:42 +00:00
fix removing tracks from queue
This commit is contained in:
parent
bb66ba70b3
commit
a496d68439
@ -3,7 +3,6 @@
|
|||||||
<div class="centered">
|
<div class="centered">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<div class="with-icons rounded-sm border">
|
<div class="with-icons rounded-sm border">
|
||||||
<!-- <button><PlusSvg /></button> -->
|
|
||||||
<RouterLink
|
<RouterLink
|
||||||
title="go to album"
|
title="go to album"
|
||||||
:to="{
|
:to="{
|
||||||
@ -26,7 +25,7 @@
|
|||||||
<div class="with-title">
|
<div class="with-title">
|
||||||
<div class="time time-current">
|
<div class="time time-current">
|
||||||
<span>
|
<span>
|
||||||
{{ formatSeconds(queue.duration?.current) }}
|
{{ formatSeconds(queue.duration.current || 0) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
@ -58,28 +57,26 @@
|
|||||||
<HotKeys />
|
<HotKeys />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class=""></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { paths } from "@/config";
|
import { paths } from "@/config";
|
||||||
import useQStore from "@/stores/queue";
|
|
||||||
import { formatSeconds } from "@/utils";
|
import { formatSeconds } from "@/utils";
|
||||||
|
|
||||||
import { Routes } from "@/composables/enums";
|
import { Routes } from "@/composables/enums";
|
||||||
import useSettingsStore from "@/stores/settings";
|
|
||||||
|
|
||||||
|
|
||||||
|
import useQStore from "@/stores/queue";
|
||||||
|
import ArtistName from "@/components/shared/ArtistName.vue";
|
||||||
import HotKeys from "@/components/LeftSidebar/NP/HotKeys.vue";
|
import HotKeys from "@/components/LeftSidebar/NP/HotKeys.vue";
|
||||||
import Progress from "@/components/LeftSidebar/NP/Progress.vue";
|
import Progress from "@/components/LeftSidebar/NP/Progress.vue";
|
||||||
import ArtistName from "@/components/shared/ArtistName.vue";
|
|
||||||
|
|
||||||
import HeartSvg from "@/assets/icons/heart.svg";
|
import HeartSvg from "@/assets/icons/heart.svg";
|
||||||
// import PlusSvg from "@/assets/icons/plus.svg";
|
// import PlusSvg from "@/assets/icons/plus.svg";
|
||||||
|
|
||||||
const queue = useQStore();
|
const queue = useQStore();
|
||||||
const settings = useSettingsStore();
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import useQStore from "../../../stores/queue";
|
import useQStore from "@/stores/queue";
|
||||||
|
|
||||||
const q = useQStore();
|
const q = useQStore();
|
||||||
|
|
||||||
|
@ -13,10 +13,12 @@
|
|||||||
key-field="id"
|
key-field="id"
|
||||||
v-slot="{ item, index }"
|
v-slot="{ item, index }"
|
||||||
>
|
>
|
||||||
|
|
||||||
<TrackItem
|
<TrackItem
|
||||||
|
:index="index"
|
||||||
:track="item.track"
|
:track="item.track"
|
||||||
:isCurrentPlaying="index === queue.currentindex && queue.playing"
|
|
||||||
:isCurrent="index === queue.currentindex"
|
:isCurrent="index === queue.currentindex"
|
||||||
|
:isCurrentPlaying="index === queue.currentindex && queue.playing"
|
||||||
:isQueueTrack="true"
|
:isQueueTrack="true"
|
||||||
@playThis="playFromQueue(index)"
|
@playThis="playFromQueue(index)"
|
||||||
/>
|
/>
|
||||||
|
@ -11,10 +11,7 @@
|
|||||||
@contextmenu.prevent="showMenu"
|
@contextmenu.prevent="showMenu"
|
||||||
>
|
>
|
||||||
<div class="album-art">
|
<div class="album-art">
|
||||||
<img
|
<img :src="paths.images.thumb.small + track.image" class="rounded-sm" />
|
||||||
:src="paths.images.thumb.small + track.image"
|
|
||||||
class="rounded-sm"
|
|
||||||
/>
|
|
||||||
<div
|
<div
|
||||||
class="now-playing-track-indicator image"
|
class="now-playing-track-indicator image"
|
||||||
v-if="isCurrent"
|
v-if="isCurrent"
|
||||||
@ -39,7 +36,9 @@
|
|||||||
@click.stop="queue.removeFromQueue(index)"
|
@click.stop="queue.removeFromQueue(index)"
|
||||||
v-if="isQueueTrack"
|
v-if="isQueueTrack"
|
||||||
>
|
>
|
||||||
<DelSvg />
|
<div title="remove from queue" >
|
||||||
|
<DelSvg/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -47,7 +46,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
|
||||||
import DelSvg from "@/assets/icons/delete.svg";
|
import DelSvg from "@/assets/icons/plus.svg";
|
||||||
import { showTrackContextMenu as showContext } from "@/composables/context";
|
import { showTrackContextMenu as showContext } from "@/composables/context";
|
||||||
import { paths } from "@/config";
|
import { paths } from "@/config";
|
||||||
import { Track } from "@/interfaces";
|
import { Track } from "@/interfaces";
|
||||||
@ -103,7 +102,7 @@ const playThis = (track: Track) => {
|
|||||||
.remove-track {
|
.remove-track {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: all 0.25s ease;
|
transition: all 0.25s ease;
|
||||||
transform: scale(0.75) translateY(1rem);
|
transform: scale(0.75) translateY(1rem) rotate(45deg);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
@ -113,7 +112,7 @@ const playThis = (track: Track) => {
|
|||||||
&:hover {
|
&:hover {
|
||||||
.remove-track {
|
.remove-track {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
transform: scale(1) translateY(0);
|
transform: scale(1) translateY(0) rotate(45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
background-color: $gray5;
|
background-color: $gray5;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { ref } from "@vue/reactivity";
|
||||||
import { paths } from "@/config";
|
import { paths } from "@/config";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { Ref } from "vue";
|
import { Ref } from "vue";
|
||||||
@ -11,7 +12,7 @@ import {
|
|||||||
fromFolder,
|
fromFolder,
|
||||||
fromPlaylist,
|
fromPlaylist,
|
||||||
fromSearch,
|
fromSearch,
|
||||||
Track
|
Track,
|
||||||
} from "../interfaces";
|
} from "../interfaces";
|
||||||
|
|
||||||
function shuffle(tracks: Track[]) {
|
function shuffle(tracks: Track[]) {
|
||||||
@ -26,6 +27,7 @@ function shuffle(tracks: Track[]) {
|
|||||||
type From = fromFolder | fromAlbum | fromPlaylist | fromSearch;
|
type From = fromFolder | fromAlbum | fromPlaylist | fromSearch;
|
||||||
|
|
||||||
let audio = new Audio();
|
let audio = new Audio();
|
||||||
|
audio.autoplay = false;
|
||||||
|
|
||||||
export default defineStore("Queue", {
|
export default defineStore("Queue", {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@ -34,7 +36,6 @@ export default defineStore("Queue", {
|
|||||||
full: 0,
|
full: 0,
|
||||||
},
|
},
|
||||||
currentindex: 0,
|
currentindex: 0,
|
||||||
currentid: <string | null>"",
|
|
||||||
playing: false,
|
playing: false,
|
||||||
from: {} as From,
|
from: {} as From,
|
||||||
tracklist: [] as Track[],
|
tracklist: [] as Track[],
|
||||||
@ -51,13 +52,12 @@ export default defineStore("Queue", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const track = this.tracklist[index];
|
const track = this.tracklist[index];
|
||||||
this.currentid = track.trackid;
|
const uri = `${paths.api.files}/${track.trackid}-${track.hash}`;
|
||||||
const uri = `${paths.api.files}/${track.hash}`;
|
|
||||||
|
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
audio.autoplay = true;
|
audio.autoplay = true;
|
||||||
audio.src = uri;
|
audio.src = uri;
|
||||||
audio.oncanplaythrough = resolve;
|
audio.oncanplay = resolve;
|
||||||
audio.onerror = reject;
|
audio.onerror = reject;
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -81,7 +81,6 @@ export default defineStore("Queue", {
|
|||||||
"Can't play: " + track.title,
|
"Can't play: " + track.title,
|
||||||
NotifType.Error
|
NotifType.Error
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this.currentindex !== this.tracklist.length - 1) {
|
if (this.currentindex !== this.tracklist.length - 1) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!this.playing) return;
|
if (!this.playing) return;
|
||||||
@ -90,22 +89,31 @@ export default defineStore("Queue", {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
stop() {
|
||||||
|
this.playing = false;
|
||||||
|
audio.src = "";
|
||||||
|
// audio.pause();
|
||||||
|
},
|
||||||
playPause() {
|
playPause() {
|
||||||
if (audio.src === "") {
|
if (audio.src === "") {
|
||||||
this.play(this.currentindex);
|
this.play(this.currentindex);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio.paused) {
|
if (audio.paused) {
|
||||||
|
audio.currentTime === 0 ? this.play(this.currentindex) : null;
|
||||||
audio.play();
|
audio.play();
|
||||||
|
this.playing = true;
|
||||||
} else {
|
} else {
|
||||||
audio.pause();
|
audio.pause();
|
||||||
|
this.playing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.playing) {
|
// if (this.playing) {
|
||||||
this.playing = false;
|
// this.playing = false;
|
||||||
} else {
|
// } else {
|
||||||
this.playing = true;
|
// this.playing = true;
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
playNext() {
|
playNext() {
|
||||||
this.play(this.nextindex);
|
this.play(this.nextindex);
|
||||||
@ -208,7 +216,6 @@ export default defineStore("Queue", {
|
|||||||
},
|
},
|
||||||
clearQueue() {
|
clearQueue() {
|
||||||
this.tracklist = [] as Track[];
|
this.tracklist = [] as Track[];
|
||||||
this.currentid = "";
|
|
||||||
this.currentindex = 0;
|
this.currentindex = 0;
|
||||||
this.from = <From>{};
|
this.from = <From>{};
|
||||||
},
|
},
|
||||||
@ -220,7 +227,7 @@ export default defineStore("Queue", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const current = this.currenttrack;
|
const current = this.currenttrack;
|
||||||
const current_hash = current.hash;
|
const current_hash = current?.hash;
|
||||||
|
|
||||||
this.tracklist = shuffle(this.tracklist);
|
this.tracklist = shuffle(this.tracklist);
|
||||||
// find current track after shuffle
|
// find current track after shuffle
|
||||||
@ -233,7 +240,7 @@ export default defineStore("Queue", {
|
|||||||
// remove current track from queue
|
// remove current track from queue
|
||||||
this.tracklist.splice(newindex, 1);
|
this.tracklist.splice(newindex, 1);
|
||||||
// insert current track at beginning of queue
|
// insert current track at beginning of queue
|
||||||
this.tracklist.unshift(current);
|
this.tracklist.unshift(current as Track);
|
||||||
this.currentindex = 0;
|
this.currentindex = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -242,7 +249,23 @@ export default defineStore("Queue", {
|
|||||||
this.play(this.currentindex);
|
this.play(this.currentindex);
|
||||||
},
|
},
|
||||||
removeFromQueue(index: number = 0) {
|
removeFromQueue(index: number = 0) {
|
||||||
this.tracklist.splice(index, 1);
|
if (index === this.currentindex) {
|
||||||
|
const is_last = index === this.tracklist.length - 1;
|
||||||
|
const was_playing = this.playing;
|
||||||
|
|
||||||
|
audio.src = "";
|
||||||
|
this.tracklist.splice(index, 1);
|
||||||
|
|
||||||
|
if (is_last) {
|
||||||
|
this.currentindex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (was_playing) {
|
||||||
|
this.playPause();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.tracklist.splice(index, 1);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setScrollFunction(
|
setScrollFunction(
|
||||||
cb: (index: number) => void,
|
cb: (index: number) => void,
|
||||||
@ -253,23 +276,26 @@ export default defineStore("Queue", {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
next(): Track {
|
next(): Track | undefined {
|
||||||
if (this.currentindex == this.tracklist.length - 1) {
|
if (this.currentindex == this.tracklist.length - 1) {
|
||||||
return this.tracklist[0];
|
return this.tracklist[0];
|
||||||
} else {
|
} else {
|
||||||
return this.tracklist[this.currentindex + 1];
|
return this.tracklist[this.currentindex + 1];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
prev(): Track {
|
prev(): Track | undefined {
|
||||||
if (this.currentindex === 0) {
|
if (this.currentindex === 0) {
|
||||||
return this.tracklist[this.tracklist.length - 1];
|
return this.tracklist[this.tracklist.length - 1];
|
||||||
} else {
|
} else {
|
||||||
return this.tracklist[this.currentindex - 1];
|
return this.tracklist[this.currentindex - 1];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
currenttrack(): Track {
|
currenttrack(): Track | undefined {
|
||||||
return this.tracklist[this.currentindex];
|
return this.tracklist[this.currentindex];
|
||||||
},
|
},
|
||||||
|
currentid(): string {
|
||||||
|
return this.currenttrack?.trackid || "";
|
||||||
|
},
|
||||||
previndex(): number {
|
previndex(): number {
|
||||||
return this.currentindex === 0
|
return this.currentindex === 0
|
||||||
? this.tracklist.length - 1
|
? this.tracklist.length - 1
|
||||||
|
@ -5,8 +5,8 @@ export default function createTrackProps(track: Track) {
|
|||||||
return {
|
return {
|
||||||
track,
|
track,
|
||||||
index: track.index + 1,
|
index: track.index + 1,
|
||||||
isCurrent: queue().currenttrack?.hash === track.hash,
|
isCurrent: queue().currentid === track.trackid,
|
||||||
isCurrentPlaying:
|
isCurrentPlaying:
|
||||||
queue().currenttrack?.hash === track.hash && queue().playing,
|
queue().currentid === track.trackid && queue().playing,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -34,13 +34,13 @@ import { computed } from "@vue/reactivity";
|
|||||||
import { onBeforeRouteLeave, onBeforeRouteUpdate } from "vue-router";
|
import { onBeforeRouteLeave, onBeforeRouteUpdate } from "vue-router";
|
||||||
|
|
||||||
import { Track } from "@/interfaces";
|
import { Track } from "@/interfaces";
|
||||||
import useQueueStore from "@/stores/queue";
|
import { isMedium, isSmall } from "@/stores/content-width";
|
||||||
import useLoaderStore from "@/stores/loader";
|
import useLoaderStore from "@/stores/loader";
|
||||||
import useFolderStore from "@/stores/pages/folder";
|
import useFolderStore from "@/stores/pages/folder";
|
||||||
import { isSmall, isMedium } from "@/stores/content-width";
|
import useQueueStore from "@/stores/queue";
|
||||||
|
|
||||||
import SongItem from "@/components/shared/SongItem.vue";
|
|
||||||
import FolderList from "@/components/FolderView/FolderList.vue";
|
import FolderList from "@/components/FolderView/FolderList.vue";
|
||||||
|
import SongItem from "@/components/shared/SongItem.vue";
|
||||||
|
|
||||||
const loader = useLoaderStore();
|
const loader = useLoaderStore();
|
||||||
const folder = useFolderStore();
|
const folder = useFolderStore();
|
||||||
@ -62,9 +62,9 @@ class songItem {
|
|||||||
this.props = {
|
this.props = {
|
||||||
track,
|
track,
|
||||||
index: track.index + 1,
|
index: track.index + 1,
|
||||||
isCurrent: queue.currenttrack?.hash === track.hash,
|
isCurrent: queue.currentid === track.trackid,
|
||||||
isCurrentPlaying:
|
isCurrentPlaying:
|
||||||
queue.currenttrack?.hash === track.hash && queue.playing,
|
queue.currentid === track.trackid && queue.playing,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ const queue = useQueueStore();
|
|||||||
const playlist = usePlaylistStore();
|
const playlist = usePlaylistStore();
|
||||||
|
|
||||||
interface ScrollerItem {
|
interface ScrollerItem {
|
||||||
id: string;
|
id: string | number;
|
||||||
component: typeof Header | typeof SongItem;
|
component: typeof Header | typeof SongItem;
|
||||||
props: Record<string, unknown>;
|
props: Record<string, unknown>;
|
||||||
size: number;
|
size: number;
|
||||||
@ -56,7 +56,7 @@ const scrollerItems = computed(() => {
|
|||||||
header,
|
header,
|
||||||
...playlist.tracks.map((track) => {
|
...playlist.tracks.map((track) => {
|
||||||
return {
|
return {
|
||||||
id: track.trackid,
|
id: Math.random(),
|
||||||
component: SongItem,
|
component: SongItem,
|
||||||
props: {
|
props: {
|
||||||
track: track,
|
track: track,
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
<SongItem
|
<SongItem
|
||||||
:track="item.track"
|
:track="item.track"
|
||||||
:index="index + 1"
|
:index="index + 1"
|
||||||
:isCurrent="queue.currenttrack?.hash === item.track.hash"
|
:isCurrent="queue.currentid === item.trackid"
|
||||||
:isCurrentPlaying="
|
:isCurrentPlaying="
|
||||||
queue.currenttrack?.hash === item.track.hash && queue.playing
|
queue.currentid === item.trackid && queue.playing
|
||||||
"
|
"
|
||||||
@playThis="playFromQueue(index)"
|
@playThis="playFromQueue(index)"
|
||||||
/>
|
/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user