mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-07-29 14:12:21 +00:00
update interfaces to use the updated property names
+ misc changes related to moving to sqlite
This commit is contained in:
parent
881adc0f88
commit
f3c4f0310a
@ -5,23 +5,27 @@
|
|||||||
:style="{
|
:style="{
|
||||||
backgroundImage: album.colors
|
backgroundImage: album.colors
|
||||||
? `linear-gradient(
|
? `linear-gradient(
|
||||||
37deg, ${album.colors[0]}, ${album.colors[3]}
|
37deg, ${album.colors[2]}, ${album.colors[2]}
|
||||||
)`
|
)`
|
||||||
: '',
|
: '',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="big-img no-scroll" :class="{ imgSmall: albumHeaderSmall }">
|
<div
|
||||||
<img :src="imguri.thumb.large + album.image" class="rounded" />
|
class="big-img no-scroll"
|
||||||
|
:class="`${albumHeaderSmall ? 'imgSmall' : ''} shadow-lg rounded-sm`"
|
||||||
|
>
|
||||||
|
<img :src="imguri.thumb.large + album.image" class="rounded-sm" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="info"
|
class="info"
|
||||||
:class="{ nocontrast: album.colors ? isLight(album.colors[0]) : false }"
|
:class="{ nocontrast: album.colors ? isLight(album.colors[2]) : false }"
|
||||||
>
|
>
|
||||||
<div class="album-info">
|
<div class="album-info">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div v-auto-animate class="h">
|
<div v-auto-animate class="h">
|
||||||
<span v-if="album.is_soundtrack">Soundtrack</span>
|
<span v-if="album.is_soundtrack">Soundtrack</span>
|
||||||
<span v-else-if="album.is_compilation">Compilation</span>
|
<span v-else-if="album.is_compilation">Compilation</span>
|
||||||
|
<span v-else-if="album.is_EP">EP</span>
|
||||||
<span v-else-if="album.is_single">Single</span>
|
<span v-else-if="album.is_single">Single</span>
|
||||||
<span v-else>Album</span>
|
<span v-else>Album</span>
|
||||||
</div>
|
</div>
|
||||||
@ -32,7 +36,7 @@
|
|||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<div class="stats ellip">
|
<div class="stats ellip">
|
||||||
<div class="border rounded-sm pad-sm">
|
<div class="border rounded-sm pad-sm">
|
||||||
{{ album.artist }} • {{ album.date }} • {{ album.count }}
|
{{ album.albumartist }} • {{ album.date }} • {{ album.count }}
|
||||||
{{ album.count === 1 ? "Track" : "Tracks" }} •
|
{{ album.count === 1 ? "Track" : "Tracks" }} •
|
||||||
{{ formatSeconds(album.duration, true) }}
|
{{ formatSeconds(album.duration, true) }}
|
||||||
</div>
|
</div>
|
||||||
@ -40,7 +44,6 @@
|
|||||||
<PlayBtnRect
|
<PlayBtnRect
|
||||||
:source="playSources.album"
|
:source="playSources.album"
|
||||||
:store="useAlbumStore"
|
:store="useAlbumStore"
|
||||||
:background="getButtonColor(album.colors)"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -99,6 +102,7 @@ useVisibility(albumheaderthing, handleVisibilityState);
|
|||||||
height: $banner-height;
|
height: $banner-height;
|
||||||
background-color: $black;
|
background-color: $black;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
.big-img {
|
.big-img {
|
||||||
height: calc(100%);
|
height: calc(100%);
|
||||||
@ -114,6 +118,7 @@ useVisibility(albumheaderthing, handleVisibilityState);
|
|||||||
|
|
||||||
.big-img.imgSmall {
|
.big-img.imgSmall {
|
||||||
width: 12rem;
|
width: 12rem;
|
||||||
|
height: 12rem;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 12rem;
|
height: 12rem;
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<div class="play"></div>
|
<div class="play"></div>
|
||||||
<div class="album-art image rounded"></div>
|
<div class="album-art image rounded"></div>
|
||||||
<div class="name ellip">{{ album.title }}</div>
|
<div class="name ellip">{{ album.title }}</div>
|
||||||
<div class="artist ellip">{{ album.artist }}</div>
|
<div class="artist ellip">{{ album.albumartist }}</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<div class="image rounded"></div>
|
<div class="image rounded"></div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name ellip">{{ album.title }}</div>
|
<div class="name ellip">{{ album.title }}</div>
|
||||||
<div class="artist ellip">{{ album.artist }}</div>
|
<div class="artist ellip">{{ album.albumartist }}</div>
|
||||||
<div class="separator"></div>
|
<div class="separator"></div>
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="play-icon"></div>
|
<div class="play-icon"></div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div
|
<div
|
||||||
v-show="context.visible"
|
v-show="context.visible"
|
||||||
class="context-menu rounded shadow-lg no-select"
|
class="context-menu rounded shadow-lg no-select"
|
||||||
ref="contextMenu"
|
ref="contextMenuRef"
|
||||||
id="context-menu"
|
id="context-menu"
|
||||||
>
|
>
|
||||||
<ContextItem
|
<ContextItem
|
||||||
@ -21,31 +21,72 @@
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { onClickOutside } from "@vueuse/core";
|
import { onClickOutside } from "@vueuse/core";
|
||||||
|
|
||||||
import useContextStore from "../stores/context";
|
import useContextStore from "@/stores/context";
|
||||||
import useSettingsStore from "../stores/settings";
|
import useSettingsStore from "@/stores/settings";
|
||||||
|
|
||||||
import ContextItem from "./Contextmenu/ContextItem.vue";
|
import ContextItem from "./Contextmenu/ContextItem.vue";
|
||||||
|
|
||||||
const context = useContextStore();
|
const context = useContextStore();
|
||||||
const settings = useSettingsStore();
|
const settings = useSettingsStore();
|
||||||
const contextMenu = ref<HTMLElement>();
|
const contextMenuRef = ref<HTMLElement>();
|
||||||
|
|
||||||
let clickCount = 0;
|
// let clickCount = 0;
|
||||||
|
|
||||||
onClickOutside(contextMenu, (e) => {
|
// onClickOutside(
|
||||||
if (!context.visible) {
|
// contextMenuRef,
|
||||||
clickCount = 0;
|
// (e) => {
|
||||||
|
// console.log(clickCount);
|
||||||
|
|
||||||
|
// if (!context.visible) {
|
||||||
|
// // clickCount = 0;
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// clickCount++;
|
||||||
|
|
||||||
|
// if (context.visible && clickCount === 1) {
|
||||||
|
// context.hideContextMenu();
|
||||||
|
// e.stopImmediatePropagation();
|
||||||
|
// clickCount = 0;
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// capture: false,
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
let watcher: any = null;
|
||||||
|
|
||||||
|
context.$subscribe((mutation, state) => {
|
||||||
|
// let watchers = [];
|
||||||
|
// console.log("watchers count: " + watchers.length)
|
||||||
|
// let wat: any = () => {};
|
||||||
|
|
||||||
|
if (state.visible) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (watcher !== null) {
|
||||||
|
watcher();
|
||||||
|
}
|
||||||
|
watcher = onClickOutside(
|
||||||
|
contextMenuRef,
|
||||||
|
(e) => {
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
console.log("clicked outside ref");
|
||||||
|
context.hideContextMenu();
|
||||||
|
},
|
||||||
|
{
|
||||||
|
capture: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, 200);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
clickCount++;
|
|
||||||
|
|
||||||
if (context.visible && clickCount == 2) {
|
if (watcher !== null) {
|
||||||
context.hideContextMenu();
|
watcher();
|
||||||
e.stopImmediatePropagation();
|
|
||||||
clickCount = 0;
|
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
capture: false
|
// wat();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -98,7 +98,6 @@ function hideContextMenu() {
|
|||||||
function runAction() {
|
function runAction() {
|
||||||
if (props.option.children) {
|
if (props.option.children) {
|
||||||
if (childrenShown.value) {
|
if (childrenShown.value) {
|
||||||
console.log("what");
|
|
||||||
hideChildren();
|
hideChildren();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<div class="songlist">
|
<div class="songlist">
|
||||||
<SongItem
|
<SongItem
|
||||||
v-for="(track, index) in tracks"
|
v-for="(track, index) in tracks"
|
||||||
:key="track.trackid"
|
:key="track.id"
|
||||||
:track="track"
|
:track="track"
|
||||||
:index="
|
:index="
|
||||||
on_album_page
|
on_album_page
|
||||||
@ -28,7 +28,7 @@
|
|||||||
"
|
"
|
||||||
@playThis="updateQueue(track.index !== undefined ? track.index : index)"
|
@playThis="updateQueue(track.index !== undefined ? track.index : index)"
|
||||||
:isCurrentPlaying="queue.playing"
|
:isCurrentPlaying="queue.playing"
|
||||||
:isCurrent="queue.currentid == track.trackid"
|
:isCurrent="queue.currentid == track.id"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="copyright" v-if="copyright && copyright">
|
<div class="copyright" v-if="copyright && copyright">
|
||||||
@ -59,7 +59,7 @@ const props = defineProps<{
|
|||||||
tracks: Track[];
|
tracks: Track[];
|
||||||
path?: string;
|
path?: string;
|
||||||
pname?: string;
|
pname?: string;
|
||||||
playlistid?: string;
|
id?: string;
|
||||||
on_album_page?: boolean;
|
on_album_page?: boolean;
|
||||||
disc?: string | number;
|
disc?: string | number;
|
||||||
copyright?: string | null;
|
copyright?: string | null;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
:to="{
|
:to="{
|
||||||
name: 'PlaylistView',
|
name: 'PlaylistView',
|
||||||
params: {
|
params: {
|
||||||
pid: p.playlistid,
|
pid: p.id,
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="last-updated" :class="{ lightbg: !info.image }">
|
<div class="last-updated" :class="{ lightbg: !info.image }">
|
||||||
<span class="status"
|
<span class="status"
|
||||||
>Last updated {{ info.lastUpdated }}  |  </span
|
>Last updated {{ info.last_updated }}  |  </span
|
||||||
>
|
>
|
||||||
<span class="edit" @click="editPlaylist">Edit</span>
|
<span class="edit" @click="editPlaylist">Edit</span>
|
||||||
</div>
|
</div>
|
||||||
@ -43,23 +43,23 @@ import useModalStore from "../../stores/modal";
|
|||||||
import { playSources } from "@/composables/enums";
|
import { playSources } from "@/composables/enums";
|
||||||
import { formatSeconds, useVisibility } from "@/utils";
|
import { formatSeconds, useVisibility } from "@/utils";
|
||||||
import { paths } from "../../config";
|
import { paths } from "../../config";
|
||||||
import { Playlist } from "../../interfaces";
|
|
||||||
|
|
||||||
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
import PlayBtnRect from "../shared/PlayBtnRect.vue";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
|
||||||
const imguri = paths.images.playlist;
|
|
||||||
const modal = useModalStore();
|
const modal = useModalStore();
|
||||||
const nav = useNavStore();
|
const nav = useNavStore();
|
||||||
|
const playlist = usePStore();
|
||||||
|
|
||||||
|
const imguri = paths.images.playlist;
|
||||||
|
|
||||||
const playlistheader = ref<HTMLElement | null>(null);
|
const playlistheader = ref<HTMLElement | null>(null);
|
||||||
|
const { info } = storeToRefs(playlist);
|
||||||
|
|
||||||
useVisibility(playlistheader, nav.toggleShowPlay);
|
useVisibility(playlistheader, nav.toggleShowPlay);
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
info: Playlist;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
function editPlaylist() {
|
function editPlaylist() {
|
||||||
modal.showEditPlaylistModal(props.info);
|
modal.showEditPlaylistModal(info.value);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<router-link
|
<router-link
|
||||||
:to="{ name: 'PlaylistView', params: { pid: playlist.playlistid } }"
|
:to="{ name: 'PlaylistView', params: { pid: playlist.id } }"
|
||||||
class="p-card rounded no-scroll"
|
class="p-card rounded no-scroll"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<div class="grid">
|
<div class="grid">
|
||||||
<PCard
|
<PCard
|
||||||
v-for="album in search.albums.value"
|
v-for="album in search.albums.value"
|
||||||
:key="`${album.artist}-${album.title}`"
|
:key="`${album.albumartist}-${album.title}`"
|
||||||
:album="album"
|
:album="album"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
<div v-if="search.tracks.value.length">
|
<div v-if="search.tracks.value.length">
|
||||||
<TrackComponent
|
<TrackComponent
|
||||||
v-for="(track, index) in search.tracks.value"
|
v-for="(track, index) in search.tracks.value"
|
||||||
:key="track.trackid"
|
:key="track.id"
|
||||||
:isCurrent="queue.currentid === track.trackid"
|
:isCurrent="queue.currentid === track.id"
|
||||||
:isHighlighted="false"
|
:isHighlighted="false"
|
||||||
:isCurrentPlaying="queue.currentid === track.trackid && queue.playing"
|
:isCurrentPlaying="queue.currentid === track.id && queue.playing"
|
||||||
:track="track"
|
:track="track"
|
||||||
@playThis="updateQueue(index)"
|
@playThis="updateQueue(index)"
|
||||||
:index="index + 1"
|
:index="index + 1"
|
||||||
|
@ -55,7 +55,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.welcome-to-alice {
|
.welcome-to-alice {
|
||||||
p {
|
p {
|
||||||
|
@ -45,10 +45,10 @@
|
|||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
// import { useDropZone } from "@vueuse/core";
|
// import { useDropZone } from "@vueuse/core";
|
||||||
|
|
||||||
|
import { updatePlaylist } from "@/composables/fetch/playlists";
|
||||||
import { paths } from "@/config";
|
import { paths } from "@/config";
|
||||||
import { Playlist } from "@/interfaces";
|
import { Playlist } from "@/interfaces";
|
||||||
import usePStore from "@/stores/pages/playlist";
|
import usePStore from "@/stores/pages/playlist";
|
||||||
import { updatePlaylist } from "@/composables/fetch/playlists";
|
|
||||||
|
|
||||||
const pStore = usePStore();
|
const pStore = usePStore();
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ function update_playlist(e: Event) {
|
|||||||
formData.append("image", image);
|
formData.append("image", image);
|
||||||
|
|
||||||
if (name && name.toString().trim() !== "") {
|
if (name && name.toString().trim() !== "") {
|
||||||
updatePlaylist(props.playlist.playlistid, formData, pStore).then(() => {
|
updatePlaylist(props.playlist.id, formData, pStore).then(() => {
|
||||||
emit("hideModal");
|
emit("hideModal");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ function getSource() {
|
|||||||
location: {
|
location: {
|
||||||
name: Routes.playlist,
|
name: Routes.playlist,
|
||||||
params: {
|
params: {
|
||||||
pid: source.playlistid,
|
pid: source.id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
<img class="rounded" :src="imguri + album.image" alt="" />
|
<img class="rounded" :src="imguri + album.image" alt="" />
|
||||||
<div>
|
<div>
|
||||||
<h4 class="title ellip" v-tooltip>{{ album.title }}</h4>
|
<h4 class="title ellip" v-tooltip>{{ album.title }}</h4>
|
||||||
<div class="artist ellip">{{ album.artist }}</div>
|
<div class="artist ellip">{{ album.albumartist }}</div>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { AlbumInfo } from "../../interfaces";
|
|
||||||
import { paths } from "../../config";
|
import { paths } from "../../config";
|
||||||
|
import { AlbumInfo } from "../../interfaces";
|
||||||
|
|
||||||
const imguri = paths.images.thumb.large;
|
const imguri = paths.images.thumb.large;
|
||||||
defineProps<{
|
defineProps<{
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
<button
|
<button
|
||||||
class="playbtnrect"
|
class="playbtnrect"
|
||||||
@click="usePlayFrom(source, useQStore, store)"
|
@click="usePlayFrom(source, useQStore, store)"
|
||||||
:style="{
|
|
||||||
background: background?.color,
|
|
||||||
}"
|
|
||||||
:class="{ playbtnrectdark: background?.isDark }"
|
|
||||||
>
|
>
|
||||||
<playBtnSvg />
|
<playBtnSvg />
|
||||||
<div class="text">Play</div>
|
<div class="text">Play</div>
|
||||||
@ -43,13 +39,6 @@ defineProps<{
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
transition: all 0.5s ease-in-out;
|
transition: all 0.5s ease-in-out;
|
||||||
color: $white;
|
color: $white;
|
||||||
}
|
background: $darkestblue !important;
|
||||||
|
|
||||||
.playbtnrectdark {
|
|
||||||
color: $black !important;
|
|
||||||
|
|
||||||
svg > path {
|
|
||||||
fill: $accent !important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -24,18 +24,16 @@ interface BtnColor {
|
|||||||
* @param {string[]} colors The album colors to choose from.
|
* @param {string[]} colors The album colors to choose from.
|
||||||
* @returns {BtnColor} A color to use as the play button background
|
* @returns {BtnColor} A color to use as the play button background
|
||||||
*/
|
*/
|
||||||
export function getButtonColor(colors: string[]): BtnColor {
|
export function getButtonColor(colors: string[], index: number): BtnColor {
|
||||||
const def = {
|
const fallback = {
|
||||||
color: "#fff",
|
color: "#234ece",
|
||||||
isDark: true,
|
isDark: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!colors || colors.length === 0) return def;
|
if (!colors || colors.length === 0) return fallback;
|
||||||
|
|
||||||
const base_color = colors[0];
|
|
||||||
|
|
||||||
for (let i = 0; i < colors.length; i++) {
|
for (let i = 0; i < colors.length; i++) {
|
||||||
if (theyContrast(base_color, colors[i])) {
|
if (theyContrast(colors[index], colors[i])) {
|
||||||
return {
|
return {
|
||||||
color: colors[i],
|
color: colors[i],
|
||||||
isDark: isLight(colors[i]),
|
isDark: isLight(colors[i]),
|
||||||
@ -43,7 +41,7 @@ export function getButtonColor(colors: string[]): BtnColor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return def;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import { paths } from "@/config";
|
import { paths } from "@/config";
|
||||||
import { Artist } from "../../interfaces";
|
import { Artist, Playlist, Track } from "../../interfaces";
|
||||||
import { Playlist, Track } from "../../interfaces";
|
|
||||||
import { Notification, NotifType } from "../../stores/notification";
|
import { Notification, NotifType } from "../../stores/notification";
|
||||||
import state from "../state";
|
|
||||||
import useAxios from "./useAxios";
|
import useAxios from "./useAxios";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -67,12 +65,12 @@ async function getAllPlaylists(): Promise<Playlist[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function addTrackToPlaylist(playlist: Playlist, track: Track) {
|
async function addTrackToPlaylist(playlist: Playlist, track: Track) {
|
||||||
const uri = `${basePlaylistUrl}/${playlist.playlistid}/add`;
|
const uri = `${basePlaylistUrl}/${playlist.id}/add`;
|
||||||
|
|
||||||
const { status } = await useAxios({
|
const { status } = await useAxios({
|
||||||
url: uri,
|
url: uri,
|
||||||
props: {
|
props: {
|
||||||
track: track.trackid,
|
track: track.trackhash,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -92,13 +90,13 @@ async function getPlaylist(pid: string) {
|
|||||||
tracks: Track[];
|
tracks: Track[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data, error } = await useAxios({
|
const { data, status } = await useAxios({
|
||||||
url: uri,
|
url: uri,
|
||||||
get: true,
|
get: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (error) {
|
if (status == 404) {
|
||||||
new Notification("Something funny happened!", NotifType.Error);
|
new Notification("Playlist not found", NotifType.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
|
@ -33,7 +33,7 @@ export default function play(
|
|||||||
|
|
||||||
useQueue.playFromAlbum(
|
useQueue.playFromAlbum(
|
||||||
a_store.info.title,
|
a_store.info.title,
|
||||||
a_store.info.artist,
|
a_store.info.albumartist,
|
||||||
a_store.info.hash,
|
a_store.info.hash,
|
||||||
a_store.allTracks
|
a_store.allTracks
|
||||||
);
|
);
|
||||||
@ -45,7 +45,7 @@ export default function play(
|
|||||||
|
|
||||||
if (p.tracks.length === 0) return;
|
if (p.tracks.length === 0) return;
|
||||||
|
|
||||||
useQueue.playFromPlaylist(p.info.name, p.info.playlistid, p.tracks);
|
useQueue.playFromPlaylist(p.info.name, p.info.id, p.tracks);
|
||||||
useQueue.play();
|
useQueue.play();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ export interface AlbumDisc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Track extends AlbumDisc {
|
export interface Track extends AlbumDisc {
|
||||||
trackid: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
album?: string;
|
album?: string;
|
||||||
artist: string[];
|
artist: string[];
|
||||||
@ -21,7 +21,7 @@ export interface Track extends AlbumDisc {
|
|||||||
track: number;
|
track: number;
|
||||||
disc: number;
|
disc: number;
|
||||||
index: number;
|
index: number;
|
||||||
hash: string;
|
trackhash: string;
|
||||||
copyright?: string;
|
copyright?: string;
|
||||||
filetype: string;
|
filetype: string;
|
||||||
}
|
}
|
||||||
@ -37,18 +37,20 @@ export interface Folder {
|
|||||||
export interface AlbumInfo {
|
export interface AlbumInfo {
|
||||||
albumid: string;
|
albumid: string;
|
||||||
title: string;
|
title: string;
|
||||||
artist: string;
|
albumartist: string;
|
||||||
count: number;
|
count: number;
|
||||||
duration: number;
|
duration: number;
|
||||||
date: string;
|
date: string;
|
||||||
image: string;
|
image: string;
|
||||||
artistimg: string;
|
artistimg: string;
|
||||||
is_compilation: boolean;
|
|
||||||
is_soundtrack: boolean;
|
|
||||||
is_single: boolean;
|
|
||||||
hash: string;
|
hash: string;
|
||||||
colors: string[];
|
colors: string[];
|
||||||
copyright?: string;
|
copyright?: string;
|
||||||
|
|
||||||
|
is_compilation: boolean;
|
||||||
|
is_soundtrack: boolean;
|
||||||
|
is_single: boolean;
|
||||||
|
is_EP: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Artist {
|
export interface Artist {
|
||||||
@ -66,12 +68,12 @@ export interface Option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Playlist {
|
export interface Playlist {
|
||||||
playlistid: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
image: string | FormData;
|
image: string | FormData;
|
||||||
tracks: Track[];
|
tracks: Track[];
|
||||||
count: number;
|
count: number;
|
||||||
lastUpdated: string;
|
last_updated: string;
|
||||||
thumb: string;
|
thumb: string;
|
||||||
duration: number;
|
duration: number;
|
||||||
}
|
}
|
||||||
@ -95,7 +97,7 @@ export interface fromAlbum {
|
|||||||
export interface fromPlaylist {
|
export interface fromPlaylist {
|
||||||
type: FromOptions.playlist;
|
type: FromOptions.playlist;
|
||||||
name: string;
|
name: string;
|
||||||
playlistid: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface fromSearch {
|
export interface fromSearch {
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
<SongItem
|
<SongItem
|
||||||
v-else
|
v-else
|
||||||
style="height: 60px"
|
style="height: 60px"
|
||||||
:key="t.data.trackid"
|
:key="t.data.id"
|
||||||
:track="t.data"
|
:track="t.data"
|
||||||
:hide_album="on_album_page"
|
:hide_album="on_album_page"
|
||||||
:index="
|
:index="
|
||||||
@ -50,9 +50,9 @@
|
|||||||
? t.data.index + 1
|
? t.data.index + 1
|
||||||
: t.index + 1
|
: t.index + 1
|
||||||
"
|
"
|
||||||
:isCurrent="queue.currentid === t.data.trackid"
|
:isCurrent="queue.currentid === t.data.id"
|
||||||
:isCurrentPlaying="
|
:isCurrentPlaying="
|
||||||
queue.currentid === t.data.trackid && queue.playing
|
queue.currentid === t.data.id && queue.playing
|
||||||
"
|
"
|
||||||
@playThis="
|
@playThis="
|
||||||
updateQueue(
|
updateQueue(
|
||||||
|
@ -55,19 +55,12 @@ export default defineStore("context-menu", {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
onFirstUpdate: () => {
|
||||||
});
|
|
||||||
|
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
this.src = src;
|
this.src = src;
|
||||||
|
},
|
||||||
// const xy = normalize(e.clientX, e.clientY);
|
});
|
||||||
|
})
|
||||||
// this.x = xy.normalX;
|
|
||||||
// this.y = xy.normalY;
|
|
||||||
|
|
||||||
// this.normalizedX = xy.normalizedX;
|
|
||||||
// this.normalizedY = xy.normalizedY;
|
|
||||||
},
|
},
|
||||||
hideContextMenu() {
|
hideContextMenu() {
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
|
@ -17,27 +17,30 @@ export default defineStore("playlist-tracks", {
|
|||||||
actions: {
|
actions: {
|
||||||
/**
|
/**
|
||||||
* Fetches a single playlist information, and its tracks from the server
|
* Fetches a single playlist information, and its tracks from the server
|
||||||
* @param playlistid The id of the playlist to fetch
|
* @param id The id of the playlist to fetch
|
||||||
*/
|
*/
|
||||||
async fetchAll(playlistid: string) {
|
async fetchAll(id: string) {
|
||||||
const playlist = await getPlaylist(playlistid);
|
const playlist = await getPlaylist(id);
|
||||||
|
|
||||||
this.info = playlist?.info || ({} as Playlist);
|
this.info = playlist?.info || ({} as Playlist);
|
||||||
this.allTracks = playlist?.tracks || [];
|
this.allTracks = playlist?.tracks || [];
|
||||||
},
|
},
|
||||||
|
|
||||||
// async fetchArtists(playlistid: string) {
|
// async fetchArtists(id: string) {
|
||||||
// this.artists = await getPlaylistArtists(playlistid);
|
// this.artists = await getPlaylistArtists(id);
|
||||||
// },
|
// },
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the playlist header info. This is used when the playlist is
|
* Updates the playlist header info. This is used when the playlist is
|
||||||
* updated.
|
* updated.
|
||||||
* @param info Playlist info
|
* @param info Playlist info
|
||||||
*/
|
*/
|
||||||
updatePInfo(info: Playlist) {
|
updatePInfo(info: Playlist) {
|
||||||
const duration = this.info.duration;
|
const { duration, count } = this.info;
|
||||||
|
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this.info.duration = duration;
|
|
||||||
|
this.info = { ...this.info, duration, count };
|
||||||
},
|
},
|
||||||
resetArtists() {
|
resetArtists() {
|
||||||
this.artists = [];
|
this.artists = [];
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { ref } from "@vue/reactivity";
|
|
||||||
import { paths } from "@/config";
|
import { paths } from "@/config";
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { Ref } from "vue";
|
import { Ref } from "vue";
|
||||||
@ -12,7 +11,7 @@ import {
|
|||||||
fromFolder,
|
fromFolder,
|
||||||
fromPlaylist,
|
fromPlaylist,
|
||||||
fromSearch,
|
fromSearch,
|
||||||
Track,
|
Track
|
||||||
} from "../interfaces";
|
} from "../interfaces";
|
||||||
|
|
||||||
function shuffle(tracks: Track[]) {
|
function shuffle(tracks: Track[]) {
|
||||||
@ -52,7 +51,7 @@ export default defineStore("Queue", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const track = this.tracklist[index];
|
const track = this.tracklist[index];
|
||||||
const uri = `${paths.api.files}/${track.trackid}-${track.hash}`;
|
const uri = `${paths.api.files}/${track.id}-${track.trackhash}`;
|
||||||
|
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
audio.autoplay = true;
|
audio.autoplay = true;
|
||||||
@ -172,7 +171,7 @@ export default defineStore("Queue", {
|
|||||||
this.from = <fromPlaylist>{
|
this.from = <fromPlaylist>{
|
||||||
type: FromOptions.playlist,
|
type: FromOptions.playlist,
|
||||||
name: pname,
|
name: pname,
|
||||||
playlistid: pid,
|
id: pid,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setNewQueue(tracks);
|
this.setNewQueue(tracks);
|
||||||
@ -195,7 +194,7 @@ export default defineStore("Queue", {
|
|||||||
const next: Track = this.tracklist[nextindex];
|
const next: Track = this.tracklist[nextindex];
|
||||||
|
|
||||||
// if track is already next, skip
|
// if track is already next, skip
|
||||||
if (next?.trackid === track.trackid) {
|
if (next?.id === track.id) {
|
||||||
Toast.showNotification("Track is already queued", NotifType.Info);
|
Toast.showNotification("Track is already queued", NotifType.Info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -227,14 +226,14 @@ export default defineStore("Queue", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const current = this.currenttrack;
|
const current = this.currenttrack;
|
||||||
const current_hash = current?.hash;
|
const current_hash = current?.trackhash;
|
||||||
|
|
||||||
this.tracklist = shuffle(this.tracklist);
|
this.tracklist = shuffle(this.tracklist);
|
||||||
// find current track after shuffle
|
// find current track after shuffle
|
||||||
|
|
||||||
if (this.playing) {
|
if (this.playing) {
|
||||||
const newindex = this.tracklist.findIndex(
|
const newindex = this.tracklist.findIndex(
|
||||||
(track) => track.hash === current_hash
|
(track) => track.trackhash === current_hash
|
||||||
);
|
);
|
||||||
|
|
||||||
// remove current track from queue
|
// remove current track from queue
|
||||||
@ -294,7 +293,7 @@ export default defineStore("Queue", {
|
|||||||
return this.tracklist[this.currentindex];
|
return this.tracklist[this.currentindex];
|
||||||
},
|
},
|
||||||
currentid(): string {
|
currentid(): string {
|
||||||
return this.currenttrack?.trackid || "";
|
return this.currenttrack?.id || "";
|
||||||
},
|
},
|
||||||
previndex(): number {
|
previndex(): number {
|
||||||
return this.currentindex === 0
|
return this.currentindex === 0
|
||||||
|
@ -4,7 +4,7 @@ import { defineStore } from "pinia";
|
|||||||
|
|
||||||
export default defineStore("settings", {
|
export default defineStore("settings", {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
use_np_img: false,
|
use_np_img: true,
|
||||||
use_sidebar: true,
|
use_sidebar: true,
|
||||||
extend_width: false,
|
extend_width: false,
|
||||||
contextChildrenShowMode: contextChildrenShowMode.click,
|
contextChildrenShowMode: contextChildrenShowMode.click,
|
||||||
|
@ -5,8 +5,8 @@ export default function createTrackProps(track: Track) {
|
|||||||
return {
|
return {
|
||||||
track,
|
track,
|
||||||
index: track.index + 1,
|
index: track.index + 1,
|
||||||
isCurrent: queue().currentid === track.trackid,
|
isCurrent: queue().currentid === track.id,
|
||||||
isCurrentPlaying:
|
isCurrentPlaying:
|
||||||
queue().currentid === track.trackid && queue().playing,
|
queue().currentid === track.id && queue().playing,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,9 @@ class songItem {
|
|||||||
this.props = {
|
this.props = {
|
||||||
track,
|
track,
|
||||||
index: track.index + 1,
|
index: track.index + 1,
|
||||||
isCurrent: queue.currentid === track.trackid,
|
isCurrent: queue.currentid === track.id,
|
||||||
isCurrentPlaying:
|
isCurrentPlaying:
|
||||||
queue.currentid === track.trackid && queue.playing,
|
queue.currentid === track.id && queue.playing,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<div class="grid">
|
<div class="grid">
|
||||||
<PlaylistCard
|
<PlaylistCard
|
||||||
v-for="p in pStore.playlists"
|
v-for="p in pStore.playlists"
|
||||||
:key="p.playlistid"
|
:key="p.id"
|
||||||
:playlist="p"
|
:playlist="p"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
import { computed } from "@vue/reactivity";
|
import { computed } from "@vue/reactivity";
|
||||||
import { onBeforeRouteLeave } from "vue-router";
|
import { onBeforeRouteLeave } from "vue-router";
|
||||||
|
|
||||||
import useQueueStore from "@/stores/queue";
|
import { isMedium, isSmall } from "@/stores/content-width";
|
||||||
import usePlaylistStore from "@/stores/pages/playlist";
|
import usePlaylistStore from "@/stores/pages/playlist";
|
||||||
import { isSmall, isMedium } from "@/stores/content-width";
|
import useQueueStore from "@/stores/queue";
|
||||||
|
|
||||||
import Header from "@/components/PlaylistView/Header.vue";
|
import Header from "@/components/PlaylistView/Header.vue";
|
||||||
import SongItem from "@/components/shared/SongItem.vue";
|
import SongItem from "@/components/shared/SongItem.vue";
|
||||||
@ -38,16 +38,16 @@ const playlist = usePlaylistStore();
|
|||||||
interface ScrollerItem {
|
interface ScrollerItem {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
component: typeof Header | typeof SongItem;
|
component: typeof Header | typeof SongItem;
|
||||||
props: Record<string, unknown>;
|
// props: Record<string, unknown>;
|
||||||
size: number;
|
size: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const header: ScrollerItem = {
|
const header: ScrollerItem = {
|
||||||
id: "header",
|
id: "header",
|
||||||
component: Header,
|
component: Header,
|
||||||
props: {
|
// props: {
|
||||||
info: playlist.info,
|
// info: playlist.info,
|
||||||
},
|
// },
|
||||||
size: 19 * 16,
|
size: 19 * 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,8 +61,8 @@ const scrollerItems = computed(() => {
|
|||||||
props: {
|
props: {
|
||||||
track: track,
|
track: track,
|
||||||
index: track.index + 1,
|
index: track.index + 1,
|
||||||
isCurrent: queue.currentid === track.trackid,
|
isCurrent: queue.currentid === track.id,
|
||||||
isCurrentPlaying: queue.currentid === track.trackid && queue.playing,
|
isCurrentPlaying: queue.currentid === track.id && queue.playing,
|
||||||
},
|
},
|
||||||
size: 64,
|
size: 64,
|
||||||
};
|
};
|
||||||
@ -71,8 +71,8 @@ const scrollerItems = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function playFromPlaylistPage(index: number) {
|
function playFromPlaylistPage(index: number) {
|
||||||
const { name, playlistid } = playlist.info;
|
const { name, id } = playlist.info;
|
||||||
queue.playFromPlaylist(name, playlistid, playlist.allTracks);
|
queue.playFromPlaylist(name, id, playlist.allTracks);
|
||||||
queue.play(index);
|
queue.play(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
<SongItem
|
<SongItem
|
||||||
:track="item.track"
|
:track="item.track"
|
||||||
:index="index + 1"
|
:index="index + 1"
|
||||||
:isCurrent="queue.currentid === item.track.trackid"
|
:isCurrent="queue.currentid === item.track.id"
|
||||||
:isCurrentPlaying="
|
:isCurrentPlaying="
|
||||||
queue.currentid === item.track.trackid && queue.playing
|
queue.currentid === item.track.id && queue.playing
|
||||||
"
|
"
|
||||||
@playThis="playFromQueue(index)"
|
@playThis="playFromQueue(index)"
|
||||||
/>
|
/>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user