add debounced ref module

This commit is contained in:
geoffrey45 2022-01-22 06:23:37 +03:00
parent 188b0541c6
commit 7f73d89fcc
4 changed files with 59 additions and 27 deletions

View File

@ -17,7 +17,7 @@
type="text" type="text"
class="search-input" class="search-input"
placeholder="Ctrl + F" placeholder="Ctrl + F"
v-model="search_query" v-model="query"
@keyup.enter="search()" @keyup.enter="search()"
/> />
<div class="search-icon image"></div> <div class="search-icon image"></div>
@ -27,17 +27,25 @@
<script> <script>
import perks from "@/composables/perks.js"; import perks from "@/composables/perks.js";
import state from "@/composables/state.js"; import { watch } from '@vue/runtime-core';
import useDebouncedRef from '@/composables/useDebouncedRef.js';
export default { export default {
props: ["path", "first_song"], props: ["path", "first_song"],
setup() { setup(props, { emit }) {
const query = useDebouncedRef("", 400);
function playFolder(song) { function playFolder(song) {
perks.updateQueue(song, "folder"); perks.updateQueue(song, "folder");
} }
watch(query, () => {
emit("search", query.value);
});
return { return {
playFolder, playFolder,
search_query: state.search_query, query,
}; };
}, },
}; };

View File

@ -0,0 +1,34 @@
import { ref, customRef } from 'vue'
const debounce = (fn, delay = 0, immediate = false) => {
let timeout
return (...args) => {
if (immediate && !timeout) fn(...args)
clearTimeout(timeout)
timeout = setTimeout(() => {
fn(...args)
}, delay)
}
}
const useDebouncedRef = (initialValue, delay, immediate) => {
const state = ref(initialValue)
const debouncedRef = customRef((track, trigger) => ({
get() {
track()
return state.value
},
set: debounce(
value => {
state.value = value
trigger()
},
delay,
immediate
),
}))
return debouncedRef
}
export default useDebouncedRef

View File

@ -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]" /> <Header :path="path" :first_song="songs[0]" @search="filterSongs" />
</div> </div>
<div id="scrollable" ref="scrollable"> <div id="scrollable" ref="scrollable">
<FolderList :folders="folders" /> <FolderList :folders="folders" />
@ -38,37 +38,23 @@ export default {
const scrollable = ref(null); const scrollable = ref(null);
function focusSearch() { const query = ref('');
console.log("focusSearch");
}
const search_query = ref(state.search_query);
const filters = ref(state.filters);
const songs = computed(() => { const songs = computed(() => {
const songs = []; const songs_ = [];
if (!filters.value.includes("🈁")) {
return song_list.value;
}
if (search_query.value.length > 2) {
state.loading.value = true;
if (query.value.length > 2) {
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
.toLowerCase() .toLowerCase()
.includes(search_query.value.toLowerCase()) .includes(query.value.toLowerCase())
) { ) {
songs.push(song_list.value[i]); songs_.push(song_list.value[i]);
} }
} }
state.song_list.value = songs; return songs_;
state.loading.value = false;
return songs;
} else { } else {
return song_list.value; return song_list.value;
} }
@ -99,8 +85,12 @@ export default {
}); });
}); });
function filterSongs(value) {
query.value = value;
}
return { return {
focusSearch, filterSongs,
songs, songs,
folders, folders,
path, path,