mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-03 20:13:02 +00:00
major refactors
This commit is contained in:
@@ -30,7 +30,14 @@ def get_all_playlists():
|
||||
@playlist_bp.route("/playlist/new", methods=["POST"])
|
||||
def create_playlist():
|
||||
data = request.get_json()
|
||||
playlist = {"name": data["name"], "description": [], "tracks": []}
|
||||
|
||||
playlist = {
|
||||
"name": data["name"],
|
||||
"description": [],
|
||||
"tracks": [],
|
||||
"count": 0,
|
||||
"lastUpdated": 0,
|
||||
}
|
||||
|
||||
try:
|
||||
p_in_db = instances.playlist_instance.get_playlist_by_name(playlist["name"])
|
||||
|
||||
@@ -21,7 +21,7 @@ class AllSongs(db.Mongo):
|
||||
# def drop_db(self):
|
||||
# self.collection.drop()
|
||||
|
||||
def insert_song(self, song_obj: dict) -> None:
|
||||
def insert_song(self, song_obj: dict) -> str:
|
||||
"""
|
||||
Inserts a new track object into the database.
|
||||
"""
|
||||
|
||||
@@ -69,11 +69,12 @@ def populate():
|
||||
for file in files:
|
||||
tags = get_tags(file)
|
||||
|
||||
if tags not in api.PRE_TRACKS:
|
||||
api.PRE_TRACKS.append(tags)
|
||||
|
||||
if tags is not None:
|
||||
instances.songs_instance.insert_song(tags)
|
||||
upsert_id = instances.songs_instance.insert_song(tags)
|
||||
|
||||
if upsert_id is not None:
|
||||
tags["_id"] = {"$oid": upsert_id}
|
||||
api.PRE_TRACKS.append(tags)
|
||||
|
||||
_bar.next()
|
||||
_bar.finish()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
This library contains all the functions related to albums.
|
||||
"""
|
||||
|
||||
from pprint import pprint
|
||||
import urllib
|
||||
from typing import List
|
||||
from app import models, functions, helpers
|
||||
@@ -52,9 +53,12 @@ def get_album_tracks(album: str, artist: str) -> List:
|
||||
tracks = []
|
||||
|
||||
for track in api.PRE_TRACKS:
|
||||
if track["album"] == album and track["albumartist"] == artist:
|
||||
tracks.append(track)
|
||||
|
||||
try:
|
||||
if track["album"] == album and track["albumartist"] == artist:
|
||||
tracks.append(track)
|
||||
except TypeError:
|
||||
pprint(track, indent=4)
|
||||
print(album, artist)
|
||||
return tracks
|
||||
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ Contains all the models for objects generation and typing.
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import date
|
||||
from typing import List
|
||||
from app import api
|
||||
from app import settings
|
||||
@@ -95,6 +96,8 @@ class Playlist:
|
||||
description: str
|
||||
image: str
|
||||
tracks: List[Track]
|
||||
count: int
|
||||
lastUpdated: int
|
||||
"""A list of track objects in the playlist"""
|
||||
|
||||
def __init__(self, data):
|
||||
@@ -103,6 +106,9 @@ class Playlist:
|
||||
self.description = data["description"]
|
||||
self.image = ""
|
||||
self.tracks = create_playlist_tracks(data["tracks"])
|
||||
self.count = len(data["tracks"])
|
||||
self.lastUpdated = data["lastUpdated"]
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
+5
-1
@@ -39,11 +39,15 @@ import useContextStore from "./stores/context";
|
||||
import ContextMenu from "./components/contextMenu.vue";
|
||||
import Modal from "./components/modal.vue";
|
||||
import Notification from "./components/Notification.vue";
|
||||
import useQStore from "./stores/queue";
|
||||
|
||||
const context_store = useContextStore();
|
||||
const queue = useQStore();
|
||||
|
||||
queue.readQueueFromLocalStorage();
|
||||
|
||||
const RightSideBar = Main;
|
||||
perks.readQueue();
|
||||
|
||||
const collapsed = ref(false);
|
||||
|
||||
const app_dom = document.getElementById("app");
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
<template>
|
||||
<div class="hotkeys">
|
||||
<div class="image ctrl-btn" id="previous" @click="playPrev"></div>
|
||||
<div class="image ctrl-btn" id="previous" @click="props.prev"></div>
|
||||
<div
|
||||
class="image ctrl-btn play-pause"
|
||||
@click="playPause"
|
||||
:class="{ isPlaying: isPlaying }"
|
||||
:class="{ isPlaying: props.playing }"
|
||||
></div>
|
||||
<div class="image ctrl-btn" id="next" @click="playNext"></div>
|
||||
<div class="image ctrl-btn" id="next" @click="props.next"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import playAudio from '../../../composables/playAudio';
|
||||
|
||||
const playPause = playAudio.playPause;
|
||||
const playNext = playAudio.playNext;
|
||||
const playPrev = playAudio.playPrev;
|
||||
|
||||
const isPlaying = playAudio.playing;
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
playing: boolean;
|
||||
playPause: () => void;
|
||||
next: () => void;
|
||||
prev: () => void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -31,16 +30,16 @@ const isPlaying = playAudio.playing;
|
||||
place-content: flex-end;
|
||||
|
||||
.ctrl-btn {
|
||||
height: 2.5rem;
|
||||
width: 100%;
|
||||
background-size: 1.5rem !important;
|
||||
cursor: pointer;
|
||||
border-radius: 0.5rem;
|
||||
height: 2.5rem;
|
||||
width: 100%;
|
||||
background-size: 1.5rem !important;
|
||||
cursor: pointer;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
&:hover {
|
||||
background-color: $red;
|
||||
}
|
||||
&:hover {
|
||||
background-color: $red;
|
||||
}
|
||||
}
|
||||
|
||||
#previous {
|
||||
background-image: url(../../../assets/icons/previous.svg);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<input
|
||||
id="progress"
|
||||
type="range"
|
||||
:value="pos"
|
||||
:value="props.pos"
|
||||
min="0"
|
||||
max="100"
|
||||
step="0.1"
|
||||
@@ -10,12 +10,14 @@
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import playAudio from "../../../composables/playAudio";
|
||||
const pos = ref(playAudio.pos);
|
||||
|
||||
<script setup lang="ts">
|
||||
const seek = () => {
|
||||
playAudio.seek(document.getElementById("progress").value);
|
||||
const value = Number(document.getElementById("progress").value);
|
||||
props.seek(value);
|
||||
};
|
||||
|
||||
const props = defineProps<{
|
||||
pos: number;
|
||||
seek: (time: number) => void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
@@ -1,39 +1,30 @@
|
||||
<template>
|
||||
<div class="info">
|
||||
<div
|
||||
v-if="props.collapsed"
|
||||
class="image art"
|
||||
:style="{
|
||||
backgroundImage: `url("${track.image}")`,
|
||||
}"
|
||||
></div>
|
||||
<div class="desc">
|
||||
<div>
|
||||
<div class="title ellip">{{ track.title }}</div>
|
||||
<div class="title ellip">{{ props.track.title }}</div>
|
||||
<div class="separator no-border"></div>
|
||||
<div class="artists ellip" v-if="track.artists[0] !== ''">
|
||||
<span v-for="artist in putCommas(track.artists)" :key="artist">{{
|
||||
artist
|
||||
}}</span>
|
||||
<div class="artists ellip" v-if="props.track.artists[0] !== ''">
|
||||
<span
|
||||
v-for="artist in putCommas(props.track.artists)"
|
||||
:key="artist"
|
||||
>{{ artist }}</span
|
||||
>
|
||||
</div>
|
||||
<div class="artists" v-else>
|
||||
<span>{{ track.albumartist }}</span>
|
||||
<span>{{ props.track.albumartist }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import perks from "../../composables/perks";
|
||||
import state from "../../composables/state";
|
||||
|
||||
const track = state.current;
|
||||
const props = defineProps({
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
import { Track } from "../../interfaces";
|
||||
const putCommas = perks.putCommas;
|
||||
</script>
|
||||
|
||||
const props = defineProps<{
|
||||
track: Track;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="l_ rounded" v-if="!props.collapsed">
|
||||
<div class="l_ rounded">
|
||||
<div class="headin">Now Playing</div>
|
||||
<div class="button menu image rounded"></div>
|
||||
<div class="separator no-border"></div>
|
||||
@@ -8,32 +8,30 @@
|
||||
<div
|
||||
class="l-image image rounded"
|
||||
:style="{
|
||||
backgroundImage: `url("${current.image}")`,
|
||||
backgroundImage: `url("${queue.current.image}")`,
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
<div class="separator no-border"></div>
|
||||
<SongCard />
|
||||
<Progress />
|
||||
<HotKeys />
|
||||
<SongCard :track="queue.current" />
|
||||
<Progress :seek="queue.seek" :pos="queue.current_time" />
|
||||
<HotKeys
|
||||
:playing="queue.playing"
|
||||
:playPause="queue.playPause"
|
||||
:next="queue.playNext"
|
||||
:prev="queue.playPrev"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import state from "../../composables/state";
|
||||
import SongCard from "./SongCard.vue";
|
||||
import HotKeys from "./NP/HotKeys.vue";
|
||||
import Progress from "./NP/Progress.vue";
|
||||
import useQStore from "../../stores/queue";
|
||||
|
||||
const current = ref(state.current);
|
||||
const props = defineProps({
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const queue = useQStore();
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.l_ {
|
||||
|
||||
@@ -28,7 +28,7 @@ const props = defineProps<{
|
||||
|
||||
.image {
|
||||
min-width: 100%;
|
||||
height: 8.5rem;
|
||||
height: 10rem;
|
||||
background-image: url("../../assets/images/eggs.jpg");
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,8 @@ const loading = state.loading
|
||||
|
||||
<style lang="scss">
|
||||
.loaderx {
|
||||
position: absolute;
|
||||
top: 0.65rem;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
height:1.5rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,10 +79,7 @@ const showContextMenu = (e: Event) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
contextStore.showContextMenu(
|
||||
e,
|
||||
trackContext(props.song, modalStore)
|
||||
);
|
||||
contextStore.showContextMenu(e, trackContext(props.song, modalStore));
|
||||
context_on.value = true;
|
||||
|
||||
contextStore.$subscribe((mutation, state) => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
@click="playThis(props.track)"
|
||||
:class="[
|
||||
{
|
||||
currentInQueue: current.trackid === props.track.trackid,
|
||||
currentInQueue: props.isCurrent,
|
||||
},
|
||||
{ 'context-on': context_on },
|
||||
]"
|
||||
@@ -18,8 +18,8 @@
|
||||
>
|
||||
<div
|
||||
class="now-playing-track image"
|
||||
v-if="current.trackid === props.track.trackid"
|
||||
:class="{ active: is_playing, not_active: !is_playing }"
|
||||
v-if="props.isCurrent"
|
||||
:class="{ active: props.isPlaying, not_active: !props.isPlaying }"
|
||||
></div>
|
||||
</div>
|
||||
<div class="tags">
|
||||
@@ -34,21 +34,31 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import perks from "../../composables/perks";
|
||||
import playAudio from "../../composables/playAudio";
|
||||
import useContextStore from "@/stores/context";
|
||||
import trackContext from "../../contexts/track_context";
|
||||
import { Track } from "../../interfaces";
|
||||
|
||||
import useContextStore from "../../stores/context";
|
||||
import useModalStore from "../../stores/modal";
|
||||
|
||||
const contextStore = useContextStore();
|
||||
const modalStore = useModalStore();
|
||||
|
||||
const props = defineProps<{
|
||||
track: Track;
|
||||
isCurrent: boolean;
|
||||
isPlaying: boolean;
|
||||
}>();
|
||||
|
||||
const context_on = ref(false);
|
||||
|
||||
const showContextMenu = (e) => {
|
||||
const showContextMenu = (e: Event) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
contextStore.showContextMenu(e, trackContext(props.track));
|
||||
contextStore.showContextMenu(e, trackContext(props.track, modalStore));
|
||||
context_on.value = true;
|
||||
|
||||
contextStore.$subscribe((mutation, state) => {
|
||||
@@ -57,18 +67,16 @@ const showContextMenu = (e) => {
|
||||
}
|
||||
});
|
||||
};
|
||||
const props = defineProps({
|
||||
track: Object,
|
||||
default: () => ({}),
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "PlayThis", track: Track): void;
|
||||
}>();
|
||||
|
||||
const current = ref(perks.current);
|
||||
const putCommas = perks.putCommas;
|
||||
const is_playing = ref(playAudio.playing);
|
||||
|
||||
const playThis = (song) => {
|
||||
playAudio.playAudio(song.trackid);
|
||||
perks.current.value = song;
|
||||
const playThis = (track: Track) => {
|
||||
emit("PlayThis", track);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,41 +1,44 @@
|
||||
import { Track } from "../interfaces.js";
|
||||
import perks from "./perks.js";
|
||||
import playAudio from "./playAudio.js";
|
||||
|
||||
let showMediaNotif = () => {
|
||||
let current = perks.current.value;
|
||||
|
||||
export default (
|
||||
track: Track,
|
||||
playPause: () => void,
|
||||
playNext: () => void,
|
||||
playPrev: () => void
|
||||
) => {
|
||||
if ("mediaSession" in navigator) {
|
||||
navigator.mediaSession.metadata = new window.MediaMetadata({
|
||||
title: current.title,
|
||||
artist: current.artists,
|
||||
title: track.title,
|
||||
artist: track.artists.join(", "),
|
||||
artwork: [
|
||||
{
|
||||
src: current.image,
|
||||
src: track.image,
|
||||
sizes: "96x96",
|
||||
type: "image/jpeg",
|
||||
},
|
||||
{
|
||||
src: current.image,
|
||||
src: track.image,
|
||||
sizes: "128x128",
|
||||
type: "image/webp",
|
||||
},
|
||||
{
|
||||
src: current.image,
|
||||
src: track.image,
|
||||
sizes: "192x192",
|
||||
type: "image/webp",
|
||||
},
|
||||
{
|
||||
src: current.image,
|
||||
src: track.image,
|
||||
sizes: "256x256",
|
||||
type: "image/webp",
|
||||
},
|
||||
{
|
||||
src: current.image,
|
||||
src: track.image,
|
||||
sizes: "384x384",
|
||||
type: "image/webp",
|
||||
},
|
||||
{
|
||||
src: current.image,
|
||||
src: track.image,
|
||||
sizes: "512x512",
|
||||
type: "image/webp",
|
||||
},
|
||||
@@ -43,22 +46,16 @@ let showMediaNotif = () => {
|
||||
});
|
||||
|
||||
navigator.mediaSession.setActionHandler("play", function () {
|
||||
playAudio.playPause();
|
||||
playPause();
|
||||
});
|
||||
navigator.mediaSession.setActionHandler("pause", function () {
|
||||
playAudio.playPause();
|
||||
playPause();
|
||||
});
|
||||
navigator.mediaSession.setActionHandler("seekbackward", function () {});
|
||||
navigator.mediaSession.setActionHandler("seekforward", function () {});
|
||||
navigator.mediaSession.setActionHandler("previoustrack", function () {
|
||||
playAudio.playPrev();
|
||||
playPrev();
|
||||
});
|
||||
navigator.mediaSession.setActionHandler("nexttrack", function () {
|
||||
playAudio.playNext();
|
||||
playNext();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
showMediaNotif,
|
||||
};
|
||||
+3
-114
@@ -1,26 +1,3 @@
|
||||
import { ref } from "@vue/reactivity";
|
||||
import { watch } from "@vue/runtime-core";
|
||||
import media from "./mediaNotification.js";
|
||||
import playAudio from "./playAudio.js";
|
||||
import state from "./state";
|
||||
|
||||
const current = ref(state.current);
|
||||
|
||||
const next = ref({
|
||||
title: "The next song",
|
||||
artists: ["... blah blah blah"],
|
||||
image: "http://127.0.0.1:8900/images/defaults/4.webp",
|
||||
_id: {
|
||||
$oid: "",
|
||||
},
|
||||
});
|
||||
|
||||
const prev = ref(state.prev);
|
||||
|
||||
const queue = ref(state.queue);
|
||||
|
||||
const search = ref("");
|
||||
|
||||
const putCommas = (artists) => {
|
||||
let result = [];
|
||||
|
||||
@@ -35,74 +12,6 @@ const putCommas = (artists) => {
|
||||
return result;
|
||||
};
|
||||
|
||||
function updateNext(song_) {
|
||||
const index = state.queue.value.findIndex(
|
||||
(item) => item.trackid === song_.trackid
|
||||
);
|
||||
|
||||
if (index === queue.value.length - 1) {
|
||||
next.value = queue.value[0];
|
||||
state.prev.value = queue.value[queue.value.length - 2];
|
||||
} else if (index === 0) {
|
||||
next.value = queue.value[1];
|
||||
} else {
|
||||
next.value = queue.value[index + 1];
|
||||
}
|
||||
}
|
||||
|
||||
function updatePrev(song) {
|
||||
const index = state.queue.value.findIndex(
|
||||
(item) => item.trackid === song.trackid
|
||||
);
|
||||
|
||||
if (index === 0) {
|
||||
prev.value = queue.value[queue.value.length - 1];
|
||||
} else if (index === queue.value.length - 1) {
|
||||
prev.value = queue.value[index - 1];
|
||||
} else {
|
||||
prev.value = queue.value[index - 1];
|
||||
}
|
||||
}
|
||||
|
||||
const readQueue = () => {
|
||||
const prev_queue = JSON.parse(localStorage.getItem("queue"));
|
||||
const last_played = JSON.parse(localStorage.getItem("current"));
|
||||
|
||||
if (last_played) {
|
||||
state.current.value = last_played;
|
||||
}
|
||||
|
||||
if (prev_queue) {
|
||||
state.queue.value = prev_queue;
|
||||
|
||||
updateNext(state.current.value);
|
||||
updatePrev(state.current.value);
|
||||
}
|
||||
};
|
||||
|
||||
const updateQueue = async (song, type) => {
|
||||
playAudio.playAudio(song.trackid);
|
||||
let list;
|
||||
|
||||
switch (type) {
|
||||
case "folder":
|
||||
list = state.folder_song_list.value;
|
||||
break;
|
||||
case "album":
|
||||
list = state.album.tracklist;
|
||||
break;
|
||||
}
|
||||
|
||||
if (state.queue.value[0].trackid !== list[0].trackid) {
|
||||
const new_queue = list;
|
||||
localStorage.setItem("queue", JSON.stringify(new_queue));
|
||||
state.queue.value = new_queue;
|
||||
}
|
||||
|
||||
state.current.value = song;
|
||||
localStorage.setItem("current", JSON.stringify(song));
|
||||
};
|
||||
|
||||
function focusCurrent() {
|
||||
const elem = document.getElementsByClassName("currentInQueue")[0];
|
||||
|
||||
@@ -132,17 +41,6 @@ function focusSearchBox() {
|
||||
elem.focus();
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
watch(current, (new_current) => {
|
||||
media.showMediaNotif();
|
||||
|
||||
updateNext(new_current);
|
||||
updatePrev(new_current);
|
||||
|
||||
localStorage.setItem("current", JSON.stringify(new_current));
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
let key_down_fired = false;
|
||||
|
||||
window.addEventListener("keydown", (e) => {
|
||||
@@ -161,7 +59,7 @@ window.addEventListener("keydown", (e) => {
|
||||
key_down_fired = false;
|
||||
}, 1000);
|
||||
|
||||
playAudio.playNext();
|
||||
// playAudio.playNext();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -173,7 +71,7 @@ window.addEventListener("keydown", (e) => {
|
||||
|
||||
key_down_fired = true;
|
||||
|
||||
playAudio.playPrev();
|
||||
// playAudio.playPrev();
|
||||
|
||||
setTimeout(() => {
|
||||
key_down_fired = false;
|
||||
@@ -190,7 +88,7 @@ window.addEventListener("keydown", (e) => {
|
||||
e.preventDefault();
|
||||
key_down_fired = true;
|
||||
|
||||
playAudio.playPause();
|
||||
// playAudio.playPause();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,8 +110,6 @@ window.addEventListener("keyup", () => {
|
||||
key_down_fired = false;
|
||||
});
|
||||
|
||||
|
||||
|
||||
function formatSeconds(seconds) {
|
||||
// check if there are arguments
|
||||
|
||||
@@ -256,14 +152,7 @@ function formatSeconds(seconds) {
|
||||
|
||||
export default {
|
||||
putCommas,
|
||||
readQueue,
|
||||
focusCurrent,
|
||||
updateQueue,
|
||||
formatSeconds,
|
||||
getElem,
|
||||
current,
|
||||
queue,
|
||||
next,
|
||||
prev,
|
||||
search,
|
||||
};
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
import {ref} from "@vue/reactivity";
|
||||
|
||||
import perks from "./perks";
|
||||
import media from "./mediaNotification.js";
|
||||
import state from "./state";
|
||||
|
||||
const audio = ref(new Audio()).value;
|
||||
|
||||
const pos = ref(0);
|
||||
const current_time = ref(0);
|
||||
|
||||
const playing = ref(state.is_playing);
|
||||
|
||||
const url = "http://127.0.0.1:9876//file/";
|
||||
|
||||
const playAudio = (trackid) => {
|
||||
const elem = document.getElementById('progress');
|
||||
|
||||
const full_path = url + encodeURIComponent(trackid);
|
||||
|
||||
new Promise((resolve, reject) => {
|
||||
audio.src = full_path;
|
||||
audio.oncanplaythrough = resolve;
|
||||
audio.onerror = reject;
|
||||
})
|
||||
.then(() => {
|
||||
audio.play().then(() => {
|
||||
perks.focusCurrent()
|
||||
state.is_playing.value = true;
|
||||
}
|
||||
);
|
||||
audio.ontimeupdate = () => {
|
||||
current_time.value = audio.currentTime;
|
||||
pos.value = (audio.currentTime / audio.duration) * 100;
|
||||
let bg_size = ((audio.currentTime / audio.duration) * 100)
|
||||
|
||||
elem.style.backgroundSize = `${bg_size}% 100%`;
|
||||
};
|
||||
})
|
||||
.catch((err) => console.log(err));
|
||||
};
|
||||
|
||||
function playNext() {
|
||||
playAudio(perks.next.value.trackid);
|
||||
perks.current.value = perks.next.value;
|
||||
media.showMediaNotif();
|
||||
}
|
||||
|
||||
function playPrev() {
|
||||
playAudio(state.prev.value.trackid);
|
||||
perks.current.value = perks.prev.value;
|
||||
}
|
||||
|
||||
function seek(position) {
|
||||
audio.currentTime = (position / 100) * audio.duration;
|
||||
}
|
||||
|
||||
function playPause() {
|
||||
if (audio.src === "") {
|
||||
playAudio(perks.current.value.trackid);
|
||||
}
|
||||
|
||||
if (audio.paused) {
|
||||
audio.play();
|
||||
} else {
|
||||
audio.pause();
|
||||
}
|
||||
}
|
||||
|
||||
audio.addEventListener("play", () => {
|
||||
state.is_playing.value = true;
|
||||
});
|
||||
|
||||
audio.addEventListener("pause", () => {
|
||||
state.is_playing.value = false;
|
||||
});
|
||||
|
||||
audio.addEventListener("ended", () => {
|
||||
playNext();
|
||||
});
|
||||
|
||||
export default {playAudio, playNext, playPrev, playPause, seek, pos, playing, current_time};
|
||||
|
||||
|
||||
// TODO
|
||||
// Try implementing classes to play audio .ie. Make the seek, playNext, playPrev, etc the methods of a class. etc
|
||||
@@ -12,6 +12,7 @@ import SettingsView from "../views/SettingsView.vue";
|
||||
|
||||
import usePStore from "../stores/playlists";
|
||||
import usePTrackStore from "../stores/p.ptracks";
|
||||
import useFStore from "../stores/folder";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@@ -23,6 +24,10 @@ const routes = [
|
||||
path: "/folder/:path",
|
||||
name: "FolderView",
|
||||
component: FolderView,
|
||||
beforeEnter: async (to) => {
|
||||
console.log("beforeEnter")
|
||||
await useFStore().fetchAll(to.params.path);
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/folder/",
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { Folder, Track } from "../interfaces";
|
||||
|
||||
import fetchThem from "../composables/getFilesAndFolders";
|
||||
|
||||
export default defineStore("FolderDirs&Tracks", {
|
||||
state: () => ({
|
||||
path: <string>{},
|
||||
dirs: <Folder[]>[],
|
||||
tracks: <Track[]>[],
|
||||
}),
|
||||
actions: {
|
||||
async fetchAll(path: string) {
|
||||
const { tracks, folders } = await fetchThem(path);
|
||||
|
||||
this.path = path;
|
||||
this.dirs = folders;
|
||||
this.tracks = tracks;
|
||||
},
|
||||
},
|
||||
});
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { defineStore } from "pinia";
|
||||
import { Track } from "../interfaces";
|
||||
enum ModalOptions {
|
||||
newPlaylist = "newPlaylist",
|
||||
editPlaylist = "editPlaylist",
|
||||
newPlaylist,
|
||||
editPlaylist,
|
||||
}
|
||||
|
||||
export default defineStore("newModal", {
|
||||
|
||||
@@ -22,6 +22,7 @@ const playlist = usePTrackStore().playlist;
|
||||
const info = {
|
||||
name: playlist.name,
|
||||
count: playlist.tracks.length,
|
||||
desc: playlist.description,
|
||||
duration: "3 hours, 4 minutes",
|
||||
lastUpdated: "yesterday",
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user