blacken search component

This commit is contained in:
geoffrey45
2021-12-30 21:32:12 +03:00
parent efd7f84b1f
commit 61e7ff7188
9 changed files with 233 additions and 128 deletions
+5 -5
View File
@@ -288,12 +288,12 @@ def getFolderTree(folder: str = None):
folders.append(dir) folders.append(dir)
if entry.is_file(): # if entry.is_file():
if isValidFile(entry.name) == True: # if isValidFile(entry.name) == True:
file = all_songs_instance.find_song_by_path(entry.path) # file = all_songs_instance.find_song_by_path(entry.path)
if not file: # if not file:
getTags(entry.path) # getTags(entry.path)
songs_array = all_songs_instance.find_songs_by_folder( songs_array = all_songs_instance.find_songs_by_folder(
req_dir) req_dir)
+32 -7
View File
@@ -11,12 +11,15 @@
<Navigation :collapsed="collapsed" /> <Navigation :collapsed="collapsed" />
<PinnedStuff :collapsed="collapsed" /> <PinnedStuff :collapsed="collapsed" />
</div> </div>
<div class="content"> <div class="content" :class="{ isMagicFlag: isMagicFlag }">
<Search <div class="search-box">
v-model:search="search" <Search
@expandSearch="expandSearch" v-model:search="search"
@collapseSearch="collapseSearch" @expandSearch="expandSearch"
/> @collapseSearch="collapseSearch"
/>
</div>
<div class="separator" style="border: none"></div> <div class="separator" style="border: none"></div>
<router-view /> <router-view />
</div> </div>
@@ -31,7 +34,7 @@
</template> </template>
<script> <script>
import { ref } from "@vue/reactivity"; import { computed, ref } from "@vue/reactivity";
import Navigation from "./components/LeftSidebar/Navigation.vue"; import Navigation from "./components/LeftSidebar/Navigation.vue";
import PinnedStuff from "./components/LeftSidebar/PinnedStuff.vue"; import PinnedStuff from "./components/LeftSidebar/PinnedStuff.vue";
@@ -41,6 +44,7 @@ import NowPlaying from "./components/RightSideBar/NowPlaying.vue";
import UpNext from "./components/RightSideBar/UpNext.vue"; import UpNext from "./components/RightSideBar/UpNext.vue";
import RecommendedArtist from "./components/RightSideBar/Recommendation.vue"; import RecommendedArtist from "./components/RightSideBar/Recommendation.vue";
import state from "@/composables/state.js";
import perks from "@/composables/perks.js"; import perks from "@/composables/perks.js";
export default { export default {
@@ -58,6 +62,10 @@ export default {
perks.readQueue(); perks.readQueue();
const isMagicFlag = computed(() => {
return state.magic_flag.value;
});
function toggleNav() { function toggleNav() {
collapsed.value = !collapsed.value; collapsed.value = !collapsed.value;
} }
@@ -87,6 +95,7 @@ export default {
expandSearch, expandSearch,
collapseSearch, collapseSearch,
search, search,
isMagicFlag,
}; };
}, },
}; };
@@ -130,4 +139,20 @@ export default {
display: none; display: none;
} }
} }
.content {
position: relative;
padding: 0.5rem;
padding-top: 4.5rem;
.search-box {
width: calc(100% - 1rem);
position: absolute;
top: 0;
z-index: 1;
}
}
.isMagicFlag {
padding-top: 7.5rem;
}
</style> </style>
-1
View File
@@ -116,7 +116,6 @@ a {
.content { .content {
grid-area: content; grid-area: content;
border-radius: 0.25rem; border-radius: 0.25rem;
padding: 0.5rem;
overflow: hidden; overflow: hidden;
} }
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path fill="#199be2" d="M35.983,32.448l-3.536,3.536l7.87,7.87c0.195,0.195,0.512,0.195,0.707,0l2.828-2.828 c0.195-0.195,0.195-0.512,0-0.707L35.983,32.448z"></path><radialGradient id="eRNmcsAyqJzyQtK0oJ_Tda" cx="20.024" cy="233.904" r="19.604" gradientTransform="matrix(1 0 0 -1 0 254)" gradientUnits="userSpaceOnUse"><stop offset=".693" stop-color="#006185"></stop><stop offset=".921" stop-color="#35c1f1"></stop></radialGradient><polygon fill="url(#eRNmcsAyqJzyQtK0oJ_Tda)" points="31.601,28.065 28.065,31.601 32.448,35.983 35.983,32.448"></polygon><linearGradient id="eRNmcsAyqJzyQtK0oJ_Tdb" x1="8.911" x2="31.339" y1="245.089" y2="222.661" gradientTransform="matrix(1 0 0 -1 0 254)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#a3ffff"></stop><stop offset=".223" stop-color="#9dfbff"></stop><stop offset=".53" stop-color="#8bf1ff"></stop><stop offset=".885" stop-color="#6ee0ff"></stop><stop offset="1" stop-color="#63daff"></stop></linearGradient><circle cx="20" cy="20" r="16" fill="url(#eRNmcsAyqJzyQtK0oJ_Tdb)"></circle><path fill="#1b9de2" d="M12.5,26.75c0-0.414,3-3.75,7.5-3.75s7.5,3.336,7.5,3.75s-0.336,0.75-0.75,0.75 c-0.067,0-3.408-1.75-6.75-1.75c-3.338,0-6.677,1.75-6.75,1.75C12.836,27.5,12.5,27.164,12.5,26.75z M24.858,18.642 c1.144,1.144,2.998,1.144,4.142,0L24.858,14.5C23.714,15.644,23.714,17.498,24.858,18.642z M15.142,18.642 c1.144-1.144,1.144-2.998,0-4.142L11,18.642C12.144,19.786,13.998,19.786,15.142,18.642z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+33 -8
View File
@@ -1,6 +1,6 @@
<template> <template>
<div class="folder"> <div class="folder">
<div class="table rounded" ref="songtitle" v-if="songs.length"> <div class="table rounded" ref="songtitle" v-if="searchSongs.length">
<table> <table>
<thead> <thead>
<tr> <tr>
@@ -12,7 +12,7 @@
</thead> </thead>
<tbody> <tbody>
<tr <tr
v-for="song in songs" v-for="song in searchSongs"
:key="song" :key="song"
:class="{ current: current._id.$oid == song._id.$oid }" :class="{ current: current._id.$oid == song._id.$oid }"
> >
@@ -64,16 +64,23 @@
</tbody> </tbody>
</table> </table>
</div> </div>
<div ref="songtitle" v-else-if="searchSongs.length === 0 && search_query">
<div class="no-results">
<div class="icon"></div>
<div class="text"> Track not found!</div>
</div>
</div>
<div v-else ref="songtitle"></div> <div v-else ref="songtitle"></div>
</div> </div>
</template> </template>
<script> <script>
import { ref, toRefs } from "@vue/reactivity"; import { computed, ref, toRefs } from "@vue/reactivity";
import { onMounted, onUnmounted } from "@vue/runtime-core"; import { onMounted, onUnmounted } from "@vue/runtime-core";
import audio from "@/composables/playAudio.js"; import audio from "@/composables/playAudio.js";
import perks from "@/composables/perks.js"; import perks from "@/composables/perks.js";
import state from "@/composables/state.js";
export default { export default {
props: ["songs"], props: ["songs"],
@@ -86,13 +93,13 @@ export default {
const putCommas = perks.putCommas; const putCommas = perks.putCommas;
const updateQueue = async (song) => { const updateQueue = async (song) => {
if (perks.queue.value[0]._id.$oid !== song_list.value[0]._id.$oid) { if (state.queue.value[0]._id.$oid !== song_list.value[0]._id.$oid) {
const queue = song_list.value; const new_queue = song_list.value;
localStorage.setItem("queue", JSON.stringify(queue)); localStorage.setItem("queue", JSON.stringify(new_queue));
perks.queue.value = queue; state.queue.value = new_queue;
} }
perks.current.value = song; state.current.value = song;
localStorage.setItem("current", JSON.stringify(song)); localStorage.setItem("current", JSON.stringify(song));
}; };
@@ -122,8 +129,18 @@ export default {
const playAudio = audio.playAudio; const playAudio = audio.playAudio;
const current = ref(perks.current); const current = ref(perks.current);
const search_query = ref(state.search_query)
const searchSongs = computed(() => {
return song_list.value.filter((song) => {
return song.title
.toLowerCase()
.includes(state.search_query.value.toLowerCase());
});
});
return { return {
searchSongs,
songtitle, songtitle,
songTitleWidth, songTitleWidth,
minWidth, minWidth,
@@ -131,12 +148,20 @@ export default {
updateQueue, updateQueue,
putCommas, putCommas,
current, current,
search_query,
}; };
}, },
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
.no-results {
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}
.table { .table {
width: 100%; width: 100%;
height: 100%; height: 100%;
+66 -43
View File
@@ -1,5 +1,8 @@
<template> <template>
<div class="right-search" ref="searchComponent"> <div
class="right-search"
ref="searchComponent"
>
<div class="input"> <div class="input">
<div class="search-icon image"></div> <div class="search-icon image"></div>
<div class="filter"> <div class="filter">
@@ -15,28 +18,25 @@
<input <input
type="search" type="search"
id="search" id="search"
@focus="toggleMagicFlag" @focus="activateMagicFlag"
@blur="toggleMagicFlag" @blur="removeMagicFlag"
@keyup.backspace="removeLastFilter" @keyup.backspace="removeLastFilter"
placeholder="find your music" placeholder="find your music"
v-model="query" v-model="query"
/> />
<div <div
class="suggestions" class="suggestions v00"
:class="{ :class="{
v00: !filters.length && !query, v00: !filters.length && !query,
v11: filters.length || query, v11: filters.length || query,
}" }"
> >
<div class="item">Kenny Rogers</div> <div class="item">Kenny Rogers</div>
<div class="item">Jim Reeves</div>
<div class="item">Juice Wrld</div>
<div class="item">Dolly Parton</div>
</div> </div>
</div> </div>
<div class="separator no-border"></div> <div class="separator no-border"></div>
<div class="options" v-if="magic_flag || query || filters.length"> <div class="options" v-if="magic_flag">
<div class="item info">I'm looking for:</div> <div class="item info">Filter by:</div>
<div <div
class="item" class="item"
v-for="option in options" v-for="option in options"
@@ -85,9 +85,13 @@
<script> <script>
import { ref, toRefs } from "@vue/reactivity"; import { ref, toRefs } from "@vue/reactivity";
import { watch } from "@vue/runtime-core"; import { watch } from "@vue/runtime-core";
import state from "@/composables/state.js";
export default { export default {
emits: ["expandSearch", "collapseSearch"],
props: ["search"], props: ["search"],
setup(props, { emit }) { setup(props, { emit }) {
const songs = [ const songs = [
@@ -121,13 +125,9 @@ export default {
title: "📁 Folder", title: "📁 Folder",
icon: "📁", icon: "📁",
}, },
{
title: "🈁 ここ",
icon: "🈁",
},
]; ];
const searchComponent = ref(null); const searchComponent = ref(null);
const filters = ref([]); const filters = ref(state.filters);
const albums = [ const albums = [
"Smooth Criminal like wtf ... and im serious", "Smooth Criminal like wtf ... and im serious",
"Xscape", "Xscape",
@@ -135,40 +135,52 @@ export default {
]; ];
const artists = ["Michael Jackson waihenya", "Jackson 5"]; const artists = ["Michael Jackson waihenya", "Jackson 5"];
const query = ref(null); const query = ref(state.searh_query);
const magic_flag = ref(false); const magic_flag = ref(state.magic_flag);
const is_hidden = toRefs(props).search; const is_hidden = toRefs(props).search;
function addFilter(filter) { function addFilter(filter) {
if (!filters.value.includes(filter)) { if (!filters.value.includes(filter)) {
filters.value.push(filter); state.filters.value.push(filter);
} }
} }
function removeFilter(filter) { function removeFilter(filter) {
filters.value = filters.value.filter((f) => f !== filter); state.filters.value = filters.value.filter((f) => f !== filter);
} }
let counter = 0; let counter = 0;
function removeLastFilter() { function removeLastFilter() {
console.log("removeLastFilter");
if (query.value === "" || query.value === null) { if (query.value === "" || query.value === null) {
counter ++; counter++;
if (counter > 1 || query.value === null){ if (counter > 1 || query.value === null) {
filters.value.pop(); state.filters.value.pop();
} }
} }
} }
function toggleMagicFlag() { function activateMagicFlag() {
setTimeout(() => { setTimeout(() => {
magic_flag.value = !magic_flag.value; state.magic_flag.value = true;
}, 300);
}
function removeMagicFlag() {
setTimeout(() => {
if (
(!filters.value.length && query.value == null) ||
query.value == ""
) {
console.log(query.value);
state.magic_flag.value = false;
}
}, 300); }, 300);
} }
watch(query, (new_query) => { watch(query, (new_query) => {
state.search_query.value = new_query;
if (new_query !== "") { if (new_query !== "") {
counter = 0; counter = 0;
emit("expandSearch"); emit("expandSearch");
@@ -177,11 +189,18 @@ export default {
} }
}); });
function hideScrollable() {
document.querySelector(".scrollable").classList.remove("v1");
document.querySelector(".scrollable").classList.add("v0");
}
return { return {
addFilter, addFilter,
toggleMagicFlag, activateMagicFlag,
removeMagicFlag,
removeFilter, removeFilter,
removeLastFilter, removeLastFilter,
hideScrollable,
songs, songs,
albums, albums,
artists, artists,
@@ -212,7 +231,7 @@ export default {
border-radius: 1rem; border-radius: 1rem;
margin: 0.5rem 0 0 0; margin: 0.5rem 0 0 0;
padding: $small $small 0 0; padding: $small $small 0 0;
background-color: #131313b2; background-color: #000000;
overflow: hidden; overflow: hidden;
.item { .item {
@@ -299,9 +318,10 @@ export default {
.right-search .scrollable { .right-search .scrollable {
height: 26rem; height: 26rem;
overflow-y: scroll; overflow-y: auto;
scroll-behavior: smooth; scroll-behavior: smooth;
padding: 0 $small 0 0; padding: 0 $small 0 0;
margin-bottom: 0.5rem;
} }
.right-search .heading { .right-search .heading {
@@ -310,20 +330,20 @@ export default {
padding: 1rem; padding: 1rem;
display: flex; display: flex;
align-items: center; align-items: center;
.more {
position: absolute;
right: 1rem;
padding: 0.5rem;
user-select: none;
}
.more:hover {
background: $blue;
border-radius: 0.5rem;
cursor: pointer;
}
} }
.right-search .heading .more {
position: absolute;
right: 1rem;
padding: 0.5rem;
user-select: none;
}
.right-search .heading .more:hover {
background: $blue;
border-radius: 0.5rem;
cursor: pointer;
}
.right-search input { .right-search input {
width: 100%; width: 100%;
height: 2.5rem; height: 2.5rem;
@@ -350,7 +370,8 @@ export default {
.right-search .tracks-results { .right-search .tracks-results {
border-radius: 0.5rem; border-radius: 0.5rem;
background-color: rgba(8, 3, 1, 0.274); background-color: rgb(27, 26, 26);
margin-left: $small;
padding: $small; padding: $small;
.result-item { .result-item {
@@ -394,8 +415,9 @@ export default {
.right-search .albums-results { .right-search .albums-results {
border-radius: 0.5rem; border-radius: 0.5rem;
background-color: rgba(8, 3, 1, 0.274); background-color: rgb(27, 26, 26);
margin-top: 1rem; margin-left: $small;
margin-top: $small;
.grid { .grid {
display: flex; display: flex;
@@ -435,7 +457,8 @@ export default {
.right-search .artists-results { .right-search .artists-results {
border-radius: 0.5rem; border-radius: 0.5rem;
background-color: rgba(8, 3, 1, 0.274); background-color: rgb(27, 26, 26);
margin: 0 0 0 $small;
.grid { .grid {
padding: 0 0 0 $small; padding: 0 0 0 $small;
+52 -64
View File
@@ -2,14 +2,9 @@ import { ref } from "@vue/reactivity";
import { watch } from "@vue/runtime-core"; import { watch } from "@vue/runtime-core";
import media from "./mediaNotification.js"; import media from "./mediaNotification.js";
import state from "./state.js";
const current = ref({ const current = ref(state.current);
title: "Nothing played yet",
artists: ["... blah blah blah"],
_id: {
$oid: "",
},
});
const next = ref({ const next = ref({
title: "The next song", title: "The next song",
@@ -19,23 +14,11 @@ const next = ref({
}, },
}); });
const prev = ref({ const prev = ref(state.prev);
title: "The previous song",
artists: ["... blah blah blah"],
_id: {
$oid: "",
},
});
const queue = ref([ const queue = ref(state.queue);
{
title: "Nothing played yet", const search = ref("");
artists: ["... blah blah blah"],
_id: {
$oid: "",
},
},
]);
const putCommas = (artists) => { const putCommas = (artists) => {
let result = []; let result = [];
@@ -51,33 +34,48 @@ const putCommas = (artists) => {
return result; return result;
}; };
const doThat = (songs, current) => { function updateNext(song_) {
queue.value = songs; const index = state.queue.value.findIndex(
current.value = current; (item) => item._id.$oid === song_._id.$oid
);
console.log(queue.value); if (index == queue.value.length - 1) {
}; next.value = queue.value[0];
state.prev.value = queue.value[queue.value.length - 2];
} else if (index == 0) {
next.value = queue.value[1];
} else {
next.value = queue.value[index + 1];
}
}
function updatePrev(song) {
const index = state.queue.value.findIndex(
(item) => item._id.$oid === song._id.$oid
);
if (index == 0) {
prev.value = queue.value[queue.value.length - 1];
} else if (index == queue.value.length - 1) {
prev.value = queue.value[index - 1];
} else {
prev.value = queue.value[index - 1];
}
}
const readQueue = () => { const readQueue = () => {
const prev_queue = JSON.parse(localStorage.getItem("queue")); const prev_queue = JSON.parse(localStorage.getItem("queue"));
const last_played = JSON.parse(localStorage.getItem("current")); const last_played = JSON.parse(localStorage.getItem("current"));
const next_ = JSON.parse(localStorage.getItem("next"));
const prev_ = JSON.parse(localStorage.getItem("prev"));
if (last_played) { if (last_played) {
current.value = last_played; state.current.value = last_played;
} }
if (prev_queue) { if (prev_queue) {
queue.value = prev_queue; state.queue.value = prev_queue;
}
updateNext(state.current.value);
if (next_) { updatePrev(state.current.value);
next.value = next_;
}
if (prev_) {
prev.value = prev_;
} }
}; };
@@ -93,40 +91,30 @@ function focusCurrent() {
} }
} }
watch(current, (new_current, old_current) => { setTimeout(() => {
media.showMediaNotif(); watch(current, (new_current) => {
media.showMediaNotif();
new Promise((resolve) => { new Promise((resolve) => {
const index = queue.value.findIndex( updateNext(new_current);
(item) => item._id.$oid === new_current._id.$oid updatePrev(new_current);
); resolve();
}).then(() => {
focusCurrent();
});
if (index == queue.value.length - 1) { localStorage.setItem("current", JSON.stringify(new_current));
next.value = queue.value[0]; // localStorage.setItem("prev", JSON.stringify(old_current));
prev.value = queue.value[queue.value.length - 2];
} else if (index == 0) {
next.value = queue.value[1];
} else {
next.value = queue.value[index + 1];
}
prev.value = old_current;
resolve();
}).then(() => {
focusCurrent();
}); });
}, 1000);
localStorage.setItem("current", JSON.stringify(new_current));
localStorage.setItem("prev", JSON.stringify(prev.value));
});
export default { export default {
putCommas, putCommas,
doThat,
readQueue, readQueue,
focusCurrent, focusCurrent,
current, current,
queue, queue,
next, next,
prev, prev,
search,
}; };
+42
View File
@@ -0,0 +1,42 @@
import { ref } from "@vue/reactivity";
const search_query = ref("");
const queue = ref([
{
title: "Nothing played yet",
artists: ["... blah blah blah"],
_id: {
$oid: "",
},
},
]);
const current = ref({
title: "Nothing played yet",
artists: ["... blah blah blah"],
_id: {
$oid: "",
},
});
const prev = ref({
title: "The previous song",
artists: ["... blah blah blah"],
_id: {
$oid: "",
},
});
const filters = ref([]);
const magic_flag = ref(false);
export default {
search_query,
queue,
current,
prev,
filters,
magic_flag,
};
+2
View File
@@ -20,6 +20,7 @@ import SearchBox from "@/components/FolderView/SearchBox.vue";
import getData from "../composables/getFiles.js"; import getData from "../composables/getFiles.js";
import { onMounted, watch } from "@vue/runtime-core"; import { onMounted, watch } from "@vue/runtime-core";
import perks from "@/composables/perks.js";
export default { export default {
components: { components: {
@@ -53,6 +54,7 @@ export default {
getPathFolders(path.value); getPathFolders(path.value);
watch(route, (new_route) => { watch(route, (new_route) => {
perks.search.value = "";
path.value = new_route.params.path; path.value = new_route.params.path;
getPathFolders(path.value); getPathFolders(path.value);
}); });