Trying out some UI changes. Added resizing support to remoteImage and LazyImage component

This commit is contained in:
Eclypsed
2024-06-10 03:22:12 -04:00
parent cb4cc1d949
commit 9dab826e53
20 changed files with 462 additions and 288 deletions

View File

@@ -25,8 +25,8 @@ export class Jellyfin implements Connection {
}
public async getConnectionInfo() {
const userEndpoint = `Users/${this.jellyfinUserId}`
const systemEndpoint = 'System/Info'
const userEndpoint = `/Users/${this.jellyfinUserId}`
const systemEndpoint = '/System/Info'
const getUserData = () =>
this.services
@@ -42,8 +42,8 @@ export class Jellyfin implements Connection {
const [userData, systemData] = await Promise.all([getUserData(), getSystemData()])
if (!userData) console.error(`Fetch to ${userEndpoint.toString()} failed`)
if (!systemData) console.error(`Fetch to ${systemEndpoint.toString()} failed`)
if (!userData) console.error(`Fetch to ${userEndpoint} failed`)
if (!systemData) console.error(`Fetch to ${systemEndpoint} failed`)
return {
id: this.id,
@@ -206,9 +206,11 @@ class JellyfinServices {
}
}
private getBestThumbnail = (item: JellyfinAPI.Song | JellyfinAPI.Album | JellyfinAPI.Artist | JellyfinAPI.Playlist) => {
private getBestThumbnail(item: JellyfinAPI.Song | JellyfinAPI.Album | JellyfinAPI.Artist | JellyfinAPI.Playlist, placeholder: string): string
private getBestThumbnail(item: JellyfinAPI.Song | JellyfinAPI.Album | JellyfinAPI.Artist | JellyfinAPI.Playlist, placeholder?: string): string | undefined
private getBestThumbnail(item: JellyfinAPI.Song | JellyfinAPI.Album | JellyfinAPI.Artist | JellyfinAPI.Playlist, placeholder?: string): string | undefined {
const imageItemId = item.ImageTags?.Primary ? item.Id : 'AlbumPrimaryImageTag' in item && item.AlbumPrimaryImageTag ? item.AlbumId : undefined
return imageItemId ? this.serverUrl(`Items/${imageItemId}/Images/Primary`).toString() : jellyfinLogo
return imageItemId ? this.serverUrl(`Items/${imageItemId}/Images/Primary`).toString() : placeholder
}
public parseSong = (song: JellyfinAPI.Song): Song => ({
@@ -216,8 +218,8 @@ class JellyfinServices {
id: song.Id,
name: song.Name,
type: 'song',
duration: Math.floor(song.RunTimeTicks / 10000000),
thumbnailUrl: this.getBestThumbnail(song),
duration: Math.round(song.RunTimeTicks / 10000000),
thumbnailUrl: this.getBestThumbnail(song, jellyfinLogo),
releaseDate: song.PremiereDate ? new Date(song.PremiereDate).toISOString() : undefined,
artists: song.ArtistItems?.map((artist) => ({ id: artist.Id, name: artist.Name })),
album: song.AlbumId && song.Album ? { id: song.AlbumId, name: song.Album } : undefined,
@@ -229,7 +231,7 @@ class JellyfinServices {
id: album.Id,
name: album.Name,
type: 'album',
thumbnailUrl: this.getBestThumbnail(album),
thumbnailUrl: this.getBestThumbnail(album, jellyfinLogo),
artists: album.AlbumArtists?.map((artist) => ({ id: artist.Id, name: artist.Name })) ?? 'Various Artists',
releaseYear: album.ProductionYear?.toString(),
})
@@ -247,7 +249,7 @@ class JellyfinServices {
id: playlist.Id,
name: playlist.Name,
type: 'playlist',
thumbnailUrl: this.getBestThumbnail(playlist),
thumbnailUrl: this.getBestThumbnail(playlist, jellyfinLogo),
})
}
@@ -268,6 +270,7 @@ class JellyfinLibraryManager {
}
public async artists(): Promise<Artist[]> {
// ? This returns just album artists instead of all artists like in finamp, but I might decide that I want to return all artists instead
return this.services
.request('/Artists/AlbumArtists?sortBy=SortName&sortOrder=Ascending&recursive=true')
.then((response) => response.json() as Promise<{ Items: JellyfinAPI.Artist[] }>)

View File

@@ -168,7 +168,7 @@ export class YouTubeMusic implements Connection {
const playerResponse = await fetch('https://www.youtube.com/youtubei/v1/player', {
headers: {
// 'user-agent': 'com.google.android.youtube/17.36.4 (Linux; U; Android 12; GB) gzip', <-- I thought this was necessary but it appears it might not be?
authorization: `Bearer ${await this.requestManager.accessToken}`, // * Including the access token is what enables access to premium content
authorization: `Bearer ${await this.requestManager.accessToken}`, // * Including the access token is what enables access to premium content for some reason
},
method: 'POST',
body: JSON.stringify({
@@ -935,7 +935,8 @@ function secondsFromISO8601(duration: string): number {
* - https://yt3.googleusercontent.com
* - https://yt3.ggpht.com
* - https://music.youtube.com
* - https://i.ytimg.com
* - https://www.gstatic.com - Static images (e.g. a placeholder artist profile picture)
* - https://i.ytimg.com - Video Thumbnails
*
* NOTE:
* https://i.ytimg.com corresponds to videos, which follow the mqdefault...maxres resolutions scale. It is generally bad practice to use these as there is no way to scale them with query params, and there is no way to tell if a maxres.jpg exists or not.
@@ -953,7 +954,7 @@ function extractLargestThumbnailUrl(thumbnails: Array<{ url: string; width: numb
return bestThumbnailURL.slice(0, bestThumbnailURL.indexOf('='))
case 'https://music.youtube.com':
return bestThumbnailURL
case 'https://www.gstatic.com': // This url will usually contain static images like a placeholder artist profile picture for example
case 'https://www.gstatic.com':
case 'https://i.ytimg.com':
return bestThumbnailURL.slice(0, bestThumbnailURL.indexOf('?'))
default: