Refined Jellyfin Search
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="card-wrapper" class="flex-shrink-0">
|
<div id="card-wrapper" class="flex-shrink-0">
|
||||||
<button id="thumbnail" class="relative h-56 transition-all duration-200 ease-out" on:click={() => goto(`/details/${mediaItem.type}?id=${mediaItem.id}`)}>
|
<button id="thumbnail" class="relative h-52 transition-all duration-200 ease-out" on:click={() => goto(`/details/${mediaItem.type}?id=${mediaItem.id}`)}>
|
||||||
{#if mediaItem.thumbnail}
|
{#if mediaItem.thumbnail}
|
||||||
<img bind:this={image} id="card-image" on:load={() => (captionText.style.width = `${image.width}px`)} class="h-full rounded transition-all" src={mediaItem.thumbnail} alt="{mediaItem.name} thumbnail" />
|
<img bind:this={image} id="card-image" on:load={() => (captionText.style.width = `${image.width}px`)} class="h-full rounded transition-all" src={mediaItem.thumbnail} alt="{mediaItem.name} thumbnail" />
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -81,15 +81,12 @@ export class Jellyfin implements Connection {
|
|||||||
if (!searchResponse.ok) throw new JellyfinFetchError('Failed to search Jellyfin', searchResponse.status, searchURL)
|
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.Artist
|
||||||
|
|
||||||
const parsedResults: MediaItem[] = []
|
const parsedResults: MediaItem[] = Array.from(searchResults, (result) => {
|
||||||
searchResults.forEach((result) => {
|
|
||||||
switch (result.Type) {
|
switch (result.Type) {
|
||||||
case 'Audio':
|
case 'Audio':
|
||||||
parsedResults.push(this.parseSong(result))
|
return this.parseSong(result)
|
||||||
break
|
|
||||||
case 'MusicAlbum':
|
case 'MusicAlbum':
|
||||||
parsedResults.push(this.parseAlbum(result))
|
return this.parseAlbum(result)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return parsedResults
|
return parsedResults
|
||||||
|
|||||||
@@ -74,6 +74,28 @@ export class YouTubeMusic implements Connection {
|
|||||||
return listenAgain.concat(quickPicks)
|
return listenAgain.concat(quickPicks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public search = async (searchTerm: string): Promise<MediaItem[]> => {
|
||||||
|
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 data = await response.json()
|
||||||
|
console.log(JSON.stringify(data))
|
||||||
|
}
|
||||||
|
|
||||||
private getHome = async (): Promise<YouTubeMusic.HomeItems> => {
|
private getHome = async (): Promise<YouTubeMusic.HomeItems> => {
|
||||||
const headers = Object.assign(this.BASEHEADERS, { authorization: `Bearer ${(await this.getTokens()).accessToken}`, 'X-Goog-Request-Time': `${Date.now()}` })
|
const headers = Object.assign(this.BASEHEADERS, { authorization: `Bearer ${(await this.getTokens()).accessToken}`, 'X-Goog-Request-Time': `${Date.now()}` })
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ScrollableCardMenu from '$lib/components/media/scrollableCardMenu.svelte'
|
import ScrollableCardMenu from '$lib/components/media/scrollableCardMenu.svelte'
|
||||||
|
import MediaCard from '$lib/components/media/mediaCard.svelte'
|
||||||
import type { PageData } from './$types'
|
import type { PageData } from './$types'
|
||||||
|
|
||||||
export let data: PageData
|
export let data: PageData
|
||||||
@@ -7,4 +8,10 @@
|
|||||||
|
|
||||||
<div id="main">
|
<div id="main">
|
||||||
<ScrollableCardMenu header={'Listen Again'} cardDataList={data.recommendations} />
|
<ScrollableCardMenu header={'Listen Again'} cardDataList={data.recommendations} />
|
||||||
|
<!-- <h1 class="mb-6 text-4xl"><strong>Listen Again</strong></h1>
|
||||||
|
<div class="flex flex-wrap justify-between gap-6">
|
||||||
|
{#each data.recommendations as recommendation}
|
||||||
|
<MediaCard mediaItem={recommendation} />
|
||||||
|
{/each}
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user