Moved connections to user page, began search functionality
This commit is contained in:
31
src/lib/components/util/searchBar.svelte
Normal file
31
src/lib/components/util/searchBar.svelte
Normal file
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation'
|
||||
|
||||
let searchBar: HTMLElement, searchInput: HTMLInputElement
|
||||
|
||||
const triggerSearch = (searchQuery: string) => goto(`/search?query=${searchQuery}`)
|
||||
</script>
|
||||
|
||||
<search role="search" bind:this={searchBar} class="relative flex h-12 w-full items-center gap-2.5 justify-self-center rounded-full border-2 border-transparent px-4 py-2" style="background-color: rgba(82, 82, 82, 0.25);">
|
||||
<button
|
||||
class="aspect-square h-6 transition-colors duration-200 hover:text-lazuli-primary"
|
||||
on:click|preventDefault={() => {
|
||||
if (searchInput.value.trim() !== '') {
|
||||
triggerSearch(searchInput.value)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<i class="fa-solid fa-magnifying-glass" />
|
||||
</button>
|
||||
<input
|
||||
bind:this={searchInput}
|
||||
type="text"
|
||||
name="search"
|
||||
class="w-full bg-transparent outline-none"
|
||||
placeholder="Let's find some music"
|
||||
autocomplete="off"
|
||||
on:keypress={(event) => {
|
||||
if (event.key === 'Enter') triggerSearch(searchInput.value)
|
||||
}}
|
||||
/>
|
||||
</search>
|
||||
@@ -1,5 +1,5 @@
|
||||
export class Jellyfin implements Connection {
|
||||
private id: string
|
||||
public id: string
|
||||
private userId: string
|
||||
private jfUserId: string
|
||||
private serverUrl: string
|
||||
@@ -72,21 +72,23 @@ export class Jellyfin implements Connection {
|
||||
public search = async (searchTerm: string): Promise<(Song | Album | Playlist)[]> => {
|
||||
const searchParams = new URLSearchParams({
|
||||
searchTerm,
|
||||
includeItemTypes: 'Audio,MusicAlbum', // Potentially add MusicArtist
|
||||
includeItemTypes: 'Audio,MusicAlbum,Playlist', // Potentially add MusicArtist
|
||||
recursive: 'true',
|
||||
})
|
||||
|
||||
const searchURL = new URL(`Users/${this.jfUserId}/Items?${searchParams.toString()}`, this.serverUrl).toString()
|
||||
const searchResponse = await fetch(searchURL, { headers: this.BASEHEADERS })
|
||||
if (!searchResponse.ok) throw new JellyfinFetchError('Failed to search Jellyfin', searchResponse.status, searchURL)
|
||||
const searchResults = (await searchResponse.json()).Items as (JellyfinAPI.Song | JellyfinAPI.Album)[] // JellyfinAPI.Artist
|
||||
const searchResults = (await searchResponse.json()).Items as (JellyfinAPI.Song | JellyfinAPI.Album | JellyfinAPI.Playlist)[] // JellyfinAPI.Artist
|
||||
|
||||
const parsedResults: (Song | Album)[] = Array.from(searchResults, (result) => {
|
||||
const parsedResults: (Song | Album | Playlist)[] = Array.from(searchResults, (result) => {
|
||||
switch (result.Type) {
|
||||
case 'Audio':
|
||||
return this.parseSong(result)
|
||||
case 'MusicAlbum':
|
||||
return this.parseAlbum(result)
|
||||
case 'Playlist':
|
||||
return this.parsePlaylist(result)
|
||||
}
|
||||
})
|
||||
return parsedResults
|
||||
@@ -147,6 +149,17 @@ export class Jellyfin implements Connection {
|
||||
}
|
||||
}
|
||||
|
||||
private parsePlaylist = (playlist: JellyfinAPI.Playlist): Playlist => {
|
||||
const thumbnail = playlist.ImageTags?.Primary ? new URL(`Items/${playlist.Id}/Images/Primary`, this.serverUrl).toString() : undefined
|
||||
|
||||
return {
|
||||
id: playlist.Id,
|
||||
name: playlist.Name,
|
||||
type: 'playlist',
|
||||
thumbnail,
|
||||
}
|
||||
}
|
||||
|
||||
public static authenticateByName = async (username: string, password: string, serverUrl: URL, deviceId: string): Promise<JellyfinAPI.AuthData> => {
|
||||
const authUrl = new URL('/Users/AuthenticateByName', serverUrl.origin).toString()
|
||||
return fetch(authUrl, {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { PUBLIC_YOUTUBE_API_CLIENT_ID } from '$env/static/public'
|
||||
import { YOUTUBE_API_CLIENT_SECRET } from '$env/static/private'
|
||||
|
||||
export class YouTubeMusic implements Connection {
|
||||
private id: string
|
||||
public id: string
|
||||
private userId: string
|
||||
private ytUserId: string
|
||||
private tokens: YouTubeMusic.Tokens
|
||||
@@ -77,23 +77,25 @@ export class YouTubeMusic implements Connection {
|
||||
public search = async (searchTerm: string): Promise<(Song | Album | Playlist)[]> => {
|
||||
const headers = Object.assign(this.BASEHEADERS, { authorization: `Bearer ${(await this.getTokens()).accessToken}`, 'X-Goog-Request-Time': `${Date.now()}` })
|
||||
|
||||
const response = await fetch(`https://music.youtube.com/youtubei/v1/search`, {
|
||||
headers,
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
query: searchTerm,
|
||||
context: {
|
||||
client: {
|
||||
clientName: 'WEB_REMIX',
|
||||
clientVersion: `1.${formatDate()}.01.00`,
|
||||
hl: 'en',
|
||||
},
|
||||
},
|
||||
}),
|
||||
})
|
||||
// const response = await fetch(`https://music.youtube.com/youtubei/v1/search`, {
|
||||
// headers,
|
||||
// method: 'POST',
|
||||
// body: JSON.stringify({
|
||||
// query: searchTerm,
|
||||
// context: {
|
||||
// client: {
|
||||
// clientName: 'WEB_REMIX',
|
||||
// clientVersion: `1.${formatDate()}.01.00`,
|
||||
// hl: 'en',
|
||||
// },
|
||||
// },
|
||||
// }),
|
||||
// })
|
||||
|
||||
const data = await response.json()
|
||||
console.log(JSON.stringify(data))
|
||||
// const data = await response.json()
|
||||
// console.log(JSON.stringify(data))
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
private getHome = async (): Promise<YouTubeMusic.HomeItems> => {
|
||||
|
||||
Reference in New Issue
Block a user