diff --git a/src/App.vue b/src/App.vue index 67da788f..cdc0ce17 100644 --- a/src/App.vue +++ b/src/App.vue @@ -47,7 +47,7 @@ const queue = useQStore(); const router = useRouter(); const modal = useModalStore(); const context_store = useContextStore(); -const app_dom = document.getElementById("app"); +const app_dom = document.getElementById("app") as HTMLElement; queue.readQueue(); handleShortcuts(useQStore); @@ -59,7 +59,7 @@ app_dom.addEventListener("click", (e) => { }); router.afterEach(() => { - document.getElementById("acontent")?.scrollTo(0, 0); + (document.getElementById("acontent") as HTMLElement).scrollTo(0, 0); }); onStartTyping(() => { diff --git a/src/components/FolderView/SongList.vue b/src/components/FolderView/SongList.vue index 1781b6ca..1563c7d3 100644 --- a/src/components/FolderView/SongList.vue +++ b/src/components/FolderView/SongList.vue @@ -19,7 +19,7 @@ @updateQueue="updateQueue" :isPlaying="queue.playing" :isCurrent="queue.currentid == track.trackid" - :isHighlighted="($route.query.highlight as string) == track.uniq_hash" + :isHighlighted="($route.query.highlight as string) == track.hash" /> @@ -39,12 +39,12 @@ import { onBeforeRouteUpdate, useRoute } from "vue-router"; import SongItem from "../shared/SongItem.vue"; +import { Routes } from "@/composables/enums"; +import { Track } from "@/interfaces"; +import useAlbumStore from "@/stores/pages/album"; +import useQStore from "@/stores/queue"; import { focusElem } from "@/utils"; import { onMounted, onUpdated, ref } from "vue"; -import { Track } from "@/interfaces"; -import useQStore from "@/stores/queue"; -import useAlbumStore from "@/stores/pages/album"; -import { Routes } from "@/composables/enums"; const queue = useQStore(); const album = useAlbumStore(); diff --git a/src/components/LeftSidebar/NP/SongCard.vue b/src/components/LeftSidebar/NP/SongCard.vue index 316e0345..b6e75bdb 100644 --- a/src/components/LeftSidebar/NP/SongCard.vue +++ b/src/components/LeftSidebar/NP/SongCard.vue @@ -6,13 +6,13 @@ :to="{ name: 'AlbumView', params: { - hash: track.albumhash, + hash: track?.albumhash ? track.albumhash : ' ', }, }" >
-
+
MASTER FLAC MP3 • {{ track.bitrate }}
-
{{ props.track.title }}
+
{{ props.track?.title }}
-
- {{ artist }} +
+ {{ + artist + }} +
+
+ {{ track.albumartist }}
- {{ props.track.albumartist }} + Meh
@@ -50,6 +54,6 @@ import { Track } from "../../../interfaces"; const imguri = paths.images.thumb; const props = defineProps<{ - track: Track; + track: Track | null; }>(); diff --git a/src/components/RightSideBar/Queue.vue b/src/components/RightSideBar/Queue.vue index 4dbce0e0..34989382 100644 --- a/src/components/RightSideBar/Queue.vue +++ b/src/components/RightSideBar/Queue.vue @@ -17,6 +17,8 @@ @playThis="queue.play(index)" :isCurrent="index === queue.current" :isPlaying="queue.playing" + :isQueueTrack="true" + :index="index" />
@@ -88,7 +90,6 @@ onUpdated(() => { grid-template-rows: max-content 1fr max-content; gap: $small; - .scrollable-r { height: 100%; overflow: hidden; diff --git a/src/components/RightSideBar/Queue/upNext.vue b/src/components/RightSideBar/Queue/upNext.vue index e27ea3e6..c38ad95a 100644 --- a/src/components/RightSideBar/Queue/upNext.vue +++ b/src/components/RightSideBar/Queue/upNext.vue @@ -6,14 +6,15 @@ @contextmenu.prevent="showMenu" >
next up
- +
-
{{ track.title }}
-
+
{{ track?.title || "Don't click here" }}
+
{{ artist }}
+ nothing will happen
@@ -27,14 +28,16 @@ import { showTrackContextMenu as showContext } from "@/composables/context"; import { ref } from "vue"; const props = defineProps<{ - track: Track; + track: Track | null; playNext: () => void; }>(); const context_on = ref(false); function showMenu(e: Event) { - showContext(e, props.track, context_on); + if (props.track) { + showContext(e, props.track, context_on); + } } diff --git a/src/components/shared/SongItem.vue b/src/components/shared/SongItem.vue index ac90fac6..00071dac 100644 --- a/src/components/shared/SongItem.vue +++ b/src/components/shared/SongItem.vue @@ -8,7 +8,7 @@ highlighted: isHighlighted, }, ]" - v-bind:class="`track-${track.uniq_hash}`" + v-bind:class="`track-${track.hash}`" @dblclick="emitUpdate(track)" @contextmenu.prevent="showMenu" > @@ -75,10 +75,10 @@ import { ref } from "vue"; import OptionSvg from "@/assets/icons/more.svg"; +import { showTrackContextMenu as showContext } from "@/composables/context"; import { paths } from "@/config"; import { Track } from "@/interfaces"; import { formatSeconds, putCommas } from "@/utils"; -import { showTrackContextMenu as showContext } from "@/composables/context"; const context_on = ref(false); const imguri = paths.images.thumb; diff --git a/src/components/shared/TrackItem.vue b/src/components/shared/TrackItem.vue index 483061ca..d2897a36 100644 --- a/src/components/shared/TrackItem.vue +++ b/src/components/shared/TrackItem.vue @@ -1,10 +1,10 @@ @@ -39,13 +51,18 @@ import { paths } from "@/config"; import { putCommas } from "@/utils"; import { Track } from "@/interfaces"; import { showTrackContextMenu as showContext } from "@/composables/context"; +import DelSvg from "@/assets/icons/plus.svg"; +import useQueueStore from "@/stores/queue"; const props = defineProps<{ track: Track; isCurrent: boolean; isPlaying: boolean; + isQueueTrack?: boolean; + index?: number; }>(); +const queue = useQueueStore(); const context_on = ref(false); function showMenu(e: Event) { @@ -73,11 +90,26 @@ const playThis = (track: Track) => { .track-item { display: grid; - grid-template-columns: min-content 1fr; + grid-template-columns: min-content 1fr max-content; align-items: center; padding: $small 1rem; + .remove-track { + opacity: 0; + transition: all 0.25s ease; + transform: translateX(1rem) rotate(45deg); + + &:hover { + opacity: 1 !important; + } + } + &:hover { + .remove-track { + opacity: 0.5; + transform: translateX(0) rotate(45deg); + } + cursor: pointer; background: linear-gradient(37deg, $gray4, $gray3, $gray3); } @@ -87,10 +119,6 @@ const playThis = (track: Track) => { margin: 0.1rem; } - // .tags { - // border: solid 1px; - // } - .album-art { display: flex; align-items: center; diff --git a/src/contexts/track_context.ts b/src/contexts/track_context.ts index 3d1fb139..7bb59e60 100644 --- a/src/contexts/track_context.ts +++ b/src/contexts/track_context.ts @@ -1,13 +1,15 @@ import { Playlist, Track } from "../interfaces"; -import Router from "../router"; + +// @ts-ignore import { Option } from "../interfaces"; +import Router from "../router"; + import { - getAllPlaylists, - addTrackToPlaylist, + addTrackToPlaylist, getAllPlaylists } from "../composables/fetch/playlists"; -import useQueueStore from "../stores/queue"; import useModalStore from "../stores/modal"; +import useQueueStore from "../stores/queue"; /** * Returns a list of context menu items for a track. * @param {any} track a track object. @@ -90,7 +92,7 @@ export default async ( Router.push({ name: "FolderView", params: { path: track.folder }, - query: { highlight: track.uniq_hash }, + query: { highlight: track.hash }, }); }, icon: "folder", diff --git a/src/interfaces.ts b/src/interfaces.ts index 41e80750..de262240 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -16,7 +16,7 @@ export interface Track { tracknumber?: number; discnumber?: number; index?: number; - uniq_hash: string; + hash: string; copyright?: string; } @@ -62,12 +62,12 @@ export interface Playlist { playlistid: string; name: string; description?: string; - image?: string | FormData; - tracks?: Track[]; - count?: number; - lastUpdated?: string; - thumb?: string; - duration?: number; + image: string | FormData; + tracks: Track[]; + count: number; + lastUpdated: string; + thumb: string; + duration: number; } export interface Notif { diff --git a/src/layouts/HeaderContentBottom.vue b/src/layouts/HeaderContentBottom.vue index 58c0992c..793b79d4 100644 --- a/src/layouts/HeaderContentBottom.vue +++ b/src/layouts/HeaderContentBottom.vue @@ -40,7 +40,7 @@ const props = defineProps<{ /** * Called when the bottom container is raised. */ - bottomRaisedCallback?: (routeparams?: RouteParams) => void; + bottomRaisedCallback?: (routeparams: RouteParams) => void; }>(); let elem: HTMLElement; diff --git a/src/stores/context.ts b/src/stores/context.ts index fcc52bbc..5daded50 100644 --- a/src/stores/context.ts +++ b/src/stores/context.ts @@ -53,6 +53,7 @@ export default defineStore("context-menu", { hideContextMenu() { this.visible = false; this.src = null; + this.options = []; }, hasManyChildren() { let result = false; diff --git a/src/stores/pages/playlist.ts b/src/stores/pages/playlist.ts index f6e4fcc9..47d83789 100644 --- a/src/stores/pages/playlist.ts +++ b/src/stores/pages/playlist.ts @@ -20,8 +20,8 @@ export default defineStore("playlist-tracks", { async fetchAll(playlistid: string) { const playlist = await getPlaylist(playlistid); - this.info = playlist.info; - this.tracks = playlist.tracks; + this.info = playlist?.info || ({} as Playlist); + this.tracks = playlist?.tracks || []; }, async fetchArtists(playlistid: string) { @@ -35,5 +35,8 @@ export default defineStore("playlist-tracks", { updatePInfo(info: Playlist) { this.info = info; }, + resetArtists() { + this.artists = []; + }, }, }); diff --git a/src/stores/queue.ts b/src/stores/queue.ts index d44d1758..46f28328 100644 --- a/src/stores/queue.ts +++ b/src/stores/queue.ts @@ -35,14 +35,6 @@ function readCurrent(): number { return 0; } -const defaultTrack = { - title: "Nothing played yet", - albumhash: " ", - artists: ["Alice"], - trackid: "", - image: "meh", -}; - function shuffle(tracks: Track[]) { const shuffled = tracks.slice(); for (let i = shuffled.length - 1; i > 0; i--) { @@ -70,18 +62,19 @@ export default defineStore("Queue", { current: 0, next: 0, prev: 0, - currentid: "", + currentid: "", playing: false, from: {} as From, currenttrack: {} as Track, - tracklist: [defaultTrack] as Track[], + tracklist: [] as Track[], }), actions: { play(index: number = 0) { + if (this.tracklist.length === 0) return; this.current = index; const track = this.tracklist[index]; this.currentid = track.trackid; - const uri = state.settings.uri + "/file/" + track.trackid; + const uri = state.settings.uri + "/file/" + track.hash; const elem = document.getElementById("progress") as HTMLElement; this.updateCurrent(index); @@ -178,8 +171,8 @@ export default defineStore("Queue", { this.currenttrack = track; this.current = index; - this.currentid = track.trackid; - this.duration.full = track.length || 0; + this.currentid = track?.trackid || null; + this.duration.full = track?.length || 0; }, setNewQueue(tracklist: Track[]) { if (this.tracklist !== tracklist) { @@ -256,15 +249,13 @@ export default defineStore("Queue", { writeQueue(this.from, this.tracklist); }, clearQueue() { - this.tracklist = [defaultTrack] as Track[]; - this.current = 0; + this.tracklist = [] as Track[]; this.currentid = ""; - this.next = 0; - this.prev = 0; + this.current, this.next, (this.prev = 0); this.from = {}; - writeQueue(this.from, [defaultTrack] as Track[]); writeCurrent(0); + writeQueue(this.from, [] as Track[]); }, shuffleQueue() { const Toast = useNotifStore(); @@ -286,5 +277,8 @@ export default defineStore("Queue", { writeQueue(this.from, shuffled); writeCurrent(0); }, + removeFromQueue(index: number = 0) { + this.tracklist.splice(index, 1); + }, }, }); diff --git a/src/views/album/Bottom.vue b/src/views/album/Bottom.vue index 82ba0d7a..ac9d4113 100644 --- a/src/views/album/Bottom.vue +++ b/src/views/album/Bottom.vue @@ -2,7 +2,10 @@
- +
diff --git a/src/views/album/index.vue b/src/views/album/index.vue index a02dff44..02752a5f 100644 --- a/src/views/album/index.vue +++ b/src/views/album/index.vue @@ -10,7 +10,7 @@ diff --git a/src/views/playlist/index.vue b/src/views/playlist/index.vue index c20b29f3..e64561b4 100644 --- a/src/views/playlist/index.vue +++ b/src/views/playlist/index.vue @@ -6,7 +6,7 @@