From 63a5304de00a3d28ec8363dbc9b46c7e922a9d6e Mon Sep 17 00:00:00 2001 From: Anatole Sot <47571181+ano0002@users.noreply.github.com> Date: Fri, 16 Feb 2024 00:39:22 +0100 Subject: [PATCH] Added some quality of life functions and brought the music page on par with the rest of the site --- server/api/musicbrainz/poster.ts | 4 +++- server/interfaces/api/settingsInterfaces.ts | 1 + server/lib/settings.ts | 6 ++++++ src/components/Common/CachedImage/index.tsx | 12 +++++++++--- src/components/TitleCard/index.tsx | 18 +++++------------- src/context/SettingsContext.tsx | 1 + src/pages/_app.tsx | 1 + 7 files changed, 26 insertions(+), 17 deletions(-) diff --git a/server/api/musicbrainz/poster.ts b/server/api/musicbrainz/poster.ts index 121067718..d0e27b9f8 100644 --- a/server/api/musicbrainz/poster.ts +++ b/server/api/musicbrainz/poster.ts @@ -1,5 +1,7 @@ import type { mbRelease, mbReleaseGroup } from './interfaces'; -function getPosterFromMB(element: mbRelease | mbReleaseGroup): string { +function getPosterFromMB( + element: mbRelease | mbReleaseGroup +): string | undefined { return `https://coverartarchive.org/${element.media_type}/${element.id}/front-250.jpg`; } diff --git a/server/interfaces/api/settingsInterfaces.ts b/server/interfaces/api/settingsInterfaces.ts index 0cd2f171a..d102b9fc8 100644 --- a/server/interfaces/api/settingsInterfaces.ts +++ b/server/interfaces/api/settingsInterfaces.ts @@ -33,6 +33,7 @@ export interface PublicSettingsResponse { partialRequestsEnabled: boolean; cacheImages: boolean; vapidPublic: string; + fallbackImage: string; enablePushRegistration: boolean; locale: string; emailEnabled: boolean; diff --git a/server/lib/settings.ts b/server/lib/settings.ts index 2194d990e..f31bf22b7 100644 --- a/server/lib/settings.ts +++ b/server/lib/settings.ts @@ -91,6 +91,7 @@ interface Quota { } export interface MainSettings { + fallbackImage: string; apiKey: string; applicationTitle: string; applicationUrl: string; @@ -128,6 +129,7 @@ interface FullPublicSettings extends PublicSettings { partialRequestsEnabled: boolean; cacheImages: boolean; vapidPublic: string; + fallbackImage: string; enablePushRegistration: boolean; locale: string; emailEnabled: boolean; @@ -309,6 +311,7 @@ class Settings { trustProxy: false, partialRequestsEnabled: true, locale: 'en', + fallbackImage: '/images/overseerr_poster_not_found_logo_top.png', }, plex: { name: '', @@ -529,6 +532,9 @@ class Settings { locale: this.data.main.locale, emailEnabled: this.data.notifications.agents.email.enabled, newPlexLogin: this.data.main.newPlexLogin, + fallbackImage: + this.data.main.fallbackImage ?? + '/images/overseerr_poster_not_found_logo_top.png', }; } diff --git a/src/components/Common/CachedImage/index.tsx b/src/components/Common/CachedImage/index.tsx index 6dfb8ee75..95b56badf 100644 --- a/src/components/Common/CachedImage/index.tsx +++ b/src/components/Common/CachedImage/index.tsx @@ -1,6 +1,7 @@ import useSettings from '@app/hooks/useSettings'; import type { ImageLoader, ImageProps } from 'next/image'; import Image from 'next/image'; +import { useState } from 'react'; const imageLoader: ImageLoader = ({ src }) => src; @@ -10,18 +11,23 @@ const imageLoader: ImageLoader = ({ src }) => src; **/ const CachedImage = ({ src, ...props }: ImageProps) => { const { currentSettings } = useSettings(); + const [imageUrl, setImageUrl] = useState(src as string); + + const handleError = () => { + setImageUrl(currentSettings?.fallbackImage); + }; - let imageUrl = src; if (typeof imageUrl === 'string' && imageUrl.startsWith('http')) { const parsedUrl = new URL(imageUrl); if (parsedUrl.host === 'image.tmdb.org' && currentSettings.cacheImages) { - imageUrl = imageUrl.replace('https://image.tmdb.org', '/imageproxy'); + setImageUrl(imageUrl.replace('https://image.tmdb.org', '/imageproxy')); } } - return ; + + return ; }; export default CachedImage; diff --git a/src/components/TitleCard/index.tsx b/src/components/TitleCard/index.tsx index 2758cd0a7..fa66acb7c 100644 --- a/src/components/TitleCard/index.tsx +++ b/src/components/TitleCard/index.tsx @@ -75,11 +75,11 @@ const TitleCard = ({ Permission.REQUEST, mediaType === 'movie' || mediaType === 'collection' ? Permission.REQUEST_MOVIE - : Permission.REQUEST_TV, + : (mediaType === 'tv' ? Permission.REQUEST_TV : Permission.REQUEST_MUSIC), ], { type: 'or' } ); - const tmdbOrMbId: boolean = mediaType in ['movie', 'tv', 'collection']; + const tmdbOrMbId: boolean = ['movie', 'tv', 'collection'].includes(mediaType); return (
{ if (!isTouch) { setShowDetail(true); @@ -132,7 +124,7 @@ const TitleCard = ({ alt="" src={ image - ? `https://image.tmdb.org/t/p/w300_and_h450_face${image}` + ? (tmdbOrMbId ? `https://image.tmdb.org/t/p/w300_and_h450_face${image}` : image) : `/images/overseerr_poster_not_found_logo_top.png` } layout="fill" diff --git a/src/context/SettingsContext.tsx b/src/context/SettingsContext.tsx index d50add4db..fdd037803 100644 --- a/src/context/SettingsContext.tsx +++ b/src/context/SettingsContext.tsx @@ -15,6 +15,7 @@ const defaultSettings = { localLogin: true, movie4kEnabled: false, series4kEnabled: false, + fallbackImage: '/images/overseerr_poster_not_found_logo_top.png', region: '', originalLanguage: '', partialRequestsEnabled: true, diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index ceb5734ec..68dd953cd 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -186,6 +186,7 @@ CoreApp.getInitialProps = async (initialProps) => { locale: 'en', emailEnabled: false, newPlexLogin: true, + fallbackImage: '/images/overseerr_poster_not_found_logo_top.png', }; if (ctx.res) {