Integrate nav

- other minor refactors
This commit is contained in:
geoffrey45
2022-04-14 11:30:19 +03:00
parent 90d646d674
commit 85c59b4cba
28 changed files with 266 additions and 141 deletions
+7 -1
View File
@@ -40,6 +40,7 @@ def create_playlist():
"pre_tracks": [], "pre_tracks": [],
"lastUpdated": data["lastUpdated"], "lastUpdated": data["lastUpdated"],
"image": "", "image": "",
"thumb": ""
} }
try: try:
@@ -100,15 +101,20 @@ def update_playlist(playlistid: str):
"description": str(data.get("description").strip()), "description": str(data.get("description").strip()),
"lastUpdated": str(data.get("lastUpdated")), "lastUpdated": str(data.get("lastUpdated")),
"image": None, "image": None,
"thumb": None
} }
for p in api.PLAYLISTS: for p in api.PLAYLISTS:
if p.playlistid == playlistid: if p.playlistid == playlistid:
if image: if image:
playlist["image"] = playlistlib.save_p_image(image, playlistid) image_, thumb_ = playlistlib.save_p_image(image, playlistid)
playlist["image"] = image_
playlist["thumb"] = thumb_
else: else:
playlist["image"] = p.image.split("/")[-1] playlist["image"] = p.image.split("/")[-1]
playlist['thumb'] = p.thumb.split("/")[-1]
p.update_playlist(playlist) p.update_playlist(playlist)
instances.playlist_instance.update_playlist(playlistid, playlist) instances.playlist_instance.update_playlist(playlistid, playlist)
+1 -1
View File
@@ -19,7 +19,7 @@ def send_track_file(trackid):
file["filepath"] for file in api.PRE_TRACKS file["filepath"] for file in api.PRE_TRACKS
if file["_id"]["$oid"] == trackid if file["_id"]["$oid"] == trackid
][0] ][0]
except (FileNotFoundError, IndexError): except (FileNotFoundError, IndexError) as e:
return "File not found", 404 return "File not found", 404
return send_file(filepath, mimetype="audio/mp3") return send_file(filepath, mimetype="audio/mp3")
+2 -2
View File
@@ -16,8 +16,8 @@ class Albums(db.Mongo):
""" """
def __init__(self): def __init__(self):
super(Albums, self).__init__("ALBUMS") super(Albums, self).__init__("ALICE_ALBUMS")
self.collection = self.db["ALBUMS"] self.collection = self.db["ALL_ALBUMS"]
def insert_album(self, album: dict) -> None: def insert_album(self, album: dict) -> None:
""" """
+2 -2
View File
@@ -12,8 +12,8 @@ class Artists(db.Mongo):
""" """
def __init__(self): def __init__(self):
super(Artists, self).__init__("ALL_ARTISTS") super(Artists, self).__init__("ALICE_ARTISTS")
self.collection = self.db["THEM_ARTISTS"] self.collection = self.db["ALL_ARTISTS"]
def insert_artist(self, artist_obj: dict) -> None: def insert_artist(self, artist_obj: dict) -> None:
""" """
+2 -2
View File
@@ -15,8 +15,8 @@ class Playlists(db.Mongo):
""" """
def __init__(self): def __init__(self):
super(Playlists, self).__init__("PLAYLISTS") super(Playlists, self).__init__("ALICE_PLAYLISTS")
self.collection = self.db["PLAYLISTS"] self.collection = self.db["ALL_PLAYLISTS"]
def insert_playlist(self, playlist: dict) -> None: def insert_playlist(self, playlist: dict) -> None:
""" """
+1 -1
View File
@@ -11,7 +11,7 @@ class TrackColors(db.Mongo):
""" """
def __init__(self): def __init__(self):
super(TrackColors, self).__init__("TRACK_COLORS") super(TrackColors, self).__init__("ALICE_TRACK_COLORS")
self.collection = self.db["TRACK_COLORS"] self.collection = self.db["TRACK_COLORS"]
def insert_track_color(self, track_color: dict) -> None: def insert_track_color(self, track_color: dict) -> None:
+2 -3
View File
@@ -15,8 +15,8 @@ class AllSongs(db.Mongo):
""" """
def __init__(self): def __init__(self):
super(AllSongs, self).__init__("ALL_SONGS") super(AllSongs, self).__init__("ALICE_MUSIC_TRACKS")
self.collection = self.db["ALL_SONGS"] self.collection = self.db["ALL_TRACKS"]
# def drop_db(self): # def drop_db(self):
# self.collection.drop() # self.collection.drop()
@@ -67,7 +67,6 @@ class AllSongs(db.Mongo):
""" """
Finds all the tracks matching the title in the query params. Finds all the tracks matching the title in the query params.
""" """
self.collection.create_index([("title", db.pymongo.TEXT)])
song = self.collection.find({"title": {"$regex": query, "$options": "i"}}) song = self.collection.find({"title": {"$regex": query, "$options": "i"}})
return convert_many(song) return convert_many(song)
-1
View File
@@ -58,7 +58,6 @@ def get_subdirs(foldername: str) -> List[models.Folder]:
if str1 is not None: if str1 is not None:
subdirs.add(foldername + "/" + str1) subdirs.add(foldername + "/" + str1)
return [create_folder(dir) for dir in subdirs] return [create_folder(dir) for dir in subdirs]
+51 -9
View File
@@ -35,8 +35,7 @@ def add_track(playlistid: str, trackid: str):
try: try:
playlist.add_track(track) playlist.add_track(track)
instances.playlist_instance.add_track_to_playlist( instances.playlist_instance.add_track_to_playlist(playlistid, track)
playlistid, track)
return return
except TrackExistsInPlaylist as error: except TrackExistsInPlaylist as error:
raise error raise error
@@ -61,6 +60,25 @@ def create_all_playlists():
_bar.next() _bar.next()
_bar.finish() _bar.finish()
validate_images()
def create_thumbnail(image: any, img_path: str) -> str:
"""
Creates a 250 x 250 thumbnail from a playlist image
"""
thumb_path = "thumb_" + img_path
full_thumb_path = os.path.join(settings.APP_DIR, "images", "playlists", thumb_path)
aspect_ratio = image.width / image.height
new_w = round(250 * aspect_ratio)
thumb = image.resize((new_w, 250), Image.ANTIALIAS)
thumb.save(full_thumb_path, "webp")
return thumb_path
def save_p_image(file: datastructures.FileStorage, pid: str): def save_p_image(file: datastructures.FileStorage, pid: str):
""" """
@@ -68,11 +86,11 @@ def save_p_image(file: datastructures.FileStorage, pid: str):
""" """
img = Image.open(file) img = Image.open(file)
random_str = "".join( random_str = "".join(random.choices(string.ascii_letters + string.digits, k=5))
random.choices(string.ascii_letters + string.digits, k=5))
img_path = pid + str(random_str) + ".webp" img_path = pid + str(random_str) + ".webp"
full_path = os.path.join(settings.APP_DIR, "images", "playlists", img_path)
full_img_path = os.path.join(settings.APP_DIR, "images", "playlists", img_path)
if file.content_type == "image/gif": if file.content_type == "image/gif":
frames = [] frames = []
@@ -80,9 +98,33 @@ def save_p_image(file: datastructures.FileStorage, pid: str):
for frame in ImageSequence.Iterator(img): for frame in ImageSequence.Iterator(img):
frames.append(frame.copy()) frames.append(frame.copy())
frames[0].save(full_path, save_all=True, append_images=frames[1:]) frames[0].save(full_img_path, save_all=True, append_images=frames[1:])
return img_path thumb_path = create_thumbnail(img, img_path=img_path)
img.save(full_path, "webp") return img_path, thumb_path
return img_path img.save(full_img_path, "webp")
thumb_path = create_thumbnail(img, img_path=img_path)
return img_path, thumb_path
def validate_images():
"""
Removes all unused images in the images/playlists folder.
"""
images = []
for playlist in api.PLAYLISTS:
if playlist.image:
img_path = playlist.image.split("/")[-1]
thumb_path = playlist.thumb.split("/")[-1]
images.append(img_path)
images.append(thumb_path)
p_path = os.path.join(settings.APP_DIR, "images", "playlists")
for image in os.listdir(p_path):
if image not in images:
os.remove(os.path.join(p_path, image))
+7 -2
View File
@@ -73,9 +73,11 @@ class Album:
def get_p_track(ptrack): def get_p_track(ptrack):
for track in api.TRACKS: for track in api.TRACKS:
if (track.title == ptrack["title"] if (
track.title == ptrack["title"]
and track.artists == ptrack["artists"] and track.artists == ptrack["artists"]
and ptrack["album"] == track.album): and ptrack["album"] == track.album
):
return track return track
@@ -103,6 +105,7 @@ class Playlist:
_pre_tracks: list = field(init=False, repr=False) _pre_tracks: list = field(init=False, repr=False)
lastUpdated: int lastUpdated: int
image: str image: str
thumb: str
description: str = "" description: str = ""
count: int = 0 count: int = 0
"""A list of track objects in the playlist""" """A list of track objects in the playlist"""
@@ -112,6 +115,7 @@ class Playlist:
self.name = data["name"] self.name = data["name"]
self.description = data["description"] self.description = data["description"]
self.image = self.create_img_link(data["image"]) self.image = self.create_img_link(data["image"])
self.thumb = self.create_img_link(data["thumb"])
self._pre_tracks = data["pre_tracks"] self._pre_tracks = data["pre_tracks"]
self.tracks = [] self.tracks = []
self.lastUpdated = data["lastUpdated"] self.lastUpdated = data["lastUpdated"]
@@ -149,6 +153,7 @@ class Playlist:
if data["image"]: if data["image"]:
self.image = self.create_img_link(data["image"]) self.image = self.create_img_link(data["image"])
self.thumb = self.create_img_link(data["thumb"])
@dataclass @dataclass
+3
View File
@@ -0,0 +1,3 @@
"""
This module contains patch functions to modify existing data in the database.
"""
+2
View File
@@ -58,6 +58,7 @@ class Playlist:
playlistid: str playlistid: str
name: str name: str
image: str image: str
thumb: str
lastUpdated: int lastUpdated: int
description: str description: str
count: int = 0 count: int = 0
@@ -68,6 +69,7 @@ class Playlist:
self.playlistid = p.playlistid self.playlistid = p.playlistid
self.name = p.name self.name = p.name
self.image = p.image self.image = p.image
self.thumb = p.thumb
self.lastUpdated = p.lastUpdated self.lastUpdated = p.lastUpdated
self.description = p.description self.description = p.description
self.count = p.count self.count = p.count
+1
View File
@@ -103,5 +103,6 @@ app_dom.addEventListener("click", (e) => {
padding: 0 $small; padding: 0 $small;
display: grid; display: grid;
grid-template-rows: 1fr; grid-template-rows: 1fr;
margin-top: $small;
} }
</style> </style>
+3 -3
View File
@@ -44,7 +44,7 @@ const props = defineProps<{
.a-header { .a-header {
display: grid; display: grid;
grid-template-columns: 13rem 1fr; grid-template-columns: 15rem 1fr;
padding: 1rem; padding: 1rem;
height: 100%; height: 100%;
background-color: $gray4; background-color: $gray4;
@@ -58,8 +58,8 @@ const props = defineProps<{
align-items: flex-end; align-items: flex-end;
.image { .image {
width: 12rem; width: 14rem;
height: 12rem; height: 14rem;
} }
} }
-59
View File
@@ -1,59 +0,0 @@
<template>
<div class="folder-top flex">
<div class="fname">
<PlayBtnRect />
<div class="ftext">
<div class="icon image"></div>
<div class="ellip">
{{ folder.path.split("/").splice(-1).join("") }}
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import useFStore from "../../stores/folder";
import PlayBtnRect from "../shared/PlayBtnRect.vue";
const folder = useFStore();
</script>
<style lang="scss">
.folder-top {
border-bottom: 1px solid $separator;
width: calc(100% - 0.5rem);
padding-bottom: $small;
height: 3rem;
}
.folder-top .fname {
width: 100%;
display: flex;
gap: $small;
align-items: center;
.ftext {
position: relative;
display: flex;
align-items: center;
height: 2.5rem;
border-radius: $small;
background-color: $primary;
padding: $small $small $small 2.25rem;
.icon {
position: absolute;
left: $small;
height: 1.5rem;
width: 1.5rem;
background-image: url(../../assets/icons/folder.fill.svg);
margin-right: $small;
}
@include phone-only {
display: none;
}
}
}
</style>
@@ -1,9 +1,8 @@
<template> <template>
<div id="playing-from" class="rounded" @click="goTo"> <div id="playing-from" class="rounded" @click="goTo">
<div class="abs shadow-sm">Playing From</div>
<div class="h"> <div class="h">
<div class="icon image" :class="from.type"></div> <div class="icon image" :class="from.type"></div>
{{ from.type }} Playing from
</div> </div>
<div class="name"> <div class="name">
<div id="to"> <div id="to">
@@ -100,27 +99,17 @@ function goTo() {
<style lang="scss"> <style lang="scss">
#playing-from { #playing-from {
background: linear-gradient(-200deg, $gray4 40%, $red, $gray4);
background-size: 120%; background-size: 120%;
padding: 0.75rem; padding: 0.75rem;
cursor: pointer; cursor: pointer;
position: relative; position: relative;
transition: all .2s ease; transition: all .2s ease;
background-color: $accent;
&:hover { &:hover {
background-position: -4rem; background-position: -4rem;
} }
.abs {
position: absolute;
right: $small;
bottom: $small;
font-size: .9rem;
background-color: $gray;
padding: $smaller;
border-radius: .25rem;
}
.name { .name {
text-transform: capitalize; text-transform: capitalize;
font-weight: bolder; font-weight: bolder;
@@ -133,7 +122,7 @@ function goTo() {
align-items: center; align-items: center;
gap: $small; gap: $small;
text-transform: capitalize; text-transform: capitalize;
color: rgba(255, 255, 255, 0.664); color: rgba(255, 255, 255, 0.849);
.icon { .icon {
height: 1.25rem; height: 1.25rem;
+60 -7
View File
@@ -1,31 +1,50 @@
<template> <template>
<div class="topnav rounded"> <div class="topnav">
<div class="left"> <div class="left">
<div class="btn"> <div class="btn">
<PlayBtn /> <NavButtons />
</div> </div>
<div class="info"> <div class="info">
<div class="title">Playlists</div> <div class="title" v-if="$route.name == 'Playlists'">Playlists</div>
<div class="folder" v-else-if="$route.name == 'FolderView'">
<div class="play">
<PlayBtnRect />
</div>
<div class="fname">
<div class="icon image"></div>
<div class="ellip">
{{ $route.params.path.split("/").splice(-1)[0] }}
</div> </div>
</div> </div>
</div>
</div>
</div>
<div class="center rounded"> <div class="center rounded">
<Loader /> <Loader />
</div> </div>
<div class="right"></div> <div class="right">
<Search />
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import PlayBtn from "../shared/PlayBtn.vue"; import NavButtons from "./NavButtons.vue";
import Loader from "../shared/Loader.vue"; import Loader from "../shared/Loader.vue";
import PlayBtnRect from "../shared/PlayBtnRect.vue";
import Search from "./Search.vue";
</script> </script>
<style lang="scss"> <style lang="scss">
.topnav { .topnav {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: 1fr max-content max-content;
padding: 0 $small; padding-bottom: 1rem;
margin: $small $small 0 $small; margin: $small $small 0 $small;
border-bottom: 1px solid $gray3;
height: 3rem;
.left { .left {
display: flex; display: flex;
@@ -37,12 +56,46 @@ import Loader from "../shared/Loader.vue";
font-size: 1.5rem; font-size: 1.5rem;
font-weight: bold; font-weight: bold;
} }
.folder {
display: flex;
gap: 1rem;
.playbtnrect {
height: 2.25rem;
}
.fname {
position: relative;
padding-left: 2.25rem;
background-color: $gray4;
border-radius: $small;
height: 2.25rem;
display: flex;
align-items: center;
padding-right: $small;
.icon {
position: absolute;
left: $small;
top: $small;
width: 1.5rem;
height: 1.5rem;
background-image: url("../../assets/icons/folder.fill.svg");
}
}
}
} }
} }
.center { .center {
display: grid; display: grid;
place-items: center; place-items: center;
margin-right: 1rem;
}
.right {
width: 100%;
} }
} }
</style> </style>
+44
View File
@@ -0,0 +1,44 @@
<template>
<div id="back-forward">
<div class="back image" @click="$router.back()"></div>
<div class="forward image" @click="$router.forward()"></div>
</div>
</template>
<script setup>
console.log();
</script>
<style lang="scss">
#back-forward {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
padding-right: 1rem;
margin-right: $small;
border-right: 1px solid $gray3;
& > div {
background-color: $gray4;
border-radius: $small;
height: 2.25rem;
width: 2.25rem;
cursor: pointer;
background-size: 2rem;
transition: all .25s ease-in-out;
&:hover {
background-color: $accent;
}
}
.back {
background-image: url("../../assets/icons/right-arrow.svg");
transform: rotate(180deg);
}
.forward {
background-image: url("../../assets/icons/right-arrow.svg");
}
}
</style>
+36
View File
@@ -0,0 +1,36 @@
<template>
<div id="nav-search">
<form>
<input
type="search"
name=""
id=""
placeholder="Search this playlist"
class="rounded"
/>
</form>
</div>
</template>
<style lang="scss">
#nav-search {
form {
display: flex;
gap: $small;
input[type="search"] {
background-color: $gray5;
border: none;
padding: $small;
width: 100%;
min-width: 24rem;
color: $white;
font-size: 1rem;
&:focus {
outline: solid $accent;
}
}
}
}
</style>
+9 -7
View File
@@ -3,6 +3,7 @@
<div class="gradient rounded"></div> <div class="gradient rounded"></div>
<div class="plus image p-image"></div> <div class="plus image p-image"></div>
<div>New Playlist</div> <div>New Playlist</div>
<div></div>
</div> </div>
</template> </template>
@@ -10,30 +11,31 @@
#new-playlist-card { #new-playlist-card {
display: grid; display: grid;
place-items: center; place-items: center;
background-color: $black;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
.gradient { .gradient {
position: absolute; position: absolute;
width: calc(100% - 2rem); width: calc(100% - 1.5rem);
height: 10rem; top: 0.75rem;
top: 1rem;
background-image: linear-gradient(37deg, $red, $blue); background-image: linear-gradient(37deg, $red, $blue);
background-size: 100%; background-size: 100%;
transition: all .5s ease-in-out; transition: all 0.5s ease-in-out;
aspect-ratio: 1;
} }
.image { .image {
background-image: url("../../assets/icons/plus.svg"); background-image: url("../../assets/icons/plus.svg");
background-size: 5rem; background-size: 5rem;
z-index: 1; z-index: 1;
transition: all .5s ease-in-out; transition: all 0.5s ease-in-out;
background-color: transparent;
margin-bottom: $small;
} }
&:hover { &:hover {
.gradient { .gradient {
background-size: 30rem; background-size: 300rem;
} }
.image { .image {
transform: rotate(270deg); transform: rotate(270deg);
+11 -7
View File
@@ -10,7 +10,7 @@
<div <div
class="image p-image rounded shadow-sm" class="image p-image rounded shadow-sm"
:style="{ :style="{
backgroundImage: `url(${props.playlist.image})`, backgroundImage: `url(${props.playlist.thumb})`,
}" }"
></div> ></div>
<div class="pbtn"> <div class="pbtn">
@@ -37,21 +37,21 @@ import Option from "../shared/Option.vue";
const props = defineProps<{ const props = defineProps<{
playlist: Playlist; playlist: Playlist;
}>(); }>();
</script> </script>
<style lang="scss"> <style lang="scss">
.p-card { .p-card {
width: 100%; width: 100%;
padding: 0.75rem; padding: 0.75rem;
transition: all 0.2s ease; transition: all 0.25s ease;
background-image: linear-gradient(37deg, #000000e8, $gray); background-position: -10rem;
position: relative; position: relative;
.p-image { .p-image {
min-width: 100%; min-width: 100%;
height: 10rem;
transition: all 0.2s ease; transition: all 0.2s ease;
background-color: $gray4;
aspect-ratio: 1;
} }
.drop { .drop {
@@ -60,6 +60,7 @@ const props = defineProps<{
right: 1.25rem; right: 1.25rem;
opacity: 0; opacity: 0;
transition: all 0.25s ease-in-out; transition: all 0.25s ease-in-out;
display: none;
.drop-btn { .drop-btn {
background-color: $gray3; background-color: $gray3;
@@ -67,6 +68,7 @@ const props = defineProps<{
} }
.pbtn { .pbtn {
display: none;
position: absolute; position: absolute;
bottom: 4.5rem; bottom: 4.5rem;
left: 1.25rem; left: 1.25rem;
@@ -75,10 +77,12 @@ const props = defineProps<{
} }
&:hover { &:hover {
background-color: $gray5;
.drop { .drop {
transition-delay: .75s; transition-delay: 0.75s;
opacity: 1; opacity: 1;
transform: translate(0, -.5rem); transform: translate(0, -0.5rem);
} }
} }
+3 -2
View File
@@ -1,13 +1,13 @@
<template> <template>
<div class="loaderx" :class="{ loader: loading, not_loader: !loading }"> <div class="loaderx" :class="{ loader: loading, not_loader: !loading }">
<div v-if="!loading">😹</div> <div v-if="!loading">🦋</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import state from "@/composables/state"; import state from "@/composables/state";
const loading = state.loading const loading = state.loading;
</script> </script>
<style lang="scss"> <style lang="scss">
@@ -15,6 +15,7 @@ const loading = state.loading
width: 1.5rem; width: 1.5rem;
height: 1.5rem; height: 1.5rem;
border-radius: 50%; border-radius: 50%;
user-select: none;
} }
.loader { .loader {
+1 -1
View File
@@ -56,7 +56,7 @@ interface Playlist {
tracks?: Track[]; tracks?: Track[];
count?: number; count?: number;
lastUpdated?: string; lastUpdated?: string;
color?: string; thumb?: string;
} }
interface Notif { interface Notif {
+1
View File
@@ -21,6 +21,7 @@ export default defineStore("album", {
this.tracks = tracks.tracks; this.tracks = tracks.tracks;
this.info = tracks.info; this.info = tracks.info;
this.artists = artists; this.artists = artists;
this.bio = null;
}, },
fetchBio(title: string, albumartist: string) { fetchBio(title: string, albumartist: string) {
getAlbumBio(title, albumartist).then((bio) => { getAlbumBio(title, albumartist).then((bio) => {
+1 -1
View File
@@ -46,7 +46,7 @@ onBeforeRouteUpdate(async (to) => {
.songs { .songs {
padding: $small; padding: $small;
min-height: calc(100% - 30rem); min-height: calc(100% - 32rem);
} }
&::-webkit-scrollbar { &::-webkit-scrollbar {
+8 -11
View File
@@ -1,8 +1,5 @@
<template> <template>
<div id="f-view-parent" class="rounded"> <div id="f-view-parent" class="rounded">
<div class="fixed">
<Header :path="FStore.path" :first_song="FStore.tracks[0]" />
</div>
<div id="scrollable" ref="scrollable"> <div id="scrollable" ref="scrollable">
<FolderList :folders="FStore.dirs" /> <FolderList :folders="FStore.dirs" />
<div <div
@@ -20,7 +17,6 @@ import { onBeforeRouteUpdate } from "vue-router";
import SongList from "@/components/FolderView/SongList.vue"; import SongList from "@/components/FolderView/SongList.vue";
import FolderList from "@/components/FolderView/FolderList.vue"; import FolderList from "@/components/FolderView/FolderList.vue";
import Header from "@/components/FolderView/Header.vue";
import useFStore from "../stores/folder"; import useFStore from "../stores/folder";
import state from "../composables/state"; import state from "../composables/state";
@@ -44,9 +40,10 @@ onBeforeRouteUpdate((to) => {
<style lang="scss"> <style lang="scss">
#f-view-parent { #f-view-parent {
position: relative; position: relative;
padding: 4rem $small 0 $small; padding: 0 $small 0 $small;
overflow: hidden; overflow: hidden;
margin: $small; margin: $small;
margin-top: $small;
.h { .h {
font-size: 2rem; font-size: 2rem;
@@ -54,12 +51,12 @@ onBeforeRouteUpdate((to) => {
} }
} }
#f-view-parent .fixed { // #f-view-parent .fixed {
position: absolute; // position: absolute;
height: min-content; // height: min-content;
width: calc(100% - 1rem); // width: calc(100% - 1rem);
top: 0.5rem; // top: 0.5rem;
} // }
#scrollable { #scrollable {
overflow-y: auto; overflow-y: auto;
+1 -1
View File
@@ -49,7 +49,7 @@ const playlist = usePTrackStore();
} }
.songlist { .songlist {
padding: $small; padding: $small;
min-height: calc(100% - 30rem); min-height: calc(100% - 32rem);
} }
} }
</style> </style>
+2 -2
View File
@@ -22,15 +22,15 @@ const pStore = usePStore();
<style lang="scss"> <style lang="scss">
#p-view { #p-view {
margin: $small; margin: $small;
margin-top: 0;
padding: $small; padding: $small;
overflow: auto; overflow: auto;
scrollbar-color: $gray2 transparent; scrollbar-color: $gray2 transparent;
border-top: 1px solid $gray3;
.grid { .grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
gap: $small; gap: 1rem;
} }
} }
</style> </style>