🔷 add PlayingFrom component to right sidebar

🔷 move upNext card into separate component
🔷 a lot of refactors
This commit is contained in:
geoffrey45
2022-04-03 21:47:57 +03:00
parent 334cf0fce1
commit 6cf9a58d6d
26 changed files with 425 additions and 220 deletions
+15 -19
View File
@@ -8,6 +8,7 @@ from app import instances, api
from app.lib import playlistlib from app.lib import playlistlib
from app import models from app import models
from app import exceptions from app import exceptions
from app import serializer
playlist_bp = Blueprint("playlist", __name__, url_prefix="/") playlist_bp = Blueprint("playlist", __name__, url_prefix="/")
@@ -17,15 +18,7 @@ TrackExistsInPlaylist = exceptions.TrackExistsInPlaylist
@playlist_bp.route("/playlists", methods=["GET"]) @playlist_bp.route("/playlists", methods=["GET"])
def get_all_playlists(): def get_all_playlists():
ppp = deepcopy(api.PLAYLISTS) return {"data": [serializer.Playlist(p) for p in api.PLAYLISTS]}
playlists = []
for pl in ppp:
pl.count = len(pl.tracks)
pl.tracks = []
playlists.append(pl)
return {"data": playlists}
@playlist_bp.route("/playlist/new", methods=["POST"]) @playlist_bp.route("/playlist/new", methods=["POST"])
@@ -35,16 +28,16 @@ def create_playlist():
playlist = { playlist = {
"name": data["name"], "name": data["name"],
"description": "", "description": "",
"tracks": [], "pre_tracks": [],
"count": 0,
"lastUpdated": 0, "lastUpdated": 0,
"image": "",
} }
try: try:
p_in_db = instances.playlist_instance.get_playlist_by_name(playlist["name"]) for pl in api.PLAYLISTS:
if pl.name == playlist["name"]:
raise PlaylistExists("Playlist already exists.")
if p_in_db:
raise PlaylistExists("Playlist already exists.")
except PlaylistExists as e: except PlaylistExists as e:
return {"error": str(e)}, 409 return {"error": str(e)}, 409
@@ -71,12 +64,15 @@ def add_track_to_playlist(playlist_id: str):
return {"msg": "I think It's done"}, 200 return {"msg": "I think It's done"}, 200
@playlist_bp.route("/playlist/<playlist_id>") @playlist_bp.route("/playlist/<playlistid>")
def get_single_p_info(playlist_id: str): def get_single_p_info(playlistid: str):
for p in api.PLAYLISTS: for p in api.PLAYLISTS:
if p.playlistid == playlist_id: if p.playlistid == playlistid:
p.count = len(p.tracks) print(p)
return {"data": p} tracks = p.get_tracks()
return {"info": serializer.Playlist(p), "tracks": tracks}
return {"info": {}, "tracks": []}
# @playlist_bp.route("/playlist/<playlist_id>/info") # @playlist_bp.route("/playlist/<playlist_id>/info")
+3 -9
View File
@@ -9,7 +9,6 @@ convert_many = db.convert_many
convert_one = db.convert_one convert_one = db.convert_one
class Playlists(db.Mongo): class Playlists(db.Mongo):
""" """
The class for all playlist-related database operations. The class for all playlist-related database operations.
@@ -43,20 +42,15 @@ class Playlists(db.Mongo):
playlist = self.collection.find_one({"_id": ObjectId(id)}) playlist = self.collection.find_one({"_id": ObjectId(id)})
return convert_one(playlist) return convert_one(playlist)
def add_track_to_playlist(self, playlistid: str, track: models.Track): def add_track_to_playlist(self, playlistid: str, track: dict) -> None:
""" """
Adds a track to a playlist. Adds a track to a playlist.
""" """
track = {
"title": track.title,
"artists": track.artists,
"album": track.album,
}
return self.collection.update_one( return self.collection.update_one(
{"_id": ObjectId(playlistid)}, {"_id": ObjectId(playlistid)},
{"$push": {"tracks": track}}, {"$push": {"pre_tracks": track}},
).modified_count )
def get_playlist_by_name(self, name: str) -> dict: def get_playlist_by_name(self, name: str) -> dict:
""" """
-1
View File
@@ -81,7 +81,6 @@ def populate():
albumslib.create_everything() albumslib.create_everything()
folderslib.run_scandir() folderslib.run_scandir()
playlistlib.create_all_playlists()
end = time.time() end = time.time()
+11 -6
View File
@@ -15,14 +15,20 @@ def add_track(playlistid: str, trackid: str):
""" """
for playlist in api.PLAYLISTS: for playlist in api.PLAYLISTS:
if playlist.playlistid == playlistid: if playlist.playlistid == playlistid:
track = trackslib.get_track_by_id(trackid) tt = trackslib.get_track_by_id(trackid)
if track not in playlist.tracks: track = {
playlist.tracks.append(track) "title": tt.title,
"artists": tt.artists,
"album": tt.album,
}
try:
playlist.add_track(track)
instances.playlist_instance.add_track_to_playlist(playlistid, track) instances.playlist_instance.add_track_to_playlist(playlistid, track)
return return
else: except TrackExistsInPlaylist as e:
raise TrackExistsInPlaylist("Track already in playlist.") return {"error": str(e)}, 409
def get_playlist_tracks(pid: str): def get_playlist_tracks(pid: str):
@@ -31,7 +37,6 @@ def get_playlist_tracks(pid: str):
return p.tracks return p.tracks
def create_all_playlists(): def create_all_playlists():
""" """
Gets all playlists from the database. Gets all playlists from the database.
+26 -3
View File
@@ -2,11 +2,12 @@
Contains all the models for objects generation and typing. Contains all the models for objects generation and typing.
""" """
from dataclasses import dataclass from dataclasses import dataclass, field
from datetime import date from datetime import date
from typing import List from typing import List
from app import api from app import api
from app import settings from app import settings
from app.exceptions import TrackExistsInPlaylist
@dataclass @dataclass
@@ -99,10 +100,11 @@ class Playlist:
playlistid: str playlistid: str
name: str name: str
description: str
image: str image: str
tracks: List[Track] tracks: List[Track]
_pre_tracks: list = field(init=False, repr=False)
lastUpdated: int lastUpdated: int
description: str = ""
count: int = 0 count: int = 0
"""A list of track objects in the playlist""" """A list of track objects in the playlist"""
@@ -111,8 +113,29 @@ class Playlist:
self.name = data["name"] self.name = data["name"]
self.description = data["description"] self.description = data["description"]
self.image = "" self.image = ""
self.tracks = create_playlist_tracks(data["tracks"]) self._pre_tracks = data["pre_tracks"]
self.tracks = []
self.lastUpdated = data["lastUpdated"] self.lastUpdated = data["lastUpdated"]
self.count = len(self._pre_tracks)
def get_tracks(self) -> List[Track]:
"""
Generates and returns Track objects from pre_tracks
"""
return create_playlist_tracks(self._pre_tracks)
def update_count(self):
self.count = len(self.tracks)
def add_track(self, track):
if track not in self._pre_tracks:
self._pre_tracks.append(track)
self.update_count()
else:
raise TrackExistsInPlaylist("Track already exists in playlist")
def update_desc(self, desc):
self.description = desc
@dataclass @dataclass
+1 -5
View File
@@ -38,11 +38,7 @@ a {
} }
.border { .border {
border: solid 1px $gray; border: solid 1px $gray3;
}
.border-sm {
border: solid 1px #27262654;
} }
.separator { .separator {
+15 -24
View File
@@ -4,47 +4,38 @@
<div <div
class="image art shadow-lg rounded" class="image art shadow-lg rounded"
:style="{ :style="{
backgroundImage: `url(&quot;${props.album_info.image}&quot;)`, backgroundImage: `url(&quot;${props.album.image}&quot;)`,
}" }"
></div> ></div>
<div class="info"> <div class="info">
<div class="top"> <div class="top">
<div class="h">Album</div> <div class="h">Album</div>
<div class="separator no-border"></div> <div class="separator no-border"></div>
<div class="title">{{ props.album_info.album }}</div> <div class="title">{{ props.album.album }}</div>
<div class="artist">{{ props.album_info.artist }}</div> <div class="artist">{{ props.album.artist }}</div>
</div> </div>
<div class="separator no-border"></div> <div class="separator no-border"></div>
<div class="bottom"> <div class="bottom">
<div class="stats shadow-sm"> <div class="stats shadow-sm">
{{ props.album_info.count }} Tracks {{ props.album.count }} Tracks
{{ perks.formatSeconds(props.album_info.duration, "long") }} {{ perks.formatSeconds(props.album.duration, "long") }}
{{ props.album_info.date }} {{ props.album.date }}
</div>
<div class="play rounded" @click="playAlbum">
<div class="icon"></div>
<div>Play</div>
</div> </div>
<PlayBtnRect :source="playSources.album" />
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup lang="ts">
import state from "@/composables/state"; import perks from "../../composables/perks.js";
import perks from "@/composables/perks.js"; import { AlbumInfo } from "../../interfaces.js";
import PlayBtnRect from "../shared/PlayBtnRect.vue";
const props = defineProps({ import { playSources } from "../../composables/enums";
album_info: { const props = defineProps<{
type: Object, album: AlbumInfo;
default: () => ({}), }>();
},
});
function playAlbum() {
perks.updateQueue(state.album.tracklist[0], "album");
}
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -13,7 +13,7 @@
v-for="artist in artists" v-for="artist in artists"
:key="artist" :key="artist"
:artist="artist" :artist="artist"
:color="ffffff00" :color="'ffffff00'"
/> />
</div> </div>
</div> </div>
+6 -13
View File
@@ -1,14 +1,14 @@
<template> <template>
<div class="p-header"> <div class="p-header">
<div class="carddd"> <div class="carddd">
<div class="art image"></div> <div class="art image shadow-sm"></div>
<div class="info"> <div class="info">
<div class="btns"> <div class="btns">
<PlayBtnRect :source="playSources.playlist" /> <PlayBtnRect :source="playSources.playlist" />
</div> </div>
<div class="duration">4 Tracks 3 Hours</div> <div class="duration">{{props.info.count}} Tracks 3 Hours</div>
<div class="desc"> <div class="desc">
{{ props.info.desc[0] }} {{ props.info.description }}
</div> </div>
<div class="title ellip">{{ props.info.name }}</div> <div class="title ellip">{{ props.info.name }}</div>
<div class="type">Playlist</div> <div class="type">Playlist</div>
@@ -25,16 +25,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { playSources } from "../../composables/enums"; import { playSources } from "../../composables/enums";
import { Playlist } from "../../interfaces";
import PlayBtnRect from "../shared/PlayBtnRect.vue"; import PlayBtnRect from "../shared/PlayBtnRect.vue";
const props = defineProps<{ const props = defineProps<{
info: { info: Playlist;
name: string;
count: number;
duration: string;
desc: string;
lastUpdated: string;
};
}>(); }>();
</script> </script>
@@ -43,9 +38,7 @@ const props = defineProps<{
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
height: 14rem; height: 14rem;
// background-image: url("../../assets/images/eggs.jpg"); background-image: linear-gradient(37deg, $black 4%, $accent, $black);
background-image: linear-gradient(23deg, $black 40%, rgb(141, 11, 2), $black);
position: relative; position: relative;
margin-top: $small; margin-top: $small;
border-radius: 0.75rem; border-radius: 0.75rem;
+10 -5
View File
@@ -1,16 +1,21 @@
<template> <template>
<div class="r-home"> <div class="r-home">
<Recommendations /> <UpNext :next="queue.next" :playNext="queue.playNext" />
<Recommendations />
</div> </div>
</template> </template>
<style lang="scss"> <style lang="scss">
.r-home { .r-home {
height: calc(100% - 1rem); height: calc(100% - 1rem);
// padding: 0 $small $small 0; padding: 0 $small $small 0;
margin-top: $small;
} }
</style> </style>
<script setup> <script setup lang="ts">
import Recommendations from '../Recommendation.vue'; import Recommendations from "../Recommendation.vue";
</script> import UpNext from "../queue/upNext.vue";
import useQStore from "../../../stores/queue";
const queue = useQStore();
</script>
+5 -69
View File
@@ -1,28 +1,8 @@
<template> <template>
<div class="up-next"> <div class="up-next">
<div class="r-grid"> <div class="r-grid">
<div class="main-item border"> <PlayingFrom :from="queue.from" />
<p class="heading">COMING UP NEXT</p> <UpNext :next="queue.next" :playNext="queue.playNext" />
<div class="itemx" @click="queue.playNext">
<div
class="album-art image"
:style="{
backgroundImage: `url(&quot;${queue.next.image}&quot;)`,
}"
></div>
<div class="tags">
<p class="title ellip">{{ queue.next.title }}</p>
<hr />
<p class="artist ellip">
<span
v-for="artist in putCommas(queue.next.artists)"
:key="artist"
>{{ artist }}</span
>
</p>
</div>
</div>
</div>
<div class="scrollable-r border rounded"> <div class="scrollable-r border rounded">
<TrackItem <TrackItem
v-for="t in queue.tracks" v-for="t in queue.tracks"
@@ -38,16 +18,14 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import perks from "../../composables/perks.js";
import TrackItem from "../shared/TrackItem.vue"; import TrackItem from "../shared/TrackItem.vue";
import useQStore from "../../stores/queue"; import useQStore from "../../stores/queue";
import { Track } from "../../interfaces.js"; import { Track } from "../../interfaces.js";
import { onBeforeMount } from "vue"; import PlayingFrom from "./queue/playingFrom.vue";
import UpNext from "./queue/upNext.vue";
const queue = useQStore(); const queue = useQStore();
const putCommas = perks.putCommas;
function playThis(track: Track) { function playThis(track: Track) {
queue.play(track); queue.play(track);
} }
@@ -64,53 +42,11 @@ function playThis(track: Track) {
margin: 0.5rem 0 1rem 0; margin: 0.5rem 0 1rem 0;
} }
.main-item {
border-radius: 0.5rem;
padding: 0.5rem;
margin-bottom: 0.5rem;
.itemx {
display: flex;
align-items: center;
padding: 0.5rem;
cursor: pointer;
border-radius: 0.5rem;
&:hover {
background-color: $gray;
}
}
.album-art {
width: 4.5rem;
height: 4.5rem;
background-image: url(../../assets/images/null.webp);
margin: 0 0.5rem 0 0;
border-radius: 0.5rem;
}
.tags {
hr {
border: none;
margin: 0.3rem;
}
.title {
width: 20rem;
margin: 0;
}
.artist {
width: 20rem;
margin: 0;
font-size: small;
}
}
}
.r-grid { .r-grid {
position: relative; position: relative;
height: 100%; height: 100%;
display: grid; display: grid;
grid-template-rows: min-content; grid-template-rows: max-content max-content 1fr;
.scrollable-r { .scrollable-r {
height: 100%; height: 100%;
@@ -1,6 +1,6 @@
<template> <template>
<div class="r-tracks rounded border"> <div class="r-tracks rounded border">
<p class="heading">SIMILAR TRACKS</p> <div class="heading">Similar Tracks</div>
<div class="tracks"> <div class="tracks">
<div class="song-item" v-for="song in songs" :key="song"> <div class="song-item" v-for="song in songs" :key="song">
<div class="album-art image"></div> <div class="album-art image"></div>
@@ -37,8 +37,13 @@ export default {
<style lang="scss"> <style lang="scss">
.r-tracks { .r-tracks {
margin: 0.5rem 0.5rem 0.5rem 0; margin: 0.5rem 0 0.5rem 0;
padding: 0.5rem; padding: 0.5rem;
.heading {
font-size: 1.25rem;
margin-bottom: 0.5rem !important;
}
} }
.r-tracks .tracks .song-item { .r-tracks .tracks .song-item {
-1
View File
@@ -170,7 +170,6 @@ search.$subscribe((mutation, state) => {
padding: $medium; padding: $medium;
border-radius: $small; border-radius: $small;
margin-bottom: $small; margin-bottom: $small;
text-align: center !important;
font-size: 2rem; font-size: 2rem;
color: $white; color: $white;
} }
@@ -0,0 +1,157 @@
<template>
<div id="playing-from" class="rounded" @click="goTo">
<div class="abs shadow-sm">Playing From</div>
<div class="h">
<div class="icon image" :class="from.type"></div>
{{ from.type }}
</div>
<div class="name">
<div id="to">
{{ from.name }}
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { fromFolder, fromAlbum, fromPlaylist } from "../../../interfaces";
import { FromOptions } from "../../../composables/enums";
import { useRouter } from "vue-router";
import { computed } from "@vue/reactivity";
const props = defineProps<{
from: fromFolder | fromAlbum | fromPlaylist;
}>();
interface from {
type: string;
name: string;
}
const from = computed((): from => {
switch (props.from.type) {
case undefined:
return {
type: "album",
name: "Welcome to Alice",
};
case FromOptions.folder:
return {
type: "folder",
name: props.from.name,
};
case FromOptions.album:
return {
type: "album",
name: props.from.name,
};
case FromOptions.playlist:
return {
type: "playlist",
name: props.from.name,
};
}
});
const router = useRouter();
function goToAlbum() {
router.push({
name: "AlbumView",
params: {
album: props.from.name,
artist: props.from.albumartist,
},
});
}
function goToFolder() {
router.push({
name: "FolderView",
params: {
path: props.from.path,
},
});
}
function goToPlaylist() {
router.push({
name: "PlaylistView",
params: {
pid: props.from.playlistid,
},
});
}
function goTo() {
switch (props.from.type) {
case FromOptions.folder:
goToFolder();
break;
case FromOptions.album:
goToAlbum();
break;
case FromOptions.playlist:
goToPlaylist();
break;
}
}
</script>
<style lang="scss">
#playing-from {
background: linear-gradient(-200deg, $gray4 40%, $red, $gray4);
background-size: 120%;
padding: 0.75rem;
margin-bottom: $small;
cursor: pointer;
position: relative;
transition: all .2s ease;
&:hover {
background-position: -4rem;
}
.abs {
position: absolute;
right: $small;
top: $small;
font-size: .9rem;
background-color: $gray;
padding: $smaller;
border-radius: .25rem;
}
.name {
text-transform: capitalize;
font-weight: bolder;
}
.h {
font-size: .9rem;
margin-bottom: $small;
display: flex;
align-items: center;
gap: $small;
text-transform: capitalize;
color: rgba(255, 255, 255, 0.664);
.icon {
height: 1.25rem;
width: 1.25rem;
}
.folder {
background-image: url("../../../assets/icons/folder.fill.svg") !important;
}
.album {
background-image: url("../../../assets/icons/album.svg") !important;
}
.playlist {
background-image: url("../../../assets/icons/playlist.svg") !important;
}
}
}
</style>
@@ -0,0 +1,91 @@
<template>
<div class="main-item border" @click="playNext">
<div class="h">#Up_Next</div>
<div class="itemx shadow">
<div
class="album-art image"
:style="{
backgroundImage: `url(&quot;${next.image}&quot;)`,
}"
></div>
<div class="tags">
<p class="title ellip">{{ next.title }}</p>
<hr />
<p class="artist ellip">
<span v-for="artist in perks.putCommas(next.artists)" :key="artist">{{
artist
}}</span>
</p>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { Track } from "../../../interfaces";
import perks from "../../../composables/perks";
const props = defineProps<{
next: Track;
playNext: () => void;
}>();
</script>
<style lang="scss">
.main-item {
border-radius: 0.5rem;
margin-bottom: 0.5rem;
position: relative;
&:hover {
background-color: $accent;
border: 1px solid transparent;
.h {
background-color: $black;
}
}
.h {
position: absolute;
right: $small;
top: $small;
font-size: 0.9rem;
background-color: $accent;
padding: $smaller;
border-radius: 0.25rem;
}
.itemx {
display: flex;
align-items: center;
border-radius: 0.5rem;
padding: 0.75rem;
cursor: pointer;
}
.album-art {
width: 4.5rem;
height: 4.5rem;
background-image: url(../../assets/images/null.webp);
margin: 0 0.5rem 0 0;
border-radius: 0.5rem;
}
.tags {
hr {
border: none;
margin: 0.3rem;
}
.title {
width: 20rem;
margin: 0;
}
.artist {
width: 20rem;
margin: 0;
font-size: small;
}
}
}
</style>
+1
View File
@@ -89,6 +89,7 @@ const context = useContextStore();
position: absolute; position: absolute;
right: -13rem; right: -13rem;
width: 13rem; width: 13rem;
top: -0.5rem;
max-height: 21.25rem; max-height: 21.25rem;
padding: $small !important; padding: $small !important;
+5 -9
View File
@@ -35,11 +35,11 @@ function play() {
break; break;
case playSources.playlist: case playSources.playlist:
queue.playFromPlaylist( queue.playFromPlaylist(
playlist.playlist.name, playlist.info.name,
playlist.playlist.playlistid, playlist.info.playlistid,
playlist.playlist.tracks playlist.tracks
); );
queue.play(playlist.playlist.tracks[0]); queue.play(playlist.tracks[0]);
break; break;
} }
} }
@@ -53,11 +53,7 @@ function play() {
height: 2.5rem; height: 2.5rem;
padding-left: 0.75rem; padding-left: 0.75rem;
cursor: pointer; cursor: pointer;
background: linear-gradient( background: linear-gradient(34deg, $accent, $red);
34deg,
rgba(255, 166, 0, 0.644) 30%,
rgb(214, 188, 38)
);
user-select: none; user-select: none;
transition: all 0.5s ease; transition: all 0.5s ease;
+7
View File
@@ -10,3 +10,10 @@ export enum NotifType {
Info, Info,
Error, Error,
} }
export enum FromOptions {
playlist = "playlist",
folder = "folder",
album = "album",
search = "search",
}
+13 -3
View File
@@ -95,12 +95,16 @@ async function getPTracks(playlistid: string) {
async function getPlaylist(pid: string) { async function getPlaylist(pid: string) {
const uri = state.settings.uri + "/playlist/" + pid; const uri = state.settings.uri + "/playlist/" + pid;
let playlist: Playlist; let playlist = {
info: {},
tracks: <Track[]>[],
};
await axios await axios
.get(uri) .get(uri)
.then((res) => { .then((res) => {
playlist = res.data.data; playlist.info = res.data.info;
playlist.tracks = res.data.tracks;
}) })
.catch((err) => { .catch((err) => {
new Notification("Something funny happened!", NotifType.Error); new Notification("Something funny happened!", NotifType.Error);
@@ -110,4 +114,10 @@ async function getPlaylist(pid: string) {
return playlist; return playlist;
} }
export { createNewPlaylist, getAllPlaylists, addTrackToPlaylist, getPTracks, getPlaylist }; export {
createNewPlaylist,
getAllPlaylists,
addTrackToPlaylist,
getPTracks,
getPlaylist,
};
+30 -2
View File
@@ -1,4 +1,5 @@
import { NotifType } from "./stores/enums"; import { FromOptions } from "./composables/enums";
import { NotifType } from "./composables/enums";
interface Track { interface Track {
trackid: string; trackid: string;
@@ -62,4 +63,31 @@ interface Notif {
type: NotifType; type: NotifType;
} }
export { Track, Folder, AlbumInfo, Artist, Option, Playlist, Notif }; interface fromFolder {
type: FromOptions;
path: string;
name: string;
}
interface fromAlbum {
type: FromOptions;
name: string;
albumartist: string;
}
interface fromPlaylist {
type: FromOptions;
name: string;
playlistid: string;
}
export {
Track,
Folder,
AlbumInfo,
Artist,
Option,
Playlist,
Notif,
fromFolder,
fromAlbum,
fromPlaylist,
};
View File
+1
View File
@@ -0,0 +1 @@
+5 -3
View File
@@ -1,15 +1,17 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { getPlaylist, getPTracks } from "../composables/playlists"; import { getPlaylist } from "../composables/playlists";
import { Track, Playlist } from "../interfaces"; import { Track, Playlist } from "../interfaces";
export default defineStore("playlist-tracks", { export default defineStore("playlist-tracks", {
state: () => ({ state: () => ({
playlist: <Playlist>{}, info: <Playlist>{},
tracks: <Track[]>[],
}), }),
actions: { actions: {
async fetchAll(playlistid: string) { async fetchAll(playlistid: string) {
const playlist = await getPlaylist(playlistid); const playlist = await getPlaylist(playlistid);
this.playlist = playlist; this.info = playlist.info;
this.tracks = playlist.tracks;
}, },
}, },
}); });
+10 -32
View File
@@ -1,31 +1,8 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import state from "../composables/state"; import state from "../composables/state";
import { Track } from "../interfaces"; import { Track, fromFolder, fromAlbum, fromPlaylist } from "../interfaces";
import notif from "../composables/mediaNotification"; import notif from "../composables/mediaNotification";
import { FromOptions } from "../composables/enums";
enum FromOptions {
playlist = "Playlist",
folder = "Folder",
album = "Album",
search = "Search",
}
interface fromFolder {
type: FromOptions.folder;
path: string;
}
interface fromAlbum {
type: FromOptions.album;
name: string;
albumartist: string;
}
interface fromPlaylist {
type: FromOptions.playlist;
name: string;
playlistid: string;
}
function addQToLocalStorage( function addQToLocalStorage(
from: fromFolder | fromAlbum | fromPlaylist, from: fromFolder | fromAlbum | fromPlaylist,
@@ -84,7 +61,6 @@ export default defineStore("Queue", {
}) })
.then(() => { .then(() => {
this.audio.play().then(() => { this.audio.play().then(() => {
this.playing = true; this.playing = true;
notif(track, this.playPause, this.playNext, this.playPrev); notif(track, this.playPause, this.playNext, this.playPrev);
@@ -108,6 +84,7 @@ export default defineStore("Queue", {
this.play(this.current); this.play(this.current);
} else if (this.audio.paused) { } else if (this.audio.paused) {
this.audio.play(); this.audio.play();
this.playing = true;
} else { } else {
this.audio.pause(); this.audio.pause();
this.playing = false; this.playing = false;
@@ -131,6 +108,7 @@ export default defineStore("Queue", {
}, },
readQueueFromLocalStorage() { readQueueFromLocalStorage() {
const queue = localStorage.getItem("queue"); const queue = localStorage.getItem("queue");
if (queue) { if (queue) {
const parsed = JSON.parse(queue); const parsed = JSON.parse(queue);
this.from = parsed.from; this.from = parsed.from;
@@ -180,30 +158,30 @@ export default defineStore("Queue", {
} }
}, },
playFromFolder(fpath: string, tracks: Track[]) { playFromFolder(fpath: string, tracks: Track[]) {
this.setNewQueue(tracks);
this.from = <fromFolder>{ this.from = <fromFolder>{
type: FromOptions.folder, type: FromOptions.folder,
path: fpath, path: fpath,
name: fpath.split("/").splice(-1).join(""),
}; };
this.setNewQueue(tracks);
}, },
playFromAlbum(aname: string, albumartist: string, tracks: Track[]) { playFromAlbum(aname: string, albumartist: string, tracks: Track[]) {
this.setNewQueue(tracks);
this.from = <fromAlbum>{ this.from = <fromAlbum>{
type: FromOptions.album, type: FromOptions.album,
name: aname, name: aname,
albumartist: albumartist, albumartist: albumartist,
}; };
this.setNewQueue(tracks);
}, },
playFromPlaylist(pname: string, pid: string, tracks: Track[]) { playFromPlaylist(pname: string, pid: string, tracks: Track[]) {
this.setNewQueue(tracks);
this.from = <fromPlaylist>{ this.from = <fromPlaylist>{
type: FromOptions.playlist, type: FromOptions.playlist,
name: pname, name: pname,
playlistid: pid, playlistid: pid,
}; };
this.setNewQueue(tracks);
}, },
}, },
}); });
+1 -1
View File
@@ -1,7 +1,7 @@
<template> <template>
<div class="al-view rounded"> <div class="al-view rounded">
<div> <div>
<Header :album_info="album.info" /> <Header :album="album.info" />
</div> </div>
<div class="separator" id="av-sep"></div> <div class="separator" id="av-sep"></div>
<div class="songs rounded"> <div class="songs rounded">
+4 -12
View File
@@ -1,13 +1,13 @@
<template> <template>
<div class="playlist-view"> <div class="playlist-view">
<Header :info="info" /> <Header :info="playlist.info" />
<div class="separator no-border"></div> <div class="separator no-border"></div>
<div class="songlist rounded"> <div class="songlist rounded">
<SongList <SongList
:tracks="playlist.tracks" :tracks="playlist.tracks"
:pname="info.name" :pname="playlist.info.name"
:playlistid="playlist.playlistid" :playlistid="playlist.info.playlistid"
/> />
</div> </div>
<div class="separator no-border"></div> <div class="separator no-border"></div>
@@ -21,15 +21,7 @@ import SongList from "../components/FolderView/SongList.vue";
import FeaturedArtists from "../components/PlaylistView/FeaturedArtists.vue"; import FeaturedArtists from "../components/PlaylistView/FeaturedArtists.vue";
import usePTrackStore from "../stores/p.ptracks"; import usePTrackStore from "../stores/p.ptracks";
const playlist = usePTrackStore().playlist; const playlist = usePTrackStore();
const info = {
name: playlist.name,
count: playlist.tracks.length,
desc: playlist.description,
duration: "3 hours, 4 minutes",
lastUpdated: "yesterday",
};
</script> </script>
<style lang="scss"> <style lang="scss">