🔷 refactor context menu to accept context src

🔷 add a getCurrentDate function to get formatted date
This commit is contained in:
geoffrey45 2022-04-08 21:07:24 +03:00
parent 24db32ae09
commit 83330a7fad
13 changed files with 107 additions and 44 deletions

View File

@ -1,63 +1,36 @@
# Fixes !
- [ ] Use click event to play song instead of url ⚠
- [ ] Show play/pause button correctly according to state ⚠
- [ ] Click on artist image to go to artist page ⚠
- [ ] Play next song if current song can't be loaded ⚠
- [ ] List item song icon for long song titles ⚠
<!-- -->
- [ ] Broken CSS
- [ ] Prevent scanning unchanged folders
- [ ] Handle '/' and '&' characters in song artists
- [ ] Nginx not serving all files in a folder
- [ ] Removing song duplicates from queries
- [ ] Different songs having same link
- [ ] ConnectionError
- [ ] Move thumbnails to .config
- [ ] Write a multithreaded file server
- [ ] Add support for WAV files
- [ ] Support multiple folders
- [ ] Compress thumbnails
# Features +
## Needed features
- [ ] Seeking current song
- [ ] Adding songs to queue
- [ ] Implement search on frontend
<!-- -->
- [ ] Watching for changes in folders and updating them instantly ⚠
- [ ] Display folders and files in a tree view. ⚠ 🔵
<!-- -->
- [ ] Add favicon
- [ ] Add keyboard shortcuts
- [ ] Right click on song to do stuff
- [ ] Adjust volume
- [ ] Add listening statistics for all songs
- [ ] Extract color from artist image [for use with artist card gradient]
- [ ] Adding songs to favorites
- [ ] Adding songs to playlist
- [ ] Playing song radio
## Future features
- [ ] Toggle shuffle
- [ ] Toggle repeat
- [ ] Display artist albums
- [ ] Suggest similar artists
- [ ] Getting artist info
- [ ] Getting album info
- [ ] Create a Python script to build, bundle and serve the app
- [ ] Getting extra song info (probably from genius)
- [ ] Getting lyrics
- [ ] Notifications
- [ ] Sorting songs
- [ ] Suggest undiscorvered artists, albums and songs
- [ ] Remember last played song
- [ ] Add next and previous song transition and progress bar reset animations
- [ ] Hover animations for list items
- [ ] Highlight currently playing song in playlist
- [ ] Add playlist to folder
- [ ] Add functionality to 'Listen now' button
- [ ] Add a 'Scan' button to the sidebar
- [ ] Paginated requests for songs
- [ ] Package app as installable PWA
## Finished ✅

View File

@ -25,7 +25,6 @@
<div class="text">Nothing down here 😑</div>
</div>
</div>
<div v-else ref="songtitle"></div>
</div>
</template>

View File

@ -12,6 +12,7 @@
<div class="info">
<div class="btns">
<PlayBtnRect :source="playSources.playlist" />
<Option @showDropdown="showDropdown" :src="context.src" />
</div>
<div class="duration">
<span v-if="props.info.count == 0">No Tracks</span>
@ -37,11 +38,15 @@
</template>
<script setup lang="ts">
import { playSources } from "../../composables/enums";
import { playSources, ContextSrc } from "../../composables/enums";
import { Playlist } from "../../interfaces";
import PlayBtnRect from "../shared/PlayBtnRect.vue";
import useModalStore from "../../stores/modal";
import Option from "../shared/Option.vue";
import pContext from "../../contexts/playlist";
import useContextStore from "../../stores/context";
const context = useContextStore();
const modal = useModalStore();
const props = defineProps<{
@ -51,6 +56,10 @@ const props = defineProps<{
function editPlaylist() {
modal.showEditPlaylistModal(props.info);
}
function showDropdown(e: any) {
context.showContextMenu(e, pContext(), ContextSrc.PHeader);
}
</script>
<style lang="scss">
@ -63,6 +72,7 @@ function editPlaylist() {
border-radius: 0.75rem;
color: $white;
background-color: transparent;
z-index: 0;
.gradient {
position: absolute;
@ -160,6 +170,8 @@ function editPlaylist() {
.btns {
margin-top: $small;
display: flex;
gap: $small;
}
}
}

View File

@ -12,6 +12,7 @@
'context-many-kids': context.hasManyChildren(),
},
]"
id="context-menu"
:style="{
left: context.x + 'px',
top: context.y + 'px',
@ -56,7 +57,6 @@ const context = useContextStore();
top: 0;
left: 0;
width: 12rem;
height: min-content;
z-index: 10;
transform: scale(0);

View File

@ -67,6 +67,7 @@
import perks from "../../composables/perks.js";
import useContextStore from "../../stores/context";
import useModalStore from "../../stores/modal";
import { ContextSrc } from "../../composables/enums";
import { ref } from "vue";
import trackContext from "../../contexts/track_context";
@ -80,7 +81,9 @@ const showContextMenu = (e: Event) => {
e.preventDefault();
e.stopPropagation();
contextStore.showContextMenu(e, trackContext(props.song, modalStore));
const menus = trackContext(props.song, modalStore);
contextStore.showContextMenu(e, menus, ContextSrc.Track);
context_on.value = true;
contextStore.$subscribe((mutation, state) => {

View File

@ -39,6 +39,7 @@ import { ref } from "vue";
import perks from "../../composables/perks";
import trackContext from "../../contexts/track_context";
import { Track } from "../../interfaces";
import { ContextSrc } from "../../composables/enums";
import useContextStore from "../../stores/context";
import useModalStore from "../../stores/modal";
@ -58,7 +59,9 @@ const showContextMenu = (e: Event) => {
e.preventDefault();
e.stopPropagation();
contextStore.showContextMenu(e, trackContext(props.track, modalStore));
const menus = trackContext(props.track, modalStore);
contextStore.showContextMenu(e, menus, ContextSrc.Track);
context_on.value = true;
contextStore.$subscribe((mutation, state) => {

View File

@ -17,3 +17,9 @@ export enum FromOptions {
album = "album",
search = "search",
}
export enum ContextSrc {
PHeader = "PHeader",
Track = "Track",
AHeader = "AHeader",
}

View File

@ -150,9 +150,24 @@ function formatSeconds(seconds) {
}
}
export function getCurrentDate(){
const date = new Date();
const yyyy = date.getFullYear();
const mm = date.getMonth() + 1;
const dd = date.getDate();
const hh = date.getHours();
const min = date.getMinutes();
const sec = date.getSeconds();
return `${yyyy}-${mm}-${dd} ${hh}:${min}:${sec}`;
}
export default {
putCommas,
focusCurrent,
formatSeconds,
getElem,
getCurrentDate
};

View File

@ -2,7 +2,7 @@ import axios from "axios";
import { Playlist, Track } from "../interfaces";
import { Notification, NotifType } from "../stores/notification";
import state from "./state";
import { getCurrentDate } from "../composables/perks";
/**
* Creates a new playlist on the server.
* @param playlist_name The name of the playlist to create.
@ -13,6 +13,7 @@ async function createNewPlaylist(playlist_name: string, track?: Track) {
await axios
.post(state.settings.uri + "/playlist/new", {
name: playlist_name,
lastUpdated: getCurrentDate(),
})
.then((res) => {
new Notification("✅ Playlist created successfullly!");

28
src/contexts/playlist.ts Normal file
View File

@ -0,0 +1,28 @@
import { Option } from "../interfaces";
export default async () => {
const deletePlaylist: Option = {
label: "Delete playlist",
critical: true,
action: () => {
console.log("delete playlist");
},
};
const playNext: Option = {
label: "Play next",
action: () => {
console.log("play next");
},
};
const addToQueue: Option = {
label: "Add to queue",
action: () => {
console.log("add to queue");
},
};
return [playNext, addToQueue, deletePlaylist];
};

View File

@ -1,23 +1,30 @@
import { defineStore } from "pinia";
import normalize from "../composables/normalizeContextMenu";
import { Option } from "../interfaces";
import { ContextSrc } from "../composables/enums";
export default defineStore("context-menu", {
state: () => ({
visible: false,
options: Array<Option>(),
options: <Option[]>[],
x: 500,
y: 500,
normalizedX: false,
normalizedY: false,
src: "",
}),
actions: {
showContextMenu(e: any, context_options: Promise<Option[]>) {
showContextMenu(
e: any,
context_options: Promise<Option[]>,
src: ContextSrc
) {
if (this.visible) {
this.visible = false;
return;
}
this.visible = true;
context_options.then((options) => {
this.options = options;
});
@ -29,11 +36,11 @@ export default defineStore("context-menu", {
this.normalizedX = yo.normalizedX;
this.normalizedY = yo.normalizedY;
this.visible = true;
this.src = src;
},
hideContextMenu() {
this.visible = false;
this.src = null;
},
hasManyChildren() {
let result = false;

View File

@ -4,11 +4,23 @@
<div class="separator no-border"></div>
<div class="songlist rounded">
<SongList
:tracks="playlist.tracks"
:pname="playlist.info.name"
:playlistid="playlist.info.playlistid"
/>
<div v-if="playlist.tracks.length">
<SongList
:tracks="playlist.tracks"
:pname="playlist.info.name"
:playlistid="playlist.info.playlistid"
/>
</div>
<div v-else-if="playlist.tracks.length === 0 && playlist.info.count > 0">
<div class="no-results">
<div class="text">We can't find your music 🦋</div>
</div>
</div>
<div v-else-if="playlist.tracks.length === 0 && playlist.info.count == 0">
<div class="no-results">
<div class="text">Nothing here</div>
</div>
</div>
</div>
<div class="separator no-border"></div>
<FeaturedArtists />

View File

@ -1,6 +1,7 @@
<template>
<div id="p-view">
<div class="grid">
<NewPlaylistCard />
<PlaylistCard
v-for="p in pStore.playlists"
:key="p.playlistid"
@ -14,6 +15,7 @@
import PlaylistCard from "../components/playlists/PlaylistCard.vue";
import usePStore from "../stores/playlists";
import NewPlaylistCard from "../components/playlists/NewPlaylistCard.vue";
const pStore = usePStore();
</script>
@ -22,10 +24,12 @@ const pStore = usePStore();
margin: $small;
padding: $small;
overflow: auto;
scrollbar-color: $gray2 transparent;
border-top: 1px solid $gray3;
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
gap: $small;
}
}