Moved connections to user page, began search functionality

This commit is contained in:
Eclypsed
2024-03-30 01:15:12 -04:00
parent a4bad9d73b
commit a624f375e4
13 changed files with 242 additions and 165 deletions

View 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>

View File

@@ -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, {

View File

@@ -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> => {