mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-05 04:53:01 +00:00
try adding playlists list to context menu - unsuccsessfully
This commit is contained in:
@@ -19,13 +19,14 @@ def create_app():
|
|||||||
cache.init_app(app)
|
cache.init_app(app)
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
from app.api import artist, track, search, folder, album
|
from app.api import artist, track, search, folder, album, playlist
|
||||||
|
|
||||||
app.register_blueprint(album.album_bp, url_prefix="/")
|
app.register_blueprint(album.album_bp, url_prefix="/")
|
||||||
app.register_blueprint(artist.artist_bp, url_prefix="/")
|
app.register_blueprint(artist.artist_bp, url_prefix="/")
|
||||||
app.register_blueprint(track.track_bp, url_prefix="/")
|
app.register_blueprint(track.track_bp, url_prefix="/")
|
||||||
app.register_blueprint(search.search_bp, url_prefix="/")
|
app.register_blueprint(search.search_bp, url_prefix="/")
|
||||||
app.register_blueprint(folder.folder_bp, url_prefix="/")
|
app.register_blueprint(folder.folder_bp, url_prefix="/")
|
||||||
|
app.register_blueprint(playlist.playlist_bp, url_prefix="/")
|
||||||
|
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from app import models, instances
|
|||||||
from app import functions, helpers, prep
|
from app import functions, helpers, prep
|
||||||
from app.lib import albumslib
|
from app.lib import albumslib
|
||||||
from app.lib import folderslib
|
from app.lib import folderslib
|
||||||
|
from app.lib import playlistlib
|
||||||
|
|
||||||
|
|
||||||
DB_TRACKS = instances.songs_instance.get_all_songs()
|
DB_TRACKS = instances.songs_instance.get_all_songs()
|
||||||
@@ -20,6 +21,7 @@ TRACKS: List[models.Track] = []
|
|||||||
PLAYLISTS: List[models.Playlist] = []
|
PLAYLISTS: List[models.Playlist] = []
|
||||||
FOLDERS: List[models.Folder] = []
|
FOLDERS: List[models.Folder] = []
|
||||||
|
|
||||||
|
|
||||||
@helpers.background
|
@helpers.background
|
||||||
def initialize() -> None:
|
def initialize() -> None:
|
||||||
"""
|
"""
|
||||||
@@ -29,8 +31,8 @@ def initialize() -> None:
|
|||||||
prep.create_config_dir()
|
prep.create_config_dir()
|
||||||
albumslib.create_everything()
|
albumslib.create_everything()
|
||||||
folderslib.run_scandir()
|
folderslib.run_scandir()
|
||||||
|
playlistlib.create_all_playlists()
|
||||||
functions.reindex_tracks()
|
functions.reindex_tracks()
|
||||||
|
|
||||||
|
|
||||||
initialize()
|
initialize()
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ def get_folder_tree():
|
|||||||
songs = []
|
songs = []
|
||||||
|
|
||||||
for track in api.TRACKS:
|
for track in api.TRACKS:
|
||||||
if track.folder + "/" == req_dir:
|
if track.folder == req_dir:
|
||||||
songs.append(track)
|
songs.append(track)
|
||||||
|
|
||||||
final_tracks = helpers.remove_duplicates(songs)
|
final_tracks = helpers.remove_duplicates(songs)
|
||||||
|
|||||||
@@ -11,22 +11,24 @@ playlist_bp = Blueprint("playlist", __name__, url_prefix="/")
|
|||||||
|
|
||||||
@playlist_bp.route("/playlists", methods=["GET"])
|
@playlist_bp.route("/playlists", methods=["GET"])
|
||||||
def get_all_playlists():
|
def get_all_playlists():
|
||||||
|
print(api.PLAYLISTS)
|
||||||
playlists = []
|
playlists = []
|
||||||
|
|
||||||
for playlist in api.PLAYLISTS:
|
for playlist in api.PLAYLISTS:
|
||||||
del playlist.tracks
|
playlist.tracks = []
|
||||||
playlists.append(playlist)
|
playlists.append(playlist)
|
||||||
|
|
||||||
return playlists
|
return {"data": playlists}
|
||||||
|
|
||||||
|
|
||||||
@playlist_bp.route("/playlist/new")
|
@playlist_bp.route("/playlist/new", methods=["POST"])
|
||||||
def create_playlist():
|
def create_playlist():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
|
|
||||||
playlist = {"name": data["name"], "description": data["description"], "tracks": []}
|
playlist = {"name": data["name"], "description": [], "tracks": []}
|
||||||
|
|
||||||
instances.playlist_instance.insert_playlist(playlist)
|
instances.playlist_instance.insert_playlist(playlist)
|
||||||
return 200
|
return {"msg": "success"}
|
||||||
|
|
||||||
|
|
||||||
@playlist_bp.route("/playlist/<playlist_id>/add", methods=["POST"])
|
@playlist_bp.route("/playlist/<playlist_id>/add", methods=["POST"])
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ from app import settings, models
|
|||||||
from app.lib import albumslib
|
from app.lib import albumslib
|
||||||
from app import api
|
from app import api
|
||||||
from app.lib import watchdoge
|
from app.lib import watchdoge
|
||||||
|
from app.lib import folderslib
|
||||||
|
|
||||||
|
|
||||||
@helpers.background
|
@helpers.background
|
||||||
@@ -61,7 +62,6 @@ def populate():
|
|||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
s, files = helpers.run_fast_scandir(settings.HOME_DIR, [".flac", ".mp3"], full=True)
|
s, files = helpers.run_fast_scandir(settings.HOME_DIR, [".flac", ".mp3"], full=True)
|
||||||
# pprint(s)
|
|
||||||
|
|
||||||
_bar = Bar("Processing files", max=len(files))
|
_bar = Bar("Processing files", max=len(files))
|
||||||
for file in files:
|
for file in files:
|
||||||
@@ -74,7 +74,8 @@ def populate():
|
|||||||
_bar.finish()
|
_bar.finish()
|
||||||
|
|
||||||
albumslib.create_everything()
|
albumslib.create_everything()
|
||||||
|
folderslib.run_scandir()
|
||||||
|
|
||||||
end = time.time()
|
end = time.time()
|
||||||
|
|
||||||
print(
|
print(
|
||||||
@@ -340,7 +341,7 @@ def get_tags(fullpath: str) -> dict:
|
|||||||
"length": round(audio.info.length),
|
"length": round(audio.info.length),
|
||||||
"bitrate": round(int(audio.info.bitrate) / 1000),
|
"bitrate": round(int(audio.info.bitrate) / 1000),
|
||||||
"filepath": fullpath,
|
"filepath": fullpath,
|
||||||
"folder": os.path.dirname(fullpath),
|
"folder": os.path.dirname(fullpath) + "/",
|
||||||
}
|
}
|
||||||
|
|
||||||
return tags
|
return tags
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ def create_folder(foldername: str) -> models.Folder:
|
|||||||
return models.Folder(folder)
|
return models.Folder(folder)
|
||||||
|
|
||||||
|
|
||||||
def create_all_folders(foldernames: List[str]) -> List[models.Folder]:
|
def create_all_folders() -> List[models.Folder]:
|
||||||
folders_: List[models.Folder] = []
|
folders_: List[models.Folder] = []
|
||||||
_bar = Bar("Creating folders", max=len(foldernames))
|
_bar = Bar("Creating folders", max=len(api.VALID_FOLDERS))
|
||||||
|
|
||||||
for foldername in foldernames:
|
for foldername in api.VALID_FOLDERS:
|
||||||
folder = create_folder(foldername)
|
folder = create_folder(foldername)
|
||||||
folders_.append(folder)
|
folders_.append(folder)
|
||||||
_bar.next()
|
_bar.next()
|
||||||
@@ -61,11 +61,17 @@ def get_subdirs(foldername: str) -> List[models.Folder]:
|
|||||||
|
|
||||||
@helpers.background
|
@helpers.background
|
||||||
def run_scandir():
|
def run_scandir():
|
||||||
|
"""
|
||||||
|
Initiates the creation of all folder objects for each folder with a track in it.
|
||||||
|
|
||||||
|
Runs in a background thread after every 5 minutes.
|
||||||
|
It calls the
|
||||||
|
"""
|
||||||
flag = False
|
flag = False
|
||||||
|
|
||||||
while flag is False:
|
while flag is False:
|
||||||
get_valid_folders()
|
get_valid_folders()
|
||||||
folders_ = create_all_folders(api.VALID_FOLDERS)
|
folders_ = create_all_folders()
|
||||||
"""Create all the folder objects before clearing api.FOLDERS"""
|
"""Create all the folder objects before clearing api.FOLDERS"""
|
||||||
|
|
||||||
api.FOLDERS.clear()
|
api.FOLDERS.clear()
|
||||||
|
|||||||
+4
-1
@@ -1,5 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<ContextMenu />
|
<ContextMenu />
|
||||||
|
<Modal />
|
||||||
|
<Notification />
|
||||||
<div class="l-container" :class="{ collapsed: collapsed }">
|
<div class="l-container" :class="{ collapsed: collapsed }">
|
||||||
<div class="l-sidebar">
|
<div class="l-sidebar">
|
||||||
<div id="logo-container">
|
<div id="logo-container">
|
||||||
@@ -25,7 +27,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import Navigation from "./components/LeftSidebar/Navigation.vue";
|
import Navigation from "./components/LeftSidebar/Navigation.vue";
|
||||||
import BottomBar from "@/components/BottomBar/BottomBar.vue";
|
|
||||||
|
|
||||||
import perks from "@/composables/perks.js";
|
import perks from "@/composables/perks.js";
|
||||||
|
|
||||||
@@ -36,6 +37,8 @@ import Tabs from "./components/RightSideBar/Tabs.vue";
|
|||||||
import SearchInput from "./components/RightSideBar/SearchInput.vue";
|
import SearchInput from "./components/RightSideBar/SearchInput.vue";
|
||||||
import useContextStore from "./stores/context";
|
import useContextStore from "./stores/context";
|
||||||
import ContextMenu from "./components/contextMenu.vue";
|
import ContextMenu from "./components/contextMenu.vue";
|
||||||
|
import Modal from "./components/modal.vue";
|
||||||
|
import Notification from "./components/Notification.vue";
|
||||||
|
|
||||||
const context_store = useContextStore();
|
const context_store = useContextStore();
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
font-size: small;
|
font-size: 2rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.t-center {
|
.t-center {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="text">
|
<div class="text">
|
||||||
<div class="icon image"></div>
|
<div class="icon image"></div>
|
||||||
<div class="ellip">
|
<div class="ellip">
|
||||||
{{ path.split("/").splice(-1) + "" }}
|
{{ path.split("/").splice(-2).join("") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<div class="new-notification rounded" v-if="store.visible">
|
||||||
|
<div>{{ store.text }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useNotificationStore } from "../stores/notification";
|
||||||
|
const store = useNotificationStore();
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.new-notification {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 2000;
|
||||||
|
width: 25rem;
|
||||||
|
bottom: 2rem;
|
||||||
|
padding: $small;
|
||||||
|
left: 50%;
|
||||||
|
translate: -50%;
|
||||||
|
background-color: rgb(5, 62, 168);
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
|
||||||
|
.link {
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<div class="new-playlist-modal" v-if="modal.visible">
|
||||||
|
<div class="bg" @click="modal.hideModal"></div>
|
||||||
|
<div class="m-content rounded">
|
||||||
|
<div class="heading">{{ modal.title }}</div>
|
||||||
|
<div class="cancel image" @click="modal.hideModal"></div>
|
||||||
|
<NewPlaylist
|
||||||
|
v-if="modal.component == modal.options.newPlaylist"
|
||||||
|
@hideModal="hideModal"
|
||||||
|
@title="title"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import useModalStore from "../stores/modal";
|
||||||
|
import NewPlaylist from "./modals/NewPlaylist.vue";
|
||||||
|
|
||||||
|
const modal = useModalStore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the modal title
|
||||||
|
* @param title
|
||||||
|
*/
|
||||||
|
function title(title: string) {
|
||||||
|
modal.setTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the emit to hide the modal
|
||||||
|
*/
|
||||||
|
function hideModal() {
|
||||||
|
modal.hideModal();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.new-playlist-modal {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 2000;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
|
||||||
|
.bg {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(12, 12, 12, 0.767);
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-content {
|
||||||
|
width: 30rem;
|
||||||
|
background-color: $black;
|
||||||
|
padding: 1rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.cancel {
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
background-image: url("../assets/icons/plus.svg");
|
||||||
|
transform: rotate(45deg);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
transform: rotate(135deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<form @submit="create" class="new-p-form">
|
||||||
|
<label for="name">Playlist name</label>
|
||||||
|
<br />
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="rounded"
|
||||||
|
name="name"
|
||||||
|
id="modal-playlist-name-input"
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<input type="submit" class="rounded" value="Create" />
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { createNewPlaylist } from "../../composables/playlists";
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: "title", title: string): void;
|
||||||
|
(e: "hideModal"): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
emit("title", "New Playlist");
|
||||||
|
|
||||||
|
function create(e: Event) {
|
||||||
|
e.preventDefault();
|
||||||
|
const name = (e.target as HTMLFormElement).elements["name"].value;
|
||||||
|
|
||||||
|
if (name.trim()) {
|
||||||
|
createNewPlaylist(name).then(() => emit("hideModal"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.new-p-form {
|
||||||
|
grid-gap: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: $gray1;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
margin: $small 0;
|
||||||
|
border: 2px solid $gray3;
|
||||||
|
background-color: transparent;
|
||||||
|
color: #fff;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="submit"] {
|
||||||
|
margin: $small 0;
|
||||||
|
background-color: $accent;
|
||||||
|
color: #fff;
|
||||||
|
width: 7rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -64,18 +64,27 @@
|
|||||||
import perks from "../../composables/perks.js";
|
import perks from "../../composables/perks.js";
|
||||||
import state from "../../composables/state";
|
import state from "../../composables/state";
|
||||||
import useContextStore from "../../stores/context";
|
import useContextStore from "../../stores/context";
|
||||||
|
import useModalStore from "../../stores/modal";
|
||||||
|
import usePlaylistStore from "../../stores/playlists";
|
||||||
|
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import trackContext from "../../contexts/track_context";
|
import trackContext from "../../contexts/track_context";
|
||||||
import { Track } from "../../interfaces.js";
|
import { Track } from "../../interfaces.js";
|
||||||
|
|
||||||
const contextStore = useContextStore();
|
const contextStore = useContextStore();
|
||||||
|
const modalStore = useModalStore();
|
||||||
|
const playlistStore = usePlaylistStore();
|
||||||
|
|
||||||
const context_on = ref(false);
|
const context_on = ref(false);
|
||||||
|
|
||||||
const showContextMenu = (e: Event) => {
|
const showContextMenu = (e: Event) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
contextStore.showContextMenu(e, trackContext(props.song));
|
contextStore.showContextMenu(
|
||||||
|
e,
|
||||||
|
trackContext(props.song, modalStore)
|
||||||
|
);
|
||||||
context_on.value = true;
|
context_on.value = true;
|
||||||
|
|
||||||
contextStore.$subscribe((mutation, state) => {
|
contextStore.$subscribe((mutation, state) => {
|
||||||
|
|||||||
@@ -1,42 +1,18 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { Folder, Track } from "../interfaces";
|
||||||
import state from "./state";
|
import state from "./state";
|
||||||
import { Track, Folder } from "../interfaces";
|
|
||||||
|
|
||||||
let base_uri = "http://127.0.0.1:9876/";
|
export default async function (path: string) {
|
||||||
|
|
||||||
const getTracksAndDirs = async (path) => {
|
|
||||||
let url;
|
|
||||||
|
|
||||||
const encoded_path = encodeURIComponent(path.replaceAll("/", "|"));
|
|
||||||
url = url = `${base_uri}/f/${encoded_path}`;
|
|
||||||
|
|
||||||
const res = await fetch(url);
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
const message = `An error has occurred: ${res.status}`;
|
|
||||||
throw new Error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = await res.json();
|
|
||||||
|
|
||||||
const songs = data.files;
|
|
||||||
const folders = data.folders;
|
|
||||||
|
|
||||||
return { songs, folders };
|
|
||||||
};
|
|
||||||
|
|
||||||
async function fetchThat(path: string) {
|
|
||||||
let tracks = Array<Track>();
|
let tracks = Array<Track>();
|
||||||
let folders = Array<Folder>();
|
let folders = Array<Folder>();
|
||||||
|
|
||||||
await axios
|
await axios
|
||||||
.post(state.settings.uri + "/folder", {
|
.post(`${state.settings.uri}/folder`, {
|
||||||
folder: path,
|
folder: path,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
tracks = res.data.tracks;
|
tracks = res.data.tracks;
|
||||||
folders = res.data.folders;
|
folders = res.data.folders;
|
||||||
console.log(tracks)
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@@ -44,5 +20,3 @@ async function fetchThat(path: string) {
|
|||||||
|
|
||||||
return { tracks, folders };
|
return { tracks, folders };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default fetchThat;
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import { Playlist } from "../interfaces";
|
||||||
|
import { Notification } from "../stores/notification";
|
||||||
|
import state from "./state";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new playlist on the server.
|
||||||
|
* @param playlist_name The name of the playlist to create.
|
||||||
|
*/
|
||||||
|
async function createNewPlaylist(playlist_name: string) {
|
||||||
|
await axios
|
||||||
|
.post(state.settings.uri + "/playlist/new", {
|
||||||
|
name: playlist_name,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
console.log(res.data);
|
||||||
|
new Notification("Playlist created!");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all playlists from the server.
|
||||||
|
* @returns {Promise<Playlist[]>} A promise that resolves to an array of playlists.
|
||||||
|
*/
|
||||||
|
async function getAllPlaylists(): Promise<Playlist[]> {
|
||||||
|
let playlists = <Playlist[]>[];
|
||||||
|
|
||||||
|
const newLocal = `${state.settings.uri}/playlists`;
|
||||||
|
|
||||||
|
await axios
|
||||||
|
.get(newLocal)
|
||||||
|
.then((res) => {
|
||||||
|
playlists = res.data.data;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
return playlists;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { createNewPlaylist, getAllPlaylists };
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
import { Track } from "../interfaces";
|
import { Track } from "../interfaces";
|
||||||
import Router from "../router";
|
import Router from "../router";
|
||||||
import { Option } from "../interfaces";
|
import { Option } from "../interfaces";
|
||||||
|
import { getAllPlaylists } from "../composables/playlists";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of context menu items for a track.
|
* Returns a list of context menu items for a track.
|
||||||
* @param {any} track a track object.
|
* @param {any} track a track object.
|
||||||
|
* @param {any} modalStore a pinia store.
|
||||||
* @return {Array<Option>()} a list of context menu items.
|
* @return {Array<Option>()} a list of context menu items.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default (track: Track): Array<Option> => {
|
export default (track: Track, modalStore: any) => {
|
||||||
const single_artist = track.artists.length === 1;
|
const single_artist = track.artists.length === 1;
|
||||||
|
|
||||||
const children = () => {
|
const goToArtist = () => {
|
||||||
if (single_artist) {
|
if (single_artist) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -24,19 +26,42 @@ export default (track: Track): Array<Option> => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const option1: Option = {
|
async function addToPlaylist() {
|
||||||
|
const p = await getAllPlaylists();
|
||||||
|
|
||||||
|
const playlists = p.map((playlist) => {
|
||||||
|
return <Option>{
|
||||||
|
label: playlist.name,
|
||||||
|
action: () => {
|
||||||
|
console.log("playlist");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const new_playlist = <Option>{
|
||||||
|
label: "New playlist",
|
||||||
|
action: () => {
|
||||||
|
modalStore.showModal(modalStore.options.newPlaylist);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log([new_playlist, ...playlists]);
|
||||||
|
return [new_playlist, ...playlists];
|
||||||
|
}
|
||||||
|
|
||||||
|
const add_to_playlist: Option = {
|
||||||
label: "Add to Playlist",
|
label: "Add to Playlist",
|
||||||
action: () => console.log("Add to Playlist"),
|
children: addToPlaylist(),
|
||||||
icon: "plus",
|
icon: "plus",
|
||||||
};
|
};
|
||||||
|
|
||||||
const option2: Option = {
|
const add_to_q: Option = {
|
||||||
label: "Add to Queue",
|
label: "Add to Queue",
|
||||||
action: () => console.log("Add to Queue"),
|
action: () => console.log("Add to Queue"),
|
||||||
icon: "add_to_queue",
|
icon: "add_to_queue",
|
||||||
};
|
};
|
||||||
|
|
||||||
const option3: Option = {
|
const go_to_folder: Option = {
|
||||||
label: "Go to Folder",
|
label: "Go to Folder",
|
||||||
action: () => {
|
action: () => {
|
||||||
Router.push({
|
Router.push({
|
||||||
@@ -47,7 +72,7 @@ export default (track: Track): Array<Option> => {
|
|||||||
icon: "folder",
|
icon: "folder",
|
||||||
};
|
};
|
||||||
|
|
||||||
const option4: Option = {
|
const go_to_artist: Option = {
|
||||||
label: single_artist ? "Go to Artist" : "Go to Artists",
|
label: single_artist ? "Go to Artist" : "Go to Artists",
|
||||||
icon: "artist",
|
icon: "artist",
|
||||||
action: () => {
|
action: () => {
|
||||||
@@ -55,16 +80,16 @@ export default (track: Track): Array<Option> => {
|
|||||||
console.log("Go to Artist");
|
console.log("Go to Artist");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
children: children(),
|
children: goToArtist(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const option7: Option = {
|
const go_to_alb_artist: Option = {
|
||||||
label: "Go to Album Artist",
|
label: "Go to Album Artist",
|
||||||
action: () => console.log("Go to Album Artist"),
|
action: () => console.log("Go to Album Artist"),
|
||||||
icon: "artist",
|
icon: "artist",
|
||||||
};
|
};
|
||||||
|
|
||||||
const option5: Option = {
|
const go_to_album: Option = {
|
||||||
label: "Go to Album",
|
label: "Go to Album",
|
||||||
action: () => {
|
action: () => {
|
||||||
Router.push({
|
Router.push({
|
||||||
@@ -75,34 +100,34 @@ export default (track: Track): Array<Option> => {
|
|||||||
icon: "album",
|
icon: "album",
|
||||||
};
|
};
|
||||||
|
|
||||||
const option6: Option = {
|
const del_track: Option = {
|
||||||
label: "Delete Track",
|
label: "Delete Track",
|
||||||
action: () => console.log("Delete Track"),
|
action: () => console.log("Delete Track"),
|
||||||
icon: "delete",
|
icon: "delete",
|
||||||
critical: true,
|
critical: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const addToFav:Option = {
|
const add_to_fav: Option = {
|
||||||
label: "I love this",
|
label: "I love this",
|
||||||
action: () => console.log("I love this"),
|
action: () => console.log("I love this"),
|
||||||
icon: "heart",
|
icon: "heart",
|
||||||
}
|
};
|
||||||
|
|
||||||
const separator: Option = {
|
const separator: Option = {
|
||||||
type: "separator",
|
type: "separator",
|
||||||
};
|
};
|
||||||
|
|
||||||
const options: Option[] = [
|
const options: Option[] = [
|
||||||
option1,
|
add_to_playlist,
|
||||||
option2,
|
add_to_q,
|
||||||
addToFav,
|
add_to_fav,
|
||||||
separator,
|
separator,
|
||||||
option3,
|
go_to_folder,
|
||||||
option4,
|
go_to_artist,
|
||||||
option7,
|
go_to_alb_artist,
|
||||||
option5,
|
go_to_album,
|
||||||
separator,
|
separator,
|
||||||
option6,
|
del_track,
|
||||||
];
|
];
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
|
|||||||
+9
-2
@@ -40,9 +40,16 @@ interface Option {
|
|||||||
type?: string;
|
type?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
action?: Function;
|
action?: Function;
|
||||||
children?: Option[] | false;
|
children?: Option[] |Promise<Option[]>| false;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
critical?: Boolean;
|
critical?: Boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Track, Folder, AlbumInfo, Artist, Option };
|
interface Playlist {
|
||||||
|
playlistid: string;
|
||||||
|
name: string;
|
||||||
|
description?: string;
|
||||||
|
image?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Track, Folder, AlbumInfo, Artist, Option, Playlist };
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
|
enum ModalOptions {
|
||||||
|
newPlaylist = "newPlaylist",
|
||||||
|
editPlaylist = "editPlaylist",
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineStore("newModal", {
|
||||||
|
state: () => ({
|
||||||
|
title: "",
|
||||||
|
options: ModalOptions,
|
||||||
|
component: "",
|
||||||
|
visible: false,
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
showModal(modalOption: string) {
|
||||||
|
this.component = modalOption;
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
hideModal() {
|
||||||
|
this.visible = false;
|
||||||
|
},
|
||||||
|
setTitle(new_title: string) {
|
||||||
|
this.title = new_title;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
|
const useNotificationStore = defineStore("notification", {
|
||||||
|
state: () => ({
|
||||||
|
text: "",
|
||||||
|
visible: false,
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
showNotification(new_text: string) {
|
||||||
|
this.text = new_text;
|
||||||
|
this.visible = true;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.visible = false;
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
class Notification {
|
||||||
|
constructor(text: string) {
|
||||||
|
useNotificationStore().showNotification(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useNotificationStore, Notification };
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
import { Playlist } from "../interfaces";
|
||||||
|
import { getAllPlaylists } from "../composables/playlists";
|
||||||
|
|
||||||
|
export default defineStore("playlists", {
|
||||||
|
state: () => ({
|
||||||
|
playlists: <Playlist[]>[],
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
fetchAll() {
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -43,7 +43,7 @@ export default {
|
|||||||
const songs = computed(() => {
|
const songs = computed(() => {
|
||||||
const songs_ = [];
|
const songs_ = [];
|
||||||
|
|
||||||
if (query.value.length > 1) {
|
if (query.value.length) {
|
||||||
for (let i = 0; i < song_list.value.length; i++) {
|
for (let i = 0; i < song_list.value.length; i++) {
|
||||||
if (
|
if (
|
||||||
song_list.value[i].title
|
song_list.value[i].title
|
||||||
@@ -63,7 +63,7 @@ export default {
|
|||||||
const folders = computed(() => {
|
const folders = computed(() => {
|
||||||
const folders_ = [];
|
const folders_ = [];
|
||||||
|
|
||||||
if (query.value.length > 1) {
|
if (query.value.length) {
|
||||||
for (let i = 0; i < folders_list.value.length; i++) {
|
for (let i = 0; i < folders_list.value.length; i++) {
|
||||||
if (
|
if (
|
||||||
folders_list.value[i].name
|
folders_list.value[i].name
|
||||||
@@ -110,6 +110,7 @@ export default {
|
|||||||
if (!path.value) return;
|
if (!path.value) return;
|
||||||
|
|
||||||
getDirData(path.value);
|
getDirData(path.value);
|
||||||
|
console.log(path.value);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user