diff --git a/src/assets/icons/add-to-queue.svg b/src/assets/icons/add-to-queue.svg
new file mode 100644
index 0000000..20ca7dd
--- /dev/null
+++ b/src/assets/icons/add-to-queue.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/icons/play-next.svg b/src/assets/icons/play-next.svg
new file mode 100644
index 0000000..99c1387
--- /dev/null
+++ b/src/assets/icons/play-next.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/icons/repeat-one.svg b/src/assets/icons/repeat-one.svg
new file mode 100644
index 0000000..23708f1
--- /dev/null
+++ b/src/assets/icons/repeat-one.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/assets/icons/repeat.svg b/src/assets/icons/repeat.svg
index 94a6be7..6f08054 100644
--- a/src/assets/icons/repeat.svg
+++ b/src/assets/icons/repeat.svg
@@ -1,3 +1,3 @@
diff --git a/src/components/BottomBar.vue b/src/components/BottomBar.vue
index c694c5f..0654130 100644
--- a/src/components/BottomBar.vue
+++ b/src/components/BottomBar.vue
@@ -25,6 +25,21 @@
@handleFav="handleFav"
/>
+
@@ -72,17 +87,22 @@
import { Routes } from "@/router/routes";
import { paths } from "@/config";
import { formatSeconds } from "@/utils";
+import { favType } from "@/composables/enums";
+import favoriteHandler from "@/composables/favoriteHandler";
+
+import useQStore from "@/stores/queue";
+import useSettingsStore from "@/stores/settings";
import HotKeys from "@/components/LeftSidebar/NP/HotKeys.vue";
import Progress from "@/components/LeftSidebar/NP/Progress.vue";
import ArtistName from "@/components/shared/ArtistName.vue";
-import useQStore from "@/stores/queue";
-import HeartSvg from "./shared/HeartSvg.vue"; // import PlusSvg from "@/assets/icons/plus.svg";
-import favoriteHandler from "@/composables/favoriteHandler";
-import { favType } from "@/composables/enums";
+import HeartSvg from "./shared/HeartSvg.vue";
+import RepeatAllSvg from "@/assets/icons/repeat.svg";
+import RepeatOneSvg from "@/assets/icons/repeat-one.svg";
const queue = useQStore();
+const settings = useSettingsStore();
function handleFav() {
favoriteHandler(
@@ -147,6 +167,16 @@ function handleFav() {
padding: 0;
border: none;
}
+
+ button.repeat {
+ svg {
+ transform: scale(0.75);
+ }
+ }
+
+ button.repeat.repeat-disabled {
+ opacity: 0.25;
+ }
}
img {
diff --git a/src/components/Contextmenu/ContextItem.vue b/src/components/Contextmenu/ContextItem.vue
index c213777..b356d20 100644
--- a/src/components/Contextmenu/ContextItem.vue
+++ b/src/components/Contextmenu/ContextItem.vue
@@ -189,10 +189,15 @@ function runChildAction(action: () => void) {
background-image: url("../../assets/icons/plus.svg");
}
- .add_to_queue {
+ .play_next {
background-image: url("../../assets/icons/add_to_queue.svg");
}
+ .add_to_queue {
+ background-image: url("../../assets/icons/add-to-queue.svg");
+ transform: scale(0.8); // reason: icon is not from same source as other
+ }
+
.heart {
background-image: url("../../assets/icons/heart.svg");
}
diff --git a/src/components/RightSideBar/Queue.vue b/src/components/RightSideBar/Queue.vue
index 9a20056..d00df8c 100644
--- a/src/components/RightSideBar/Queue.vue
+++ b/src/components/RightSideBar/Queue.vue
@@ -61,6 +61,7 @@ function scrollToCurrent() {
onMounted(() => {
queue.setScrollFunction(scrollToCurrent, mouseover);
+ queue.focusCurrentInSidebar();
});
onBeforeUnmount(() => {
diff --git a/src/contexts/track_context.ts b/src/contexts/track_context.ts
index 9dea41c..a2287da 100644
--- a/src/contexts/track_context.ts
+++ b/src/contexts/track_context.ts
@@ -92,7 +92,7 @@ export default async (
action: () => {
QueueStore().playTrackNext(track);
},
- icon: "add_to_queue",
+ icon: "play_next",
};
const go_to_folder: Option = {
diff --git a/src/stores/queue.ts b/src/stores/queue.ts
index 3743dd5..645f82c 100644
--- a/src/stores/queue.ts
+++ b/src/stores/queue.ts
@@ -6,6 +6,7 @@ import { NotifType, useNotifStore } from "./notification";
import { favType, FromOptions } from "../composables/enums";
import updateMediaNotif from "../composables/mediaNotification";
import { isFavorite } from "@/composables/fetch/favorite";
+import useSettingsStore from "./settings";
import {
fromAlbum,
@@ -51,13 +52,17 @@ export default defineStore("Queue", {
mousover: [null,
}),
actions: {
+ focusCurrentInSidebar(timeout = 500) {
+ if (!this.mousover) {
+ setTimeout(() => {
+ this.queueScrollFunction(this.currentindex - 1);
+ }, timeout);
+ }
+ },
play(index: number = 0) {
if (this.tracklist.length === 0) return;
this.currentindex = index;
-
- if (!this.mousover) {
- this.queueScrollFunction(this.currentindex - 1);
- }
+ this.focusCurrentInSidebar();
const track = this.tracklist[index];
const uri = `${paths.api.files}/${track.trackhash}`;
@@ -79,7 +84,7 @@ export default defineStore("Queue", {
};
audio.onended = () => {
- this.playNext();
+ this.autoPlayNext();
};
});
})
@@ -92,15 +97,14 @@ export default defineStore("Queue", {
if (this.currentindex !== this.tracklist.length - 1) {
setTimeout(() => {
if (!this.playing) return;
- this.playNext();
+ this.autoPlayNext();
}, 5000);
}
});
},
stop() {
- this.playing = false;
audio.src = "";
- // audio.pause();
+ this.playing = false;
},
playPause() {
if (audio.src === "") {
@@ -116,12 +120,28 @@ export default defineStore("Queue", {
audio.pause();
this.playing = false;
}
+ },
+ autoPlayNext() {
+ const settings = useSettingsStore();
+ const is_last = this.currentindex === this.tracklist.length - 1;
- // if (this.playing) {
- // this.playing = false;
- // } else {
- // this.playing = true;
- // }
+ if (settings.repeat_one) {
+ this.play(this.currentindex);
+ return;
+ }
+
+ if (settings.repeat_all) {
+ this.play(is_last ? 0 : this.currentindex + 1);
+ return;
+ }
+
+ const resetQueue = () => {
+ this.currentindex = 0;
+ this.playing = false;
+ this.focusCurrentInSidebar();
+ };
+
+ !is_last ? this.play(this.currentindex + 1) : resetQueue();
},
playNext() {
this.play(this.nextindex);
@@ -152,6 +172,13 @@ export default defineStore("Queue", {
this.tracklist = [];
this.tracklist.push(...tracklist);
}
+
+ const settings = useSettingsStore();
+
+ if (settings.repeat_one) {
+ settings.toggleRepeatMode();
+ }
+ this.focusCurrentInSidebar(1000);
},
playFromFolder(fpath: string, tracks: Track[]) {
console.log("play from folder");
diff --git a/src/stores/settings/index.ts b/src/stores/settings/index.ts
index e93f5ee..8df791d 100644
--- a/src/stores/settings/index.ts
+++ b/src/stores/settings/index.ts
@@ -9,6 +9,8 @@ export default defineStore("settings", {
extend_width: false,
contextChildrenShowMode: contextChildrenShowMode.click,
artist_top_tracks_count: 5,
+ repeat_all: true,
+ repeat_one: false,
}),
actions: {
toggleUseNPImg() {
@@ -29,11 +31,31 @@ export default defineStore("settings", {
? contextChildrenShowMode.hover
: contextChildrenShowMode.click;
},
+ toggleRepeatMode() {
+ if (this.repeat_all) {
+ this.repeat_all = false;
+ this.repeat_one = true;
+ return;
+ }
+
+ if (this.repeat_one) {
+ this.repeat_one = false;
+ this.repeat_all = false;
+ return;
+ }
+
+ if (!this.repeat_all && !this.repeat_one) {
+ this.repeat_all = true;
+ }
+ },
},
getters: {
can_extend_width(): boolean {
return xxl.value;
},
+ no_repeat(): boolean {
+ return !this.repeat_all && !this.repeat_one;
+ },
},
persist: true,
});
]