From 35c6bfc0216bf879353b3ee546b439a06c8e6121 Mon Sep 17 00:00:00 2001 From: TheCatLady <52870424+TheCatLady@users.noreply.github.com> Date: Wed, 3 Feb 2021 05:44:10 -0500 Subject: [PATCH] feat(ui): Add custom title functionality (#825) --- overseerr-api.yml | 3 ++ server/interfaces/api/settingsInterfaces.ts | 5 +-- server/lib/notifications/agents/discord.ts | 8 +++-- server/lib/notifications/agents/slack.ts | 2 +- server/lib/settings.ts | 12 ++++--- src/components/CollectionDetails/index.tsx | 6 ++-- src/components/Common/PageTitle/index.tsx | 22 +++++++++++++ src/components/Discover/DiscoverMovies.tsx | 5 ++- src/components/Discover/DiscoverTv.tsx | 5 ++- src/components/Discover/Trending.tsx | 5 ++- src/components/Discover/Upcoming.tsx | 5 ++- src/components/Discover/index.tsx | 3 ++ src/components/Layout/Sidebar/index.tsx | 4 +-- src/components/Login/index.tsx | 9 +++--- .../MovieDetails/MovieCast/index.tsx | 2 ++ .../MovieDetails/MovieCrew/index.tsx | 2 ++ .../MovieDetails/MovieRecommendations.tsx | 4 +++ src/components/MovieDetails/MovieSimilar.tsx | 4 +++ src/components/MovieDetails/index.tsx | 11 +++---- src/components/PersonDetails/index.tsx | 2 ++ src/components/RequestList/index.tsx | 2 ++ src/components/Search/index.tsx | 3 ++ src/components/Settings/SettingsLayout.tsx | 3 ++ src/components/Settings/SettingsMain.tsx | 31 ++++++++++++++++++- src/components/Setup/index.tsx | 7 +++-- src/components/TvDetails/TvCast/index.tsx | 4 +++ src/components/TvDetails/TvCrew/index.tsx | 4 +++ .../TvDetails/TvRecommendations.tsx | 4 +++ src/components/TvDetails/TvSimilar.tsx | 2 ++ src/components/TvDetails/index.tsx | 10 +++--- src/components/UserEdit/index.tsx | 2 ++ src/components/UserList/index.tsx | 3 ++ src/context/SettingsContext.tsx | 5 +-- src/i18n/locale/en.json | 4 +++ src/pages/_app.tsx | 1 + 35 files changed, 162 insertions(+), 42 deletions(-) create mode 100644 src/components/Common/PageTitle/index.tsx diff --git a/overseerr-api.yml b/overseerr-api.yml index bacf20525..d90f79adc 100644 --- a/overseerr-api.yml +++ b/overseerr-api.yml @@ -94,6 +94,9 @@ components: type: string example: 'anapikey' readOnly: true + applicationTitle: + type: string + example: Overseerr applicationUrl: type: string example: https://os.example.com diff --git a/server/interfaces/api/settingsInterfaces.ts b/server/interfaces/api/settingsInterfaces.ts index ba46e66bd..b731b979f 100644 --- a/server/interfaces/api/settingsInterfaces.ts +++ b/server/interfaces/api/settingsInterfaces.ts @@ -7,10 +7,11 @@ export interface SettingsAboutResponse { export interface PublicSettingsResponse { initialized: boolean; - movie4kEnabled: boolean; - series4kEnabled: boolean; + applicationTitle: string; hideAvailable: boolean; localLogin: boolean; + movie4kEnabled: boolean; + series4kEnabled: boolean; } export interface CacheItem { diff --git a/server/lib/notifications/agents/discord.ts b/server/lib/notifications/agents/discord.ts index 798f6525f..81558cdfc 100644 --- a/server/lib/notifications/agents/discord.ts +++ b/server/lib/notifications/agents/discord.ts @@ -203,7 +203,10 @@ class DiscordAgent description: payload.message, color, timestamp: new Date().toISOString(), - author: { name: 'Overseerr', url: settings.main.applicationUrl }, + author: { + name: settings.main.applicationTitle, + url: settings.main.applicationUrl, + }, fields: [ ...fields, // If we have extra data, map it to fields for discord notifications @@ -236,6 +239,7 @@ class DiscordAgent ): Promise { logger.debug('Sending discord notification', { label: 'Notifications' }); try { + const settings = getSettings(); const webhookUrl = this.getSettings().options.webhookUrl; if (!webhookUrl) { @@ -243,7 +247,7 @@ class DiscordAgent } await axios.post(webhookUrl, { - username: 'Overseerr', + username: settings.main.applicationTitle, embeds: [this.buildEmbed(type, payload)], } as DiscordWebhookPayload); diff --git a/server/lib/notifications/agents/slack.ts b/server/lib/notifications/agents/slack.ts index f6ca6856b..269ab6674 100644 --- a/server/lib/notifications/agents/slack.ts +++ b/server/lib/notifications/agents/slack.ts @@ -58,7 +58,7 @@ class SlackAgent payload: NotificationPayload ): SlackBlockEmbed { const settings = getSettings(); - let header = 'Overseerr'; + let header = settings.main.applicationTitle; let actionUrl: string | undefined; const fields: EmbedField[] = []; diff --git a/server/lib/settings.ts b/server/lib/settings.ts index 9312ee37d..f5ac5e8e8 100644 --- a/server/lib/settings.ts +++ b/server/lib/settings.ts @@ -50,6 +50,7 @@ export interface SonarrSettings extends DVRSettings { export interface MainSettings { apiKey: string; + applicationTitle: string; applicationUrl: string; csrfProtection: boolean; defaultPermissions: number; @@ -63,10 +64,11 @@ interface PublicSettings { } interface FullPublicSettings extends PublicSettings { - movie4kEnabled: boolean; - series4kEnabled: boolean; + applicationTitle: string; hideAvailable: boolean; localLogin: boolean; + movie4kEnabled: boolean; + series4kEnabled: boolean; } export interface NotificationAgentConfig { @@ -160,6 +162,7 @@ class Settings { clientId: uuidv4(), main: { apiKey: '', + applicationTitle: 'Overseerr', applicationUrl: '', csrfProtection: false, defaultPermissions: Permission.REQUEST, @@ -292,14 +295,15 @@ class Settings { get fullPublicSettings(): FullPublicSettings { return { ...this.data.public, + applicationTitle: this.data.main.applicationTitle, + hideAvailable: this.data.main.hideAvailable, + localLogin: this.data.main.localLogin, movie4kEnabled: this.data.radarr.some( (radarr) => radarr.is4k && radarr.isDefault ), series4kEnabled: this.data.sonarr.some( (sonarr) => sonarr.is4k && sonarr.isDefault ), - hideAvailable: this.data.main.hideAvailable, - localLogin: this.data.main.localLogin, }; } diff --git a/src/components/CollectionDetails/index.tsx b/src/components/CollectionDetails/index.tsx index d286b83b1..b6bec5e21 100644 --- a/src/components/CollectionDetails/index.tsx +++ b/src/components/CollectionDetails/index.tsx @@ -1,5 +1,4 @@ import axios from 'axios'; -import Head from 'next/head'; import { useRouter } from 'next/router'; import React, { useContext, useState } from 'react'; import { defineMessages, useIntl } from 'react-intl'; @@ -18,6 +17,7 @@ import Modal from '../Common/Modal'; import Slider from '../Slider'; import TitleCard from '../TitleCard'; import Transition from '../Transition'; +import PageTitle from '../Common/PageTitle'; const messages = defineMessages({ overviewunavailable: 'Overview unavailable.', @@ -108,9 +108,7 @@ const CollectionDetails: React.FC = ({ backgroundImage: `linear-gradient(180deg, rgba(17, 24, 39, 0.47) 0%, rgba(17, 24, 39, 1) 100%), url(//image.tmdb.org/t/p/w1920_and_h800_multi_faces/${data.backdropPath})`, }} > - - {data.name} - Overseerr - + = ({ title }) => { + const settings = useSettings(); + + return ( + + + {Array.isArray(title) ? title.filter(Boolean).join(' - ') : title} -{' '} + {settings.currentSettings.applicationTitle} + + + ); +}; + +export default PageTitle; diff --git a/src/components/Discover/DiscoverMovies.tsx b/src/components/Discover/DiscoverMovies.tsx index 243edf7a4..4ebad1430 100644 --- a/src/components/Discover/DiscoverMovies.tsx +++ b/src/components/Discover/DiscoverMovies.tsx @@ -3,10 +3,11 @@ import { useSWRInfinite } from 'swr'; import type { MovieResult } from '../../../server/models/Search'; import ListView from '../Common/ListView'; import { LanguageContext } from '../../context/LanguageContext'; -import { defineMessages, FormattedMessage } from 'react-intl'; +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import Header from '../Common/Header'; import useSettings from '../../hooks/useSettings'; import { MediaStatus } from '../../../server/constants/media'; +import PageTitle from '../Common/PageTitle'; const messages = defineMessages({ discovermovies: 'Popular Movies', @@ -20,6 +21,7 @@ interface SearchResult { } const DiscoverMovies: React.FC = () => { + const intl = useIntl(); const settings = useSettings(); const { locale } = useContext(LanguageContext); const { data, error, size, setSize } = useSWRInfinite( @@ -68,6 +70,7 @@ const DiscoverMovies: React.FC = () => { return ( <> +
diff --git a/src/components/Discover/DiscoverTv.tsx b/src/components/Discover/DiscoverTv.tsx index 5c3fb70b7..d75cd943d 100644 --- a/src/components/Discover/DiscoverTv.tsx +++ b/src/components/Discover/DiscoverTv.tsx @@ -2,11 +2,12 @@ import React, { useContext } from 'react'; import { useSWRInfinite } from 'swr'; import type { TvResult } from '../../../server/models/Search'; import ListView from '../Common/ListView'; -import { defineMessages, FormattedMessage } from 'react-intl'; +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { LanguageContext } from '../../context/LanguageContext'; import Header from '../Common/Header'; import useSettings from '../../hooks/useSettings'; import { MediaStatus } from '../../../server/constants/media'; +import PageTitle from '../Common/PageTitle'; const messages = defineMessages({ discovertv: 'Popular Series', @@ -20,6 +21,7 @@ interface SearchResult { } const DiscoverTv: React.FC = () => { + const intl = useIntl(); const settings = useSettings(); const { locale } = useContext(LanguageContext); const { data, error, size, setSize } = useSWRInfinite( @@ -67,6 +69,7 @@ const DiscoverTv: React.FC = () => { return ( <> +
diff --git a/src/components/Discover/Trending.tsx b/src/components/Discover/Trending.tsx index e99bbda58..75da4a410 100644 --- a/src/components/Discover/Trending.tsx +++ b/src/components/Discover/Trending.tsx @@ -7,10 +7,11 @@ import type { } from '../../../server/models/Search'; import ListView from '../Common/ListView'; import { LanguageContext } from '../../context/LanguageContext'; -import { defineMessages, FormattedMessage } from 'react-intl'; +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import Header from '../Common/Header'; import useSettings from '../../hooks/useSettings'; import { MediaStatus } from '../../../server/constants/media'; +import PageTitle from '../Common/PageTitle'; const messages = defineMessages({ trending: 'Trending', @@ -24,6 +25,7 @@ interface SearchResult { } const Trending: React.FC = () => { + const intl = useIntl(); const settings = useSettings(); const { locale } = useContext(LanguageContext); const { data, error, size, setSize } = useSWRInfinite( @@ -74,6 +76,7 @@ const Trending: React.FC = () => { return ( <> +
diff --git a/src/components/Discover/Upcoming.tsx b/src/components/Discover/Upcoming.tsx index b26ff00e0..bc14a768e 100644 --- a/src/components/Discover/Upcoming.tsx +++ b/src/components/Discover/Upcoming.tsx @@ -3,10 +3,11 @@ import { useSWRInfinite } from 'swr'; import type { MovieResult } from '../../../server/models/Search'; import ListView from '../Common/ListView'; import { LanguageContext } from '../../context/LanguageContext'; -import { defineMessages, FormattedMessage } from 'react-intl'; +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import Header from '../Common/Header'; import useSettings from '../../hooks/useSettings'; import { MediaStatus } from '../../../server/constants/media'; +import PageTitle from '../Common/PageTitle'; const messages = defineMessages({ upcomingmovies: 'Upcoming Movies', @@ -20,6 +21,7 @@ interface SearchResult { } const UpcomingMovies: React.FC = () => { + const intl = useIntl(); const settings = useSettings(); const { locale } = useContext(LanguageContext); const { data, error, size, setSize } = useSWRInfinite( @@ -69,6 +71,7 @@ const UpcomingMovies: React.FC = () => { return ( <> +
diff --git a/src/components/Discover/index.tsx b/src/components/Discover/index.tsx index 649087787..e883d4ae0 100644 --- a/src/components/Discover/index.tsx +++ b/src/components/Discover/index.tsx @@ -8,8 +8,10 @@ import type { MediaResultsResponse } from '../../../server/interfaces/api/mediaI import type { RequestResultsResponse } from '../../../server/interfaces/api/requestInterfaces'; import RequestCard from '../RequestCard'; import MediaSlider from '../MediaSlider'; +import PageTitle from '../Common/PageTitle'; const messages = defineMessages({ + discover: 'Discover', recentrequests: 'Recent Requests', popularmovies: 'Popular Movies', populartv: 'Popular Series', @@ -35,6 +37,7 @@ const Discover: React.FC = () => { return ( <> +
diff --git a/src/components/Layout/Sidebar/index.tsx b/src/components/Layout/Sidebar/index.tsx index e9277b35f..b6d9808dd 100644 --- a/src/components/Layout/Sidebar/index.tsx +++ b/src/components/Layout/Sidebar/index.tsx @@ -176,7 +176,7 @@ const Sidebar: React.FC = ({ open, setClosed }) => { @@ -238,7 +238,7 @@ const Sidebar: React.FC = ({ open, setClosed }) => { diff --git a/src/components/Login/index.tsx b/src/components/Login/index.tsx index bfd88997e..c4fd93a6b 100644 --- a/src/components/Login/index.tsx +++ b/src/components/Login/index.tsx @@ -10,8 +10,10 @@ import LanguagePicker from '../Layout/LanguagePicker'; import LocalLogin from './LocalLogin'; import Accordion from '../Common/Accordion'; import useSettings from '../../hooks/useSettings'; +import PageTitle from '../Common/PageTitle'; const messages = defineMessages({ + signin: 'Sign In', signinheader: 'Sign in to continue', signinwithplex: 'Use your Plex account', signinwithoverseerr: 'Use your Overseerr account', @@ -59,6 +61,7 @@ const Login: React.FC = () => { return (
+ {
- Overseerr Logo + Logo

diff --git a/src/components/MovieDetails/MovieCast/index.tsx b/src/components/MovieDetails/MovieCast/index.tsx index 2c07a979c..883de9fb1 100644 --- a/src/components/MovieDetails/MovieCast/index.tsx +++ b/src/components/MovieDetails/MovieCast/index.tsx @@ -9,6 +9,7 @@ import Error from '../../../pages/_error'; import Header from '../../Common/Header'; import LoadingSpinner from '../../Common/LoadingSpinner'; import PersonCard from '../../PersonCard'; +import PageTitle from '../../Common/PageTitle'; const messages = defineMessages({ fullcast: 'Full Cast', @@ -32,6 +33,7 @@ const MovieCast: React.FC = () => { return ( <> +
{ return ( <> +
{ return ( <> +
{ return ( <> +
= ({ movie }) => { backgroundImage: `linear-gradient(180deg, rgba(17, 24, 39, 0.47) 0%, rgba(17, 24, 39, 1) 100%), url(//image.tmdb.org/t/p/w1920_and_h800_multi_faces/${data.backdropPath})`, }} > - - {data.title} - Overseerr - - + = ({ movie }) => {
{data?.mediaInfo && data?.mediaInfo.status !== MediaStatus.AVAILABLE && ( -
+