- Search continuations (related to #46)
- Search for Playlists (related to #46)
This commit is contained in:
Shiny Nematoda 2022-10-17 17:12:38 +00:00
parent 7905394b26
commit 2ff1308278
No known key found for this signature in database
GPG key ID: 6506D50F5613A42D
6 changed files with 104 additions and 38 deletions

View file

@ -130,22 +130,6 @@ onMounted(() => {
} }
}; };
/* Media Controls */
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('previoustrack', () => {
if (data.state.urls.length > 2) {
const i = data.state.urls.map(s => s.url).indexOf(data.state.url);
data.getSong(data.state.urls[i - 1].url);
}
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
if (data.state.urls.length > 2) {
const i = data.state.urls.map(s => s.url).indexOf(data.state.url);
data.getSong(data.state.urls[i + 1].url);
}
});
}
/* Setup IndexedDB for storing custom playlists */ /* Setup IndexedDB for storing custom playlists */
useSetupDB(); useSetupDB();

View file

@ -97,12 +97,11 @@ async function Stream() {
if (quality == 'best') sel = Math.max(...bandwidths); if (quality == 'best') sel = Math.max(...bandwidths);
else if (quality == 'worst') sel = Math.min(...bandwidths); else if (quality == 'worst') sel = Math.min(...bandwidths);
if (sel) { if (sel)
window.audioPlayer.selectVariantTrack( window.audioPlayer.selectVariantTrack(
tracks[bandwidths.indexOf(sel)], tracks[bandwidths.indexOf(sel)],
); );
} }
}
}) })
.catch(err => { .catch(err => {
console.error('Code: ' + err.code, err); console.error('Code: ' + err.code, err);
@ -152,6 +151,30 @@ onMounted(() => {
audio.value.pause(); audio.value.pause();
player.state.status = 'play'; player.state.status = 'play';
}); });
navigator.mediaSession.setActionHandler('previoustrack', () => {
if (data.state.urls.length > 2) {
const i = data.state.urls.map(s => s.url).indexOf(data.state.url);
data.getSong(data.state.urls[i - 1].url);
}
});
navigator.mediaSession.setActionHandler('nexttrack', () => {
if (data.state.urls.length > 2) {
const i = data.state.urls.map(s => s.url).indexOf(data.state.url);
data.getSong(data.state.urls[i + 1].url);
}
});
navigator.mediaSession.setActionHandler('seekbackward', () => {
audio.value.duration -= 10;
});
navigator.mediaSession.setActionHandler('seekforward', () => {
audio.value.duration += 10;
});
} }
}); });

View file

@ -1,5 +1,12 @@
<script setup> <script setup>
import { ref, reactive, watch, onUpdated } from 'vue'; import {
ref,
reactive,
watch,
onActivated,
onUpdated,
onDeactivated,
} from 'vue';
import Btn from './Btn.vue'; import Btn from './Btn.vue';
import SongItem from './SongItem.vue'; import SongItem from './SongItem.vue';
@ -20,7 +27,7 @@ const { t } = useI18n(),
artist = useArtist(); artist = useArtist();
const emit = defineEmits(['play-urls']), const emit = defineEmits(['play-urls']),
filters = ['music_songs', 'music_albums', 'music_artists'], filters = ['music_songs', 'music_albums', 'music_artists', 'music_playlists'],
filter = ref('music_songs'), filter = ref('music_songs'),
isSearch = ref(/search/.test(location.pathname)), isSearch = ref(/search/.test(location.pathname)),
albumMenu = ref(false); albumMenu = ref(false);
@ -91,6 +98,32 @@ const shuffleAdd = () => {
console.log('No Search'); console.log('No Search');
} }
}, },
loading = ref(false),
next = ref(null),
getSearchNext = async () => {
if (!isSearch.value || loading.value || !next.value) return;
if (
window.innerHeight + window.scrollY >=
document.body.offsetHeight - window.innerHeight
) {
loading.value = true;
const f = filter.value || 'music_songs',
json = await getJsonPiped(
`/nextpage/search?nextpage=${encodeURIComponent(next.value)}&q=${
nav.state.search
}&filter=${f}`,
),
key = f.split('_')[1];
next.value = json.nextpage;
results.items[key].items.push(...json.items);
loading.value = false;
console.log(json, results.items);
}
},
getResults = async q => { getResults = async q => {
results.resetItems(); results.resetItems();
@ -98,6 +131,8 @@ const shuffleAdd = () => {
json = await getJsonPiped(`/search?q=${q}&filter=${f}`), json = await getJsonPiped(`/search?q=${q}&filter=${f}`),
key = f.split('_')[1]; key = f.split('_')[1];
next.value = json.nextpage;
results.setItem(key, json); results.setItem(key, json);
console.log(json, key); console.log(json, key);
}; };
@ -119,6 +154,14 @@ watch(
onUpdated(() => { onUpdated(() => {
isSearch.value = /search/.test(location.pathname); isSearch.value = /search/.test(location.pathname);
}); });
onActivated(() => {
window.addEventListener('scroll', getSearchNext);
});
onDeactivated(() => {
window.removeEventListener('scroll', getSearchNext);
});
</script> </script>
<template> <template>
@ -190,7 +233,7 @@ onUpdated(() => {
<div <div
v-if="results.items.songs && results.items.songs.items[0]" v-if="results.items.songs && results.items.songs.items[0]"
class="search-songs"> class="search-wrap">
<h2 v-if="!isSearch">{{ t('title.songs') }}</h2> <h2 v-if="!isSearch">{{ t('title.songs') }}</h2>
<div class="grid"> <div class="grid">
<template v-for="(song, index) in results.items.songs.items"> <template v-for="(song, index) in results.items.songs.items">
@ -236,7 +279,7 @@ onUpdated(() => {
<div <div
v-if="results.items.albums && results.items.albums.items[0]" v-if="results.items.albums && results.items.albums.items[0]"
class="search-albums"> class="search-wrap">
<h2 v-if="!isSearch">{{ t('title.albums') }}</h2> <h2 v-if="!isSearch">{{ t('title.albums') }}</h2>
<div class="grid-3"> <div class="grid-3">
<template v-for="album in results.items.albums.items"> <template v-for="album in results.items.albums.items">
@ -251,9 +294,23 @@ onUpdated(() => {
</div> </div>
</div> </div>
<div
v-if="results.items.playlists && results.items.playlists.items[0]"
class="search-wrap">
<h2>{{ t('title.playlists') }}</h2>
<div class="grid-3">
<AlbumItem
v-for="pl in results.items.playlists.items"
:author="pl.videos + ' Songs • ' + pl.uploaderName"
:name="pl.name"
:art="pl.thumbnail"
@open-album="results.getAlbum(pl.url)" />
</div>
</div>
<div <div
v-if="results.items.singles && results.items.singles.items[0]" v-if="results.items.singles && results.items.singles.items[0]"
class="search-albums"> class="search-wrap">
<h2>{{ t('title.singles') }}</h2> <h2>{{ t('title.singles') }}</h2>
<div class="grid-3"> <div class="grid-3">
<template v-for="single in results.items.singles.items"> <template v-for="single in results.items.singles.items">
@ -272,7 +329,7 @@ onUpdated(() => {
results.items.recommendedArtists.items[0]) || results.items.recommendedArtists.items[0]) ||
(results.items.artists && results.items.artists.items[0]) (results.items.artists && results.items.artists.items[0])
" "
class="search-artists"> class="search-wrap">
<h2 v-if="!isSearch"> <h2 v-if="!isSearch">
{{ {{
results.items.artists ? t('title.artists') : t('title.similar_artists') results.items.artists ? t('title.artists') : t('title.similar_artists')
@ -296,18 +353,14 @@ onUpdated(() => {
</template> </template>
<style scoped> <style scoped>
.search-albums, .search-wrap {
.search-songs,
.search-artists {
place-items: start center; place-items: start center;
margin-bottom: 2rem; margin-bottom: 2rem;
} }
.search-songs h2, .search-wrap h2 {
.search-artists h2,
.search-albums h2 {
text-align: center; text-align: center;
} }
.search-artists { .circle {
text-align: center; text-align: center;
} }
:deep(.bi) { :deep(.bi) {
@ -328,16 +381,17 @@ onUpdated(() => {
padding: 0.5rem; padding: 0.5rem;
} }
.filters { .filters {
max-width: 100%;
display: flex; display: flex;
width: 100%; width: 100%;
justify-content: center; justify-content: center;
margin-bottom: 2rem; margin-bottom: 2rem;
overflow-x: auto;
} }
.filter { .filter {
width: calc(80% / v-bind('filters.length'));
max-width: 200px; max-width: 200px;
margin: 1rem; margin: 0 0.25rem;
padding: 0.5rem; padding: 0.5rem 1rem;
font-size: 1.25rem; font-size: 1.25rem;
border-radius: 0.25rem; border-radius: 0.25rem;
} }

View file

@ -226,7 +226,9 @@ async function Like() {
<button <button
id="btn-lyrics" id="btn-lyrics"
class="bi bi-file-music clickable" title="Lyrics"
aria-label="Lyrics"
class="bi bi-chat-square-quote clickable"
:data-active="player.state.lyrics" :data-active="player.state.lyrics"
@click="player.toggle('lyrics')"></button> @click="player.toggle('lyrics')"></button>

View file

@ -5,6 +5,7 @@
"singles": "Singles", "singles": "Singles",
"artists": "Artists", "artists": "Artists",
"similar_artists": "Similar Artists", "similar_artists": "Similar Artists",
"playlists": "Playlists",
"moods": "Moods", "moods": "Moods",
"genres": "Genres", "genres": "Genres",
"featured": "Featured", "featured": "Featured",

View file

@ -24,9 +24,11 @@ export async function getJson(url) {
if (res && res.error) { if (res && res.error) {
alert( alert(
res.message res.message
? res.message
.replaceAll('Video', 'Audio') .replaceAll('Video', 'Audio')
.replaceAll('video', 'audio') .replaceAll('video', 'audio')
.replaceAll('watched', 'heard'), .replaceAll('watched', 'heard')
: res.error,
); );
console.error(res.message); console.error(res.message);
} else if (res) { } else if (res) {