mirror of
https://github.com/tcsenpai/swingmusic.git
synced 2025-06-10 13:07:35 +00:00
fix albumView using watch function
- other minor changes to almost all files
This commit is contained in:
parent
bdfbb59d76
commit
73dec9189e
@ -28,6 +28,8 @@ def adutsfsd():
|
|||||||
|
|
||||||
@bp.route('/search')
|
@bp.route('/search')
|
||||||
def search_by_title():
|
def search_by_title():
|
||||||
|
query:str = ""
|
||||||
|
|
||||||
if not request.args.get('q'):
|
if not request.args.get('q'):
|
||||||
query = "mexican girl"
|
query = "mexican girl"
|
||||||
else:
|
else:
|
||||||
@ -83,20 +85,20 @@ def search_by_title():
|
|||||||
else:
|
else:
|
||||||
more_tracks = False
|
more_tracks = False
|
||||||
|
|
||||||
if len(artists_dicts) > 8:
|
if len(artists_dicts) > 6:
|
||||||
more_artists = True
|
more_artists = True
|
||||||
else:
|
else:
|
||||||
more_artists = False
|
more_artists = False
|
||||||
|
|
||||||
if len(albums_dicts) > 8:
|
if len(albums_dicts) > 6:
|
||||||
more_albums = True
|
more_albums = True
|
||||||
else:
|
else:
|
||||||
more_albums = False
|
more_albums = False
|
||||||
|
|
||||||
return {'data': [
|
return {'data': [
|
||||||
{'tracks': tracks[:5], 'more': more_tracks},
|
{'tracks': tracks[:5], 'more': more_tracks},
|
||||||
{'albums': albums_dicts[:8], 'more': more_albums},
|
{'albums': albums_dicts[:6], 'more': more_albums},
|
||||||
{'artists': artists_dicts[:8], 'more': more_artists}
|
{'artists': artists_dicts[:6], 'more': more_artists}
|
||||||
]}
|
]}
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ def populate_images():
|
|||||||
bar.finish()
|
bar.finish()
|
||||||
|
|
||||||
|
|
||||||
def extract_thumb(audio_file_path: str = None) -> str:
|
def extract_thumb(audio_file_path: str) -> str:
|
||||||
"""
|
"""
|
||||||
Extracts the thumbnail from an audio file. Returns the path to the thumbnail.
|
Extracts the thumbnail from an audio file. Returns the path to the thumbnail.
|
||||||
"""
|
"""
|
||||||
|
@ -5,6 +5,7 @@ This module contains mimi functions for the server.
|
|||||||
import os
|
import os
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
from typing import List
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
@ -37,10 +38,11 @@ def check_for_new_songs():
|
|||||||
|
|
||||||
while flag is False:
|
while flag is False:
|
||||||
functions.populate()
|
functions.populate()
|
||||||
|
functions.populate_images()
|
||||||
time.sleep(300)
|
time.sleep(300)
|
||||||
|
|
||||||
|
|
||||||
def run_fast_scandir(dir: str, ext: str) -> list:
|
def run_fast_scandir(dir: str, ext: str):
|
||||||
"""
|
"""
|
||||||
Scans a directory for files with a specific extension. Returns a list of files and folders in the directory.
|
Scans a directory for files with a specific extension. Returns a list of files and folders in the directory.
|
||||||
"""
|
"""
|
||||||
@ -125,7 +127,7 @@ def create_config_dir() -> None:
|
|||||||
|
|
||||||
os.chmod(path, 0o755)
|
os.chmod(path, 0o755)
|
||||||
|
|
||||||
def getAllSongs() -> None:
|
def getAllSongs() -> List:
|
||||||
"""
|
"""
|
||||||
Gets all songs under the ~/ directory.
|
Gets all songs under the ~/ directory.
|
||||||
"""
|
"""
|
||||||
|
@ -67,7 +67,6 @@ export default {
|
|||||||
|
|
||||||
#toggle {
|
#toggle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0.2rem;
|
|
||||||
width: 3rem;
|
width: 3rem;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: url(./assets/icons/menu.svg);
|
background: url(./assets/icons/menu.svg);
|
||||||
|
@ -21,18 +21,20 @@ input[type="range"]::-webkit-slider-thumb {
|
|||||||
|
|
||||||
input[type="range"]::-moz-range-thumb {
|
input[type="range"]::-moz-range-thumb {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
height: 1rem;
|
height: 0.8rem;
|
||||||
width: 1rem;
|
width: 0.8rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: $blue;
|
background: $blue;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-ms-thumb {
|
input[type="range"]::-ms-thumb {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
height: 1rem;
|
height: 0.8rem;
|
||||||
width: 1rem;
|
width: 0.8rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: $blue;
|
background: $blue;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-thumb:hover {
|
input[type="range"]::-webkit-slider-thumb:hover {
|
||||||
|
@ -8,11 +8,10 @@
|
|||||||
width: auto;
|
width: auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: $small $small 0 $small;
|
padding: $small $small 0 $small;
|
||||||
// margin: $small 0 $small 0;
|
|
||||||
|
|
||||||
.no-res {
|
.no-res {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: calc(100% - 1rem);
|
// height: calc(100% - 1rem);
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
||||||
.highlight {
|
.highlight {
|
||||||
@ -45,30 +44,6 @@
|
|||||||
background-image: url(../../icons/search.svg);
|
background-image: url(../../icons/search.svg);
|
||||||
background-size: 70%;
|
background-size: 70%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v11 {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-4rem);
|
|
||||||
transition: all 0.2s ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v00 {
|
|
||||||
opacity: 1;
|
|
||||||
transition: all 0.2s ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
.suggestions {
|
|
||||||
display: flex;
|
|
||||||
gap: 0.5rem;
|
|
||||||
margin-left: 1rem;
|
|
||||||
position: absolute;
|
|
||||||
right: 2.5rem;
|
|
||||||
|
|
||||||
.item::before {
|
|
||||||
content: "#";
|
|
||||||
color: grey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-search .scrollable {
|
.right-search .scrollable {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="b-bar border card-dark">
|
<div class="b-bar border card-dark">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<SongCard />
|
<SongCard/>
|
||||||
<div class="controlsx border rounded">
|
<div class="controlsx border rounded">
|
||||||
<div class="controls controls-bottom">
|
<div class="controls controls-bottom">
|
||||||
<HotKeys />
|
<HotKeys />
|
||||||
@ -9,7 +9,7 @@
|
|||||||
<div class="progress progress-bottom">
|
<div class="progress progress-bottom">
|
||||||
<span class="durationx">0:45</span>
|
<span class="durationx">0:45</span>
|
||||||
<Progress />
|
<Progress />
|
||||||
<span class="durationx">3:55</span>
|
<span class="durationx">{{ state.current.value.length }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="r-group">
|
<div class="r-group">
|
||||||
<div class="heart image"></div>
|
<div class="heart image"></div>
|
||||||
@ -18,24 +18,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="controls controls-bottom"></div>
|
<div class="controls controls-bottom"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="volume-group">
|
<div class="volume-group"></div>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
|
||||||
import "../../assets/css/BottomBar/BottomBar.scss";
|
import "../../assets/css/BottomBar/BottomBar.scss";
|
||||||
import playAudio from "../../composables/playAudio";
|
|
||||||
import SongCard from "./SongCard.vue";
|
import SongCard from "./SongCard.vue";
|
||||||
import Progress from "../shared/Progress.vue";
|
import Progress from "../shared/Progress.vue";
|
||||||
import HotKeys from "../shared/HotKeys.vue";
|
import HotKeys from "../shared/HotKeys.vue";
|
||||||
|
import state from "../../composables/state";
|
||||||
const isPlaying = ref(playAudio.playing);
|
|
||||||
|
|
||||||
const { playNext } = playAudio;
|
|
||||||
const { playPrev } = playAudio;
|
|
||||||
const { playPause } = playAudio;
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -26,8 +26,9 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import perks from "../../composables/perks";
|
import perks from "../../composables/perks";
|
||||||
|
import state from "../../composables/state";
|
||||||
|
|
||||||
const track = ref(perks.current);
|
const track = ref(state.current);
|
||||||
|
|
||||||
const putCommas = perks.putCommas;
|
const putCommas = perks.putCommas;
|
||||||
</script>
|
</script>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<SongItem
|
<SongItem
|
||||||
v-for="(song, index) in props.songs"
|
v-for="(song, index) in props.songs"
|
||||||
:key="song"
|
:key="song.id"
|
||||||
:song="song"
|
:song="song"
|
||||||
:index="index + 1"
|
:index="index + 1"
|
||||||
@updateQueue="updateQueue"
|
@updateQueue="updateQueue"
|
||||||
@ -25,8 +25,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else-if="props.songs.length === 0 && search_query">
|
<div v-else-if="props.songs.length === 0 && search_query">
|
||||||
<div class="no-results">
|
<div class="no-results">
|
||||||
<div class="icon"></div>
|
<div class="text">Nothing down here 😑</div>
|
||||||
<div class="text">No tracks 🎸</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else ref="songtitle"></div>
|
<div v-else ref="songtitle"></div>
|
||||||
@ -47,8 +46,8 @@ import state from "@/composables/state.js";
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
songs: {
|
songs: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
required: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let route;
|
let route;
|
||||||
@ -85,7 +84,15 @@ function loadAlbum(title, album_artist) {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
|
||||||
|
// .icon {
|
||||||
|
// height: 10rem;
|
||||||
|
// width: 15rem;
|
||||||
|
// border: solid;
|
||||||
|
// background-image: url("../../assets/images/sokka.webp");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
.table {
|
.table {
|
||||||
@ -138,7 +145,7 @@ table {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
width: 5rem;
|
width: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
th.album-header {
|
th.album-header {
|
||||||
@ -152,4 +159,4 @@ table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -110,6 +110,7 @@ export default {
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
overflow-x: scroll;
|
overflow-x: scroll;
|
||||||
|
gap: $small;
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="r-sidebar">
|
<div class="r-sidebar">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="r-content border rounded">
|
<div class="r-content rounded">
|
||||||
<div class="r-dash" v-if="current_tab == tabs.home">
|
<div class="r-dash" v-show="current_tab == tabs.home">
|
||||||
<DashBoard/>
|
<DashBoard />
|
||||||
</div>
|
</div>
|
||||||
<div class="r-search" v-if="current_tab == tabs.search">
|
<div class="r-search" v-show="current_tab == tabs.search">
|
||||||
<Search
|
<Search />
|
||||||
v-model:search="search"
|
|
||||||
@expandSearch="expandSearch"
|
|
||||||
@collapseSearch="collapseSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="r-queue" v-if="current_tab == tabs.queue">
|
<div class="r-queue" v-show="current_tab == tabs.queue">
|
||||||
<UpNext v-model:up_next="up_next" @expandQueue="expandQueue" />
|
<UpNext />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-keys card-dark border">
|
<div class="tab-keys card-dark border">
|
||||||
@ -33,28 +29,13 @@ import Main from "./Home/Main.vue";
|
|||||||
|
|
||||||
const DashBoard = Main;
|
const DashBoard = Main;
|
||||||
|
|
||||||
let up_next = ref(true);
|
|
||||||
let search = ref(false);
|
|
||||||
|
|
||||||
const expandQueue = () => {
|
|
||||||
up_next.value = !up_next.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const expandSearch = () => {
|
|
||||||
search.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const collapseSearch = () => {
|
|
||||||
search.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const tabs = {
|
const tabs = {
|
||||||
home: "home",
|
home: "home",
|
||||||
search: "search",
|
search: "search",
|
||||||
queue: "queue",
|
queue: "queue",
|
||||||
};
|
};
|
||||||
|
|
||||||
const current_tab = ref(tabs.search);
|
const current_tab = ref(tabs.queue);
|
||||||
|
|
||||||
function changeTab(tab) {
|
function changeTab(tab) {
|
||||||
current_tab.value = tab;
|
current_tab.value = tab;
|
||||||
@ -63,18 +44,30 @@ function changeTab(tab) {
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.r-sidebar {
|
.r-sidebar {
|
||||||
width: 34em;
|
width: 34.5em;
|
||||||
|
margin: $small 0 $small 0;
|
||||||
|
|
||||||
|
@include phone-only {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @include tablet-landscape {
|
||||||
|
// width: 3rem;
|
||||||
|
// }
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-areas: "content tabs";
|
position: relative;
|
||||||
|
|
||||||
.r-content {
|
.r-content {
|
||||||
grid-area: content;
|
grid-area: content;
|
||||||
width: 100%;
|
width: 31rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: $small $small $small 0;
|
|
||||||
|
// @include tablet-landscape {
|
||||||
|
// display: none;
|
||||||
|
// }
|
||||||
|
|
||||||
.r-search {
|
.r-search {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -90,10 +83,12 @@ function changeTab(tab) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tab-keys {
|
.tab-keys {
|
||||||
|
right: 0;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
grid-area: tabs;
|
grid-area: tabs;
|
||||||
width: 3rem;
|
|
||||||
padding: $small;
|
padding: $small;
|
||||||
margin-left: $small;
|
border-radius: $small 0 0 $small;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,10 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="scrollable-r border">
|
<div class="scrl border rounded">
|
||||||
<TrackItem v-for="song in queue" :key="song" :track="song" />
|
<div class="scrollable-r">
|
||||||
|
<TrackItem v-for="song in queue" :key="song.id" :track="song" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -76,8 +78,6 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.heading {
|
.heading {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0.5rem 0 1rem 0;
|
margin: 0.5rem 0 1rem 0;
|
||||||
@ -127,13 +127,19 @@ export default {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: min-content 1fr;
|
grid-template-rows: min-content 1fr;
|
||||||
|
padding-bottom: $small;
|
||||||
|
|
||||||
|
.scrl {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.scrollable-r {
|
.scrollable-r {
|
||||||
margin-bottom: $small;
|
height: 100%;
|
||||||
padding: $small;
|
padding: $small;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: $card-dark;
|
background-color: $card-dark;
|
||||||
border-radius: 0.5rem;
|
scrollbar-color: grey transparent;
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
&::-webkit-scrollbar-track {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="right-search" ref="searchComponent">
|
<div class="right-search border">
|
||||||
<div>
|
<div>
|
||||||
<div class="input">
|
<div class="input">
|
||||||
<Loader />
|
<Loader />
|
||||||
@ -8,29 +8,17 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="search"
|
id="search"
|
||||||
@focus="activateMagicFlag"
|
|
||||||
@blur="removeMagicFlag"
|
|
||||||
@keyup.backspace="removeLastFilter"
|
@keyup.backspace="removeLastFilter"
|
||||||
placeholder="find your music"
|
placeholder="find your music"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
/>
|
/>
|
||||||
<div class="search-icon image"></div>
|
<div class="search-icon image"></div>
|
||||||
<!-- -->
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="suggestions v00"
|
|
||||||
:class="{
|
|
||||||
v00: !filters.length && !query,
|
|
||||||
v11: filters.length || query,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div class="item">Kenny Rogers</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="separator no-border"></div>
|
<div class="separator no-border"></div>
|
||||||
<Options :magic_flag="magic_flag" @addFilter="addFilter" />
|
<Options @addFilter="addFilter" />
|
||||||
</div>
|
</div>
|
||||||
<div class="scrollable" :class="{ v0: !is_hidden, v1: is_hidden }">
|
<div class="scrollable">
|
||||||
<TracksGrid
|
<TracksGrid
|
||||||
:tracks="tracks.tracks"
|
:tracks="tracks.tracks"
|
||||||
:more="tracks.more"
|
:more="tracks.more"
|
||||||
@ -52,22 +40,24 @@
|
|||||||
v-if="
|
v-if="
|
||||||
!artists.artists.length &&
|
!artists.artists.length &&
|
||||||
!tracks.tracks.length &&
|
!tracks.tracks.length &&
|
||||||
!albums.albums.length
|
!albums.albums.length && query.length != 0
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class="no-res-icon image"></div>
|
|
||||||
<div class="no-res-text">
|
<div class="no-res-text">
|
||||||
No results for <span class="highlight rounded">{{ query }}</span>
|
No results for <span class="highlight rounded">{{ query }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else-if="query.length == 0" class="no-res">
|
||||||
|
<div class="no-res-text">Find your music 🔍😀</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { reactive, ref, toRefs } from "@vue/reactivity";
|
import { reactive, ref } from "@vue/reactivity";
|
||||||
|
|
||||||
import { onMounted, watch } from "@vue/runtime-core";
|
import { watch } from "@vue/runtime-core";
|
||||||
import state from "@/composables/state.js";
|
import state from "@/composables/state.js";
|
||||||
import searchMusic from "@/composables/searchMusic.js";
|
import searchMusic from "@/composables/searchMusic.js";
|
||||||
import useDebouncedRef from "@/composables/useDebouncedRef";
|
import useDebouncedRef from "@/composables/useDebouncedRef";
|
||||||
@ -80,8 +70,6 @@ import Filters from "@/components/Search/Filters.vue";
|
|||||||
import "@/assets/css/Search/Search.scss";
|
import "@/assets/css/Search/Search.scss";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
emits: ["expandSearch", "collapseSearch"],
|
|
||||||
props: ["search"],
|
|
||||||
components: {
|
components: {
|
||||||
AlbumGrid,
|
AlbumGrid,
|
||||||
ArtistGrid,
|
ArtistGrid,
|
||||||
@ -91,9 +79,8 @@ export default {
|
|||||||
Filters,
|
Filters,
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props, { emit }) {
|
setup() {
|
||||||
const loading = ref(state.loading);
|
const loading = ref(state.loading);
|
||||||
const searchComponent = ref(null);
|
|
||||||
const filters = ref([]);
|
const filters = ref([]);
|
||||||
|
|
||||||
const tracks = reactive({
|
const tracks = reactive({
|
||||||
@ -111,9 +98,7 @@ export default {
|
|||||||
more: false,
|
more: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const query = useDebouncedRef("", 400);
|
const query = useDebouncedRef("", 600);
|
||||||
const magic_flag = ref(state.magic_flag);
|
|
||||||
const is_hidden = toRefs(props).search;
|
|
||||||
|
|
||||||
function addFilter(filter) {
|
function addFilter(filter) {
|
||||||
if (!filters.value.includes(filter)) {
|
if (!filters.value.includes(filter)) {
|
||||||
@ -137,24 +122,15 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function activateMagicFlag() {
|
|
||||||
setTimeout(() => {
|
|
||||||
state.magic_flag.value = true;
|
|
||||||
}, 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeMagicFlag() {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (
|
|
||||||
(!filters.value.length && query.value == null) ||
|
|
||||||
query.value == ""
|
|
||||||
) {
|
|
||||||
state.magic_flag.value = false;
|
|
||||||
}
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(query, (new_query) => {
|
watch(query, (new_query) => {
|
||||||
|
if (query.value == "" || query.value == " " || query.value.length < 2) {
|
||||||
|
albums.albums = [];
|
||||||
|
artists.artists = [];
|
||||||
|
tracks.tracks = [];
|
||||||
|
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
searchMusic(new_query).then((res) => {
|
searchMusic(new_query).then((res) => {
|
||||||
albums.albums = res.albums.albums;
|
albums.albums = res.albums.albums;
|
||||||
albums.more = res.albums.more;
|
albums.more = res.albums.more;
|
||||||
@ -165,43 +141,19 @@ export default {
|
|||||||
tracks.tracks = res.tracks.tracks;
|
tracks.tracks = res.tracks.tracks;
|
||||||
tracks.more = res.tracks.more;
|
tracks.more = res.tracks.more;
|
||||||
});
|
});
|
||||||
|
|
||||||
state.search_query.value = new_query;
|
|
||||||
if (new_query !== "" && new_query.length > 2) {
|
|
||||||
counter = 0;
|
|
||||||
emit("expandSearch");
|
|
||||||
} else {
|
|
||||||
emit("collapseSearch");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
const dom = document.getElementsByClassName("right-search")[0];
|
|
||||||
|
|
||||||
document.addEventListener("click", (e) => {
|
|
||||||
var isClickedInside = dom.contains(e.target);
|
|
||||||
if (!isClickedInside) {
|
|
||||||
emit("collapseSearch");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addFilter,
|
addFilter,
|
||||||
activateMagicFlag,
|
|
||||||
removeMagicFlag,
|
|
||||||
removeFilter,
|
removeFilter,
|
||||||
removeLastFilter,
|
removeLastFilter,
|
||||||
tracks,
|
tracks,
|
||||||
albums,
|
albums,
|
||||||
artists,
|
artists,
|
||||||
query,
|
query,
|
||||||
is_hidden,
|
|
||||||
magic_flag,
|
|
||||||
filters,
|
filters,
|
||||||
searchComponent,
|
|
||||||
loading,
|
loading,
|
||||||
searchMusic,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -34,17 +34,15 @@ export default {
|
|||||||
.right-search .albums-results {
|
.right-search .albums-results {
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background: #0f131b44;
|
background: #0f131b44;
|
||||||
|
|
||||||
margin-top: $small;
|
margin-top: $small;
|
||||||
padding: $small 0;
|
padding-bottom: $small;
|
||||||
|
padding-top: $small;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
|
|
||||||
|
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
padding: 0 0 0 $small;
|
padding: $small $small 0 $small;
|
||||||
gap: $small;
|
gap: $small;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,9 +42,10 @@ export default {
|
|||||||
margin-bottom: $small;
|
margin-bottom: $small;
|
||||||
|
|
||||||
.grid {
|
.grid {
|
||||||
padding: 0 0 0 $small;
|
padding: $small $small 0 $small;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
gap: $small;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -32,8 +32,8 @@ export default {
|
|||||||
margin-left: 2rem;
|
margin-left: 2rem;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
|
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
&:hover {
|
&:hover {
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
|
|
||||||
@ -48,4 +48,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="options border rounded">
|
<div class="options border rounded">
|
||||||
<div class="item info">Filter by:</div>
|
<div class="item info header">Filter by:</div>
|
||||||
<div
|
<div
|
||||||
class="item"
|
class="item"
|
||||||
v-for="option in options"
|
v-for="option in options"
|
||||||
:key="option"
|
:key="option"
|
||||||
@click="addFilter(option.icon)"
|
@click="addFilter(option.icon)"
|
||||||
>
|
>
|
||||||
{{ option.title }}
|
<div>
|
||||||
|
<span class="icon">{{ option.icon }}</span>
|
||||||
|
<span class="title"> {{ option.title }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -18,23 +21,23 @@ export default {
|
|||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
title: "🎵 Track",
|
title: "Track",
|
||||||
icon: "🎵",
|
icon: "🎵",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "💿 Album",
|
title: "Album",
|
||||||
icon: "💿",
|
icon: "💿",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "🙄 Artist",
|
title: "Artist",
|
||||||
icon: "🙄",
|
icon: "🙄",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "😍 Playlist",
|
title: "Playlist",
|
||||||
icon: "😍",
|
icon: "😍",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "📁 Folder",
|
title: "Folder",
|
||||||
icon: "📁",
|
icon: "📁",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -58,6 +61,38 @@ export default {
|
|||||||
|
|
||||||
.item {
|
.item {
|
||||||
margin: $small;
|
margin: $small;
|
||||||
|
width: 2.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
position: absolute;
|
||||||
|
left: 1.5rem;
|
||||||
|
top: 0.5rem;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5rem;
|
||||||
|
left: .75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
width: 5.5rem;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
width: 5.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<TrackItem
|
<TrackItem
|
||||||
v-for="track in props.tracks"
|
v-for="track in props.tracks"
|
||||||
:key="track"
|
:key="track.id"
|
||||||
:track="track"
|
:track="track"
|
||||||
/>
|
/>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -32,6 +32,7 @@ export default {
|
|||||||
border-radius: $small;
|
border-radius: $small;
|
||||||
text-align: left !important;
|
text-align: left !important;
|
||||||
width: 9rem;
|
width: 9rem;
|
||||||
|
// border: solid 1px red !important;
|
||||||
|
|
||||||
.album-art {
|
.album-art {
|
||||||
height: 7rem;
|
height: 7rem;
|
||||||
|
@ -21,7 +21,6 @@ export default {
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0 $small 0 0;
|
|
||||||
|
|
||||||
width: 9em;
|
width: 9em;
|
||||||
height: 11em;
|
height: 11em;
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="ellip">{{ song.title }}</span>
|
<span class="ellip">{{ song.title }}</span>
|
||||||
<div class="separator no-border"></div>
|
|
||||||
<div class="artist ellip">
|
<div class="artist ellip">
|
||||||
<span v-for="artist in putCommas(song.artists)" :key="artist">
|
<span v-for="artist in putCommas(song.artists)" :key="artist">
|
||||||
{{ artist }}
|
{{ artist }}
|
||||||
|
@ -60,6 +60,9 @@ const playThis = (song) => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
|
position: relative;
|
||||||
|
height: 4rem;
|
||||||
|
padding-left: 4rem;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -72,6 +75,8 @@ const playThis = (song) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.album-art {
|
.album-art {
|
||||||
|
position: absolute;
|
||||||
|
left: $small;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -83,7 +88,6 @@ const playThis = (song) => {
|
|||||||
background-image: url(../../assets/images/null.webp);
|
background-image: url(../../assets/images/null.webp);
|
||||||
}
|
}
|
||||||
.artist {
|
.artist {
|
||||||
width: 20rem;
|
|
||||||
font-size: small;
|
font-size: small;
|
||||||
color: rgba(255, 255, 255, 0.637);
|
color: rgba(255, 255, 255, 0.637);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
let base_uri = "http://0.0.0.0:9876";
|
let base_uri = "http://0.0.0.0:9876";
|
||||||
|
|
||||||
const getData = async (path) => {
|
const getTracksAndDirs = async (path) => {
|
||||||
let url;
|
let url;
|
||||||
|
|
||||||
const encoded_path = encodeURIComponent(path.replaceAll("/", "|"));
|
const encoded_path = encodeURIComponent(path.replaceAll("/", "|"));
|
||||||
@ -21,4 +21,4 @@ const getData = async (path) => {
|
|||||||
return { songs, folders };
|
return { songs, folders };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default getData;
|
export default getTracksAndDirs;
|
||||||
|
@ -37,9 +37,7 @@ const putCommas = (artists) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function updateNext(song_) {
|
function updateNext(song_) {
|
||||||
const index = state.queue.value.findIndex(
|
const index = state.queue.value.findIndex((item) => item.id === song_.id);
|
||||||
(item) => item.id === song_.id
|
|
||||||
);
|
|
||||||
|
|
||||||
if (index == queue.value.length - 1) {
|
if (index == queue.value.length - 1) {
|
||||||
next.value = queue.value[0];
|
next.value = queue.value[0];
|
||||||
@ -52,9 +50,7 @@ function updateNext(song_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updatePrev(song) {
|
function updatePrev(song) {
|
||||||
const index = state.queue.value.findIndex(
|
const index = state.queue.value.findIndex((item) => item.id === song.id);
|
||||||
(item) => item.id === song.id
|
|
||||||
);
|
|
||||||
|
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
prev.value = queue.value[queue.value.length - 1];
|
prev.value = queue.value[queue.value.length - 1];
|
||||||
@ -82,7 +78,7 @@ const readQueue = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateQueue = async (song, type) => {
|
const updateQueue = async (song, type) => {
|
||||||
playAudio.playAudio(song.filepath)
|
playAudio.playAudio(song.filepath);
|
||||||
let list;
|
let list;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -93,9 +89,9 @@ const updateQueue = async (song, type) => {
|
|||||||
list = state.album_song_list.value;
|
list = state.album_song_list.value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.queue.value[0].id !==list[0].id) {
|
if (state.queue.value[0].id !== list[0].id) {
|
||||||
const new_queue =list;
|
const new_queue = list;
|
||||||
localStorage.setItem("queue", JSON.stringify(new_queue));
|
localStorage.setItem("queue", JSON.stringify(new_queue));
|
||||||
state.queue.value = new_queue;
|
state.queue.value = new_queue;
|
||||||
}
|
}
|
||||||
@ -152,6 +148,8 @@ window.addEventListener("keydown", (e) => {
|
|||||||
|
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case "ArrowRight":
|
case "ArrowRight":
|
||||||
|
if (target.tagName == "INPUT") return;
|
||||||
|
|
||||||
{
|
{
|
||||||
if (!key_down_fired) {
|
if (!key_down_fired) {
|
||||||
key_down_fired = true;
|
key_down_fired = true;
|
||||||
@ -168,6 +166,8 @@ window.addEventListener("keydown", (e) => {
|
|||||||
case "ArrowLeft":
|
case "ArrowLeft":
|
||||||
{
|
{
|
||||||
if (!key_down_fired) {
|
if (!key_down_fired) {
|
||||||
|
if (target.tagName == "INPUT") return;
|
||||||
|
|
||||||
key_down_fired = true;
|
key_down_fired = true;
|
||||||
|
|
||||||
playAudio.playPrev();
|
playAudio.playPrev();
|
||||||
|
@ -4,6 +4,7 @@ import album from "./album.js";
|
|||||||
import state from "./state.js";
|
import state from "./state.js";
|
||||||
|
|
||||||
function toAlbum(title, artist) {
|
function toAlbum(title, artist) {
|
||||||
|
state.loading.value = true;
|
||||||
album
|
album
|
||||||
.getAlbumTracks(title, artist)
|
.getAlbumTracks(title, artist)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
@ -24,15 +25,16 @@ function toAlbum(title, artist) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.then(
|
.then(() => {
|
||||||
Router.push({
|
Router.push({
|
||||||
name: "AlbumView",
|
name: "AlbumView",
|
||||||
params: {
|
params: {
|
||||||
album: title,
|
album: title,
|
||||||
artist: artist,
|
artist: artist,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
)
|
state.loading.value = false;
|
||||||
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
});
|
});
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<div class="separator" id="av-sep"></div>
|
<div class="separator" id="av-sep"></div>
|
||||||
<FeaturedArtists :artists="artists" />
|
<FeaturedArtists :artists="artists" />
|
||||||
<div class="separator" id="av-sep"></div>
|
<div class="separator" id="av-sep"></div>
|
||||||
<AlbumBio :bio="bio" v-if="bio"/>
|
<AlbumBio :bio="bio" v-if="bio" />
|
||||||
<div class="separator" id="av-sep"></div>
|
<div class="separator" id="av-sep"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -19,7 +19,7 @@
|
|||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { onMounted } from "@vue/runtime-core";
|
import { onMounted } from "@vue/runtime-core";
|
||||||
import { onUnmounted } from "@vue/runtime-core";
|
import { onUnmounted } from "@vue/runtime-core";
|
||||||
|
import { watch, ref } from "vue";
|
||||||
import Header from "../components/AlbumView/Header.vue";
|
import Header from "../components/AlbumView/Header.vue";
|
||||||
import AlbumBio from "../components/AlbumView/AlbumBio.vue";
|
import AlbumBio from "../components/AlbumView/AlbumBio.vue";
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ import SongList from "../components/FolderView/SongList.vue";
|
|||||||
import FeaturedArtists from "../components/PlaylistView/FeaturedArtists.vue";
|
import FeaturedArtists from "../components/PlaylistView/FeaturedArtists.vue";
|
||||||
|
|
||||||
import state from "@/composables/state.js";
|
import state from "@/composables/state.js";
|
||||||
import routeLoader from "@/composables/routeLoader.js"
|
import routeLoader from "@/composables/routeLoader.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -38,13 +38,16 @@ export default {
|
|||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const title = route.params.album;
|
|
||||||
const album_artists = route.params.artist;
|
watch(
|
||||||
|
() => route.params,
|
||||||
|
() => {
|
||||||
|
routeLoader.toAlbum(route.params.album, route.params.artist);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (!state.album_song_list.value.length) {
|
routeLoader.toAlbum(route.params.album, route.params.artist);
|
||||||
routeLoader.toAlbum(title, album_artists);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
@ -69,7 +72,7 @@ export default {
|
|||||||
height: calc(100% - 1rem);
|
height: calc(100% - 1rem);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
margin-top: $small;
|
margin-top: $small;
|
||||||
|
scrollbar-width: none;
|
||||||
.songs {
|
.songs {
|
||||||
padding: $small;
|
padding: $small;
|
||||||
background-color: $card-dark;
|
background-color: $card-dark;
|
||||||
@ -83,4 +86,4 @@ export default {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="f-view-parent" class="rounded">
|
<div id="f-view-parent" class="rounded">
|
||||||
<div class="fixed">
|
<div class="fixed">
|
||||||
<Header :path="path" :first_song="songs[0]" @search="filterSongs" />
|
<Header :path="path" :first_song="songs[0]" @search="updateQueryString" />
|
||||||
</div>
|
</div>
|
||||||
<div id="scrollable" ref="scrollable">
|
<div id="scrollable" ref="scrollable">
|
||||||
<FolderList :folders="folders" />
|
<FolderList :folders="folders" />
|
||||||
@ -19,7 +19,7 @@ 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 Header from "@/components/FolderView/Header.vue";
|
||||||
|
|
||||||
import getData from "../composables/getFiles.js";
|
import getTracksAndDirs from "../composables/getFiles.js";
|
||||||
import { onMounted, watch } from "@vue/runtime-core";
|
import { onMounted, watch } from "@vue/runtime-core";
|
||||||
import state from "@/composables/state.js";
|
import state from "@/composables/state.js";
|
||||||
|
|
||||||
@ -34,16 +34,16 @@ export default {
|
|||||||
const path = ref(route.params.path);
|
const path = ref(route.params.path);
|
||||||
|
|
||||||
const song_list = ref(state.folder_song_list);
|
const song_list = ref(state.folder_song_list);
|
||||||
const folders = ref(state.folder_list);
|
const folders_list = ref(state.folder_list);
|
||||||
|
|
||||||
const scrollable = ref(null);
|
const scrollable = ref(null);
|
||||||
|
|
||||||
const query = ref('');
|
const query = ref("");
|
||||||
|
|
||||||
const songs = computed(() => {
|
const songs = computed(() => {
|
||||||
const songs_ = [];
|
const songs_ = [];
|
||||||
|
|
||||||
if (query.value.length > 2) {
|
if (query.value.length > 1) {
|
||||||
for (let i = 0; i < song_list.value.length; i++) {
|
for (let i = 0; i < song_list.value.length; i++) {
|
||||||
if (
|
if (
|
||||||
song_list.value[i].title
|
song_list.value[i].title
|
||||||
@ -60,37 +60,62 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const folders = computed(() => {
|
||||||
|
const folders_ = [];
|
||||||
|
|
||||||
|
if (query.value.length > 1) {
|
||||||
|
for (let i = 0; i < folders_list.value.length; i++) {
|
||||||
|
if (
|
||||||
|
folders_list.value[i].name
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(query.value.toLowerCase())
|
||||||
|
) {
|
||||||
|
folders_.push(folders_list.value[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return folders_;
|
||||||
|
} else {
|
||||||
|
return folders_list.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const getPathFolders = (path, last_id) => {
|
const getDirData = (path) => {
|
||||||
state.loading.value = true;
|
state.loading.value = true;
|
||||||
getData(path, last_id).then((data) => {
|
getTracksAndDirs(path)
|
||||||
scrollable.value.scrollTop = 0;
|
.then((data) => {
|
||||||
|
scrollable.value.scrollTop = 0;
|
||||||
|
|
||||||
state.folder_song_list.value = data.songs;
|
state.folder_song_list.value = data.songs;
|
||||||
state.folder_list.value = data.folders;
|
state.folder_list.value = data.folders;
|
||||||
|
|
||||||
state.loading.value = false;
|
state.loading.value = false;
|
||||||
});
|
})
|
||||||
|
.then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
query.value = "";
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
getPathFolders(path.value);
|
getDirData(path.value);
|
||||||
|
|
||||||
watch(route, (new_route) => {
|
watch(route, (new_route) => {
|
||||||
state.search_query.value = "";
|
|
||||||
path.value = new_route.params.path;
|
path.value = new_route.params.path;
|
||||||
|
|
||||||
if (!path.value) return;
|
if (!path.value) return;
|
||||||
|
|
||||||
getPathFolders(path.value);
|
getDirData(path.value);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function filterSongs(value) {
|
function updateQueryString(value) {
|
||||||
query.value = value;
|
query.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
filterSongs,
|
updateQueryString,
|
||||||
songs,
|
songs,
|
||||||
folders,
|
folders,
|
||||||
path,
|
path,
|
||||||
@ -129,4 +154,4 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user