search feature

This commit is contained in:
ju09279
2024-08-18 02:20:46 +02:00
parent b4ac10c006
commit 97521f19e5
13 changed files with 783 additions and 88 deletions

View File

@@ -7,20 +7,47 @@ import CollectionListItem from '../components/CollectionListItem.vue'
const userStore = useUserStore();
const collections = ref<CollectionPreview[]>([]);
const limit = ref(10);
const offset = ref(0);
const isLoading = ref(false);
onMounted(async () => {
const data = await userStore.fetchCollections();
const fetchCollections = async () => {
if (isLoading.value) return;
isLoading.value = true;
const data = await userStore.fetchCollections(offset.value, limit.value);
data.forEach(song => {
song.previewimage = `${userStore.baseUrl}api/v1/images/${song.previewimage}?h=80&w=80`;
})
collections.value = data;
});
collections.value = [...collections.value, ...data];
offset.value += limit.value;
isLoading.value = false;
};
onMounted(async () => {
await fetchCollections();
const container = document.querySelector('.collection-container');
if (container) {
container.addEventListener('scroll', async () => {
const scrollTop = container.scrollTop;
const scrollHeight = container.scrollHeight;
const clientHeight = container.clientHeight;
if (scrollTop + clientHeight >= scrollHeight * 0.9 && !isLoading.value) {
await fetchCollections();
}
});
}
});
</script>
<template>
<main class="flex-1 text-center flex flex-col h-full overflow-scroll">
<div class="flex flex-col overflow-scroll">
<div class="flex flex-col overflow-scroll collection-container">
<CollectionListItem v-for="(collection, index) in collections" :key="index" :collection="collection" />
</div>
</main>

View File

@@ -49,7 +49,7 @@ const audioStore = useAudioStore();
<div class="flex flex-col justify-between mb-4">
<i @click="audioStore.toggleRepeat" :class="[audioStore.repeat ? 'text-pink-500' : '']"
class="fa-solid fa-repeat"></i>
<i @click="this.$router.go(-1);" class="fa-solid fa-arrow-down"></i>
<i @click="$router.go(-1);" class="fa-solid fa-arrow-down"></i>
</div>
</div>
<div class="flex">

View File

@@ -1,10 +1,70 @@
<script setup lang="ts">
import SongItem from '../components/SongItem.vue'
import type { Song, CollectionPreview } from '../script/types'
import { ref, onMounted } from 'vue'
import { useUserStore } from '@/stores/userStore';
import { useRoute } from 'vue-router';
import CollectionListItem from '../components/CollectionListItem.vue'
import { useAudioStore } from '@/stores/audioStore';
const route = useRoute();
const userStore = useUserStore();
const audioStore = useAudioStore();
const songs = ref<Song[]>([]);
const name = ref('name');
const limit = ref(100);
const offset = ref(0);
const isLoading = ref(false);
const fetchRecent = async () => {
if (isLoading.value) return;
isLoading.value = true;
const data = await userStore.fetchRecent(limit.value, offset.value);
data.forEach(song => {
song.previewimage = `${userStore.baseUrl}api/v1/images/${song.previewimage}`;
song.url = `${userStore.baseUrl}api/v1/audio/${song.url}`;
});
offset.value += limit.value;
console.log(data)
songs.value = [...songs.value, ...data];
isLoading.value = false;
audioStore.setCollection(null);
}
onMounted(async () => {
await fetchRecent();
const container = document.querySelector('.song-container');
if (container) {
container.addEventListener('scroll', async () => {
const scrollTop = container.scrollTop;
const scrollHeight = container.scrollHeight;
const clientHeight = container.clientHeight;
if (scrollTop + clientHeight >= scrollHeight * 0.9 && !isLoading.value) {
await fetchRecent();
}
});
}
});
</script>
<template>
<main class="flex-1 flex-col overflow-scroll">
<div class="flex-1 flex-col h-full overflow-scroll song-container">
<SongItem v-for="(song, index) in songs" :key="index" :song="song" />
</div>
</main>
</template>

View File

@@ -1,4 +1,81 @@
<script setup lang="ts">
import type { Song, CollectionPreview } from '../script/types'
import { useUserStore } from '@/stores/userStore';
import { onMounted, ref, watch } from 'vue';
import ActiveSearchList from '../components/ActiveSearchList.vue'
import { useRoute, useRouter } from 'vue-router';
import SongItem from '../components/SongItem.vue'
import { useAudioStore } from '@/stores/audioStore';
const router = useRouter();
const route = useRoute();
const audioStore = useAudioStore();
const userStore = useUserStore();
const activesongs = ref<Song[]>([]);
const songs = ref<Song[]>([]);
const artists = ref<string[]>([]);
const showSearch = ref(false);
onMounted(async () => {
await loadartistifexist();
const container = document.querySelector('.search') as HTMLInputElement;
if (container) {
container.addEventListener('input', async (event: Event) => {
showSearch.value = true;
const target = event.target as HTMLInputElement;
if(target.value != undefined && target.value != ""){
const data = await userStore.fetchActiveSearch(target.value)
router.push({ query: {s: target.value } });
data.songs.forEach(song => {
song.previewimage = `${userStore.baseUrl}api/v1/images/${song.previewimage}`;
song.url = `${userStore.baseUrl}api/v1/audio/${song.url}`;
});
activesongs.value = data.songs;
audioStore.setCollection(data.songs)
artists.value = data.artist;
} else {
activesongs.value = [];
artists.value = [];
showSearch.value = false;
}
}
)}
const s = route.query.s as string;
if(s){container.value = s; container.dispatchEvent(new Event('input'))}
});
async function loadartistifexist(){
const query = route.query.a as string;
if (query) {
showSearch.value = false;
const data = await userStore.fetchSearchArtist(query)
console.log(data);
data.forEach(song => {
song.previewimage = `${userStore.baseUrl}api/v1/images/${song.previewimage}`;
song.url = `${userStore.baseUrl}api/v1/audio/${song.url}`;
});
songs.value = data;
}
}
watch(() => route.query.a, async (newQuery) => {
await loadartistifexist();
});
</script>
<template>
@@ -12,8 +89,13 @@
<hr>
</div>
</header>
<main class="flex-1 flex-col">
<h1> Search...</h1>
<input class="flex-1 border border-pink-500 accent-pink-800 bg-yellow-300 bg-opacity-20 rounded-lg m-2 p-2" />
<main class="flex flex-col flex-1 flex-col w-full h-full overflow-scroll">
<input placeholder="Type to Search..." class="flex-1 max-h-12 search border border-pink-500 accent-pink-800 bg-yellow-300 bg-opacity-20 rounded-lg m-2 p-2" />
<div class="relative flex flex-col w-full h-full overflow-scroll">
<div v-if="showSearch" class="absolute w-full text-center search-recommendations z -20">
<ActiveSearchList :songs="activesongs" :artist="artists"/>
</div>
<SongItem v-for="(song, index) in songs" :key="index" :song="song" />
</div>
</main>
</template>