Added search suggestions

This commit is contained in:
WardPearce
2024-03-09 19:16:37 +13:00
parent 10070bb6a6
commit bfcceb58eb
5 changed files with 81 additions and 3 deletions
+8 -1
View File
@@ -1,6 +1,6 @@
import { get } from 'svelte/store';
import { invidiousInstance, returnYTDislikesInstance } from '../../store';
import type { Channel, Comments, ReturnYTDislikes, Video, VideoPlay } from './model';
import type { Channel, Comments, ReturnYTDislikes, SearchSuggestion, Video, VideoPlay } from './model';
export function buildPath(path: string): string {
return `${get(invidiousInstance)}/api/v1/${path}`;
@@ -31,4 +31,11 @@ export async function getComments(videoId: string, parameters: { sortBy: "top" |
export async function getChannel(channelId: string): Promise<Channel> {
const resp = await fetch(buildPath(`channels/${channelId}`));
return await resp.json();
}
export async function getSearchSuggestions(search: string): Promise<SearchSuggestion> {
const path = new URL(buildPath("search/suggestions"));
path.search = new URLSearchParams({ q: search }).toString();
const resp = await fetch(path);
return await resp.json();
}
+5
View File
@@ -149,4 +149,9 @@ export interface Channel {
allowedRegions: string[];
tabs: string[];
latestVideos: Video[];
}
export interface SearchSuggestion {
query: string;
suggestions: string[];
}
+59 -2
View File
@@ -1,4 +1,5 @@
<script lang="ts">
import { getSearchSuggestions } from '$lib/Api/index';
import Logo from '$lib/Logo.svelte';
import 'beercss';
import 'material-dynamic-colors';
@@ -7,6 +8,7 @@
import {
activePage,
darkMode,
interfaceSearchSuggestions,
playerAlwaysLoop,
playerAutoPlay,
playerDash,
@@ -33,6 +35,21 @@
playerDash.subscribe((value) => (dash = value));
playerListenByDefault.subscribe((value) => (listenByDefault = value));
let searchSuggestions = false;
interfaceSearchSuggestions.subscribe((value) => (searchSuggestions = value));
let suggestionsForSearch: string[] = [];
let debounceTimer = 0;
const debouncedSearch = (event: any) => {
if (!searchSuggestions) return;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(async () => {
suggestionsForSearch = (await getSearchSuggestions(event.target.value)).suggestions;
}, 250);
};
const pages = [
{
icon: 'home',
@@ -134,7 +151,24 @@
<div class="max"></div>
<div class="max field round suffix prefix small no-margin m l white black-text">
<i class="front">search</i><input type="text" placeholder="Search..." />
<i class="front">search</i><input
data-ui="search-suggestions"
type="text"
placeholder="Search..."
on:keyup={(target) => debouncedSearch(target)}
/>
{#if searchSuggestions}
<menu
class="no-wrap"
style="width: 100%;"
id="search-suggestions"
data-ui="#search-suggestions"
>
{#each suggestionsForSearch as suggestion}
<a href={`/search/${suggestion}`}>{suggestion}</a>
{/each}
</menu>
{/if}
</div>
<div class="max"></div>
<button class="circle large transparent" data-ui="#dialog-notifications"
@@ -169,6 +203,25 @@
</button>
</div>
<div class="settings">
<h6>Interface</h6>
<div class="field no-margin">
<nav class="no-padding">
<div class="max">
<div>Search suggestions</div>
</div>
<label class="switch">
<input
type="checkbox"
bind:checked={searchSuggestions}
on:click={() => interfaceSearchSuggestions.set(!searchSuggestions)}
/>
<span></span>
</label>
</nav>
</div>
</div>
<div class="settings">
<h6>Player</h6>
<div class="field no-margin">
@@ -284,7 +337,11 @@
</nav>
</header>
{#each pages as page}
<a class="row round" data-ui="#dialog-expanded" href={page.href}
<a
class="row round"
data-ui="#dialog-expanded"
href={page.href}
class:active={currentPage === page.name.toLowerCase()}
><i>{page.icon}</i>
<div>{page.name}</div></a
>
+5
View File
@@ -0,0 +1,5 @@
<script lang="ts">
import { activePage } from '../store';
activePage.set('home');
</script>
+4
View File
@@ -14,3 +14,7 @@ export const playerProxyVideos = persisted("proxyVideos", false);
export const playerListenByDefault = persisted("listenByDefault", false);
export const playerSavePlaybackPosition = persisted("savePlaybackPosition", true);
export const playerDash = persisted("dash", true);
export const interfaceSearchSuggestions = persisted("searchSuggestions", true);
export const authToken = persisted("authToken", "");