feat(frontend): add more tooltips (#2961)

* feat(frontend): add more tooltips

* fix: remove styling from Tooltip

* refactor: tooltip expects a single child
pull/2963/head
TheCatLady 2 years ago committed by GitHub
parent 43a9067976
commit 950b1712b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,29 +1,31 @@
import React from 'react';
import type { Config } from 'react-popper-tooltip'; import type { Config } from 'react-popper-tooltip';
import { usePopperTooltip } from 'react-popper-tooltip'; import { usePopperTooltip } from 'react-popper-tooltip';
type TooltipProps = { type TooltipProps = {
content: React.ReactNode; content: React.ReactNode;
children: React.ReactNode; children: React.ReactElement;
tooltipConfig?: Config; tooltipConfig?: Partial<Config>;
}; };
const Tooltip = ({ children, content, tooltipConfig }: TooltipProps) => { const Tooltip = ({ children, content, tooltipConfig }: TooltipProps) => {
const { getTooltipProps, setTooltipRef, setTriggerRef, visible } = const { getTooltipProps, setTooltipRef, setTriggerRef, visible } =
usePopperTooltip({ usePopperTooltip({
followCursor: true, followCursor: true,
placement: 'left-end', offset: [-28, 6],
placement: 'auto-end',
...tooltipConfig, ...tooltipConfig,
}); });
return ( return (
<> <>
<div ref={setTriggerRef}>{children}</div> {React.cloneElement(children, { ref: setTriggerRef })}
{visible && ( {visible && (
<div <div
ref={setTooltipRef} ref={setTooltipRef}
{...getTooltipProps({ {...getTooltipProps({
className: className:
'bg-gray-800 px-2 py-1 rounded border border-gray-600 shadow text-gray-100', 'z-50 text-sm font-normal bg-gray-800 px-2 py-1 rounded border border-gray-600 shadow text-gray-100',
})} })}
> >
{content} {content}

@ -78,6 +78,8 @@ const messages = defineMessages({
theatricalrelease: 'Theatrical Release', theatricalrelease: 'Theatrical Release',
digitalrelease: 'Digital Release', digitalrelease: 'Digital Release',
physicalrelease: 'Physical Release', physicalrelease: 'Physical Release',
reportissue: 'Report an Issue',
managemovie: 'Manage Movie',
}); });
interface MovieDetailsProps { interface MovieDetailsProps {
@ -388,38 +390,42 @@ const MovieDetails = ({ movie }: MovieDetailsProps) => {
type: 'or', type: 'or',
} }
) && ( ) && (
<Tooltip content={intl.formatMessage(messages.reportissue)}>
<Button
buttonType="warning"
onClick={() => setShowIssueModal(true)}
className="ml-2 first:ml-0"
>
<ExclamationIcon />
</Button>
</Tooltip>
)}
{hasPermission(Permission.MANAGE_REQUESTS) && data.mediaInfo && (
<Tooltip content={intl.formatMessage(messages.managemovie)}>
<Button <Button
buttonType="warning" buttonType="default"
className="ml-2 first:ml-0" onClick={() => setShowManager(true)}
onClick={() => setShowIssueModal(true)} className="relative ml-2 first:ml-0"
> >
<ExclamationIcon /> <CogIcon className="!mr-0" />
{hasPermission(
[Permission.MANAGE_ISSUES, Permission.VIEW_ISSUES],
{
type: 'or',
}
) &&
(
data.mediaInfo?.issues.filter(
(issue) => issue.status === IssueStatus.OPEN
) ?? []
).length > 0 && (
<>
<div className="absolute -right-1 -top-1 h-3 w-3 rounded-full bg-red-600" />
<div className="absolute -right-1 -top-1 h-3 w-3 animate-ping rounded-full bg-red-600" />
</>
)}
</Button> </Button>
)} </Tooltip>
{hasPermission(Permission.MANAGE_REQUESTS) && data.mediaInfo && (
<Button
buttonType="default"
className="relative ml-2 first:ml-0"
onClick={() => setShowManager(true)}
>
<CogIcon className="!mr-0" />
{hasPermission(
[Permission.MANAGE_ISSUES, Permission.VIEW_ISSUES],
{
type: 'or',
}
) &&
(
data.mediaInfo?.issues.filter(
(issue) => issue.status === IssueStatus.OPEN
) ?? []
).length > 0 && (
<>
<div className="absolute -right-1 -top-1 h-3 w-3 rounded-full bg-red-600" />
<div className="absolute -right-1 -top-1 h-3 w-3 animate-ping rounded-full bg-red-600" />
</>
)}
</Button>
)} )}
</div> </div>
</div> </div>

@ -1,7 +1,7 @@
import Badge from '@app/components/Common/Badge';
import Button from '@app/components/Common/Button'; import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner'; import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import SensitiveInput from '@app/components/Common/SensitiveInput'; import SensitiveInput from '@app/components/Common/SensitiveInput';
import SettingsBadge from '@app/components/Settings/SettingsBadge';
import globalMessages from '@app/i18n/globalMessages'; import globalMessages from '@app/i18n/globalMessages';
import { BeakerIcon, SaveIcon } from '@heroicons/react/outline'; import { BeakerIcon, SaveIcon } from '@heroicons/react/outline';
import axios from 'axios'; import axios from 'axios';
@ -382,9 +382,7 @@ const NotificationsEmail = () => {
<span className="mr-2"> <span className="mr-2">
{intl.formatMessage(messages.pgpPrivateKey)} {intl.formatMessage(messages.pgpPrivateKey)}
</span> </span>
<Badge badgeType="danger"> <SettingsBadge badgeType="advanced" />
{intl.formatMessage(globalMessages.advanced)}
</Badge>
<span className="label-tip"> <span className="label-tip">
{intl.formatMessage(messages.pgpPrivateKeyTip, { {intl.formatMessage(messages.pgpPrivateKeyTip, {
OpenPgpLink: OpenPgpLink, OpenPgpLink: OpenPgpLink,
@ -414,9 +412,7 @@ const NotificationsEmail = () => {
<span className="mr-2"> <span className="mr-2">
{intl.formatMessage(messages.pgpPassword)} {intl.formatMessage(messages.pgpPassword)}
</span> </span>
<Badge badgeType="danger"> <SettingsBadge badgeType="advanced" />
{intl.formatMessage(globalMessages.advanced)}
</Badge>
<span className="label-tip"> <span className="label-tip">
{intl.formatMessage(messages.pgpPasswordTip, { {intl.formatMessage(messages.pgpPasswordTip, {
OpenPgpLink: OpenPgpLink, OpenPgpLink: OpenPgpLink,

@ -0,0 +1,54 @@
import Badge from '@app/components/Common/Badge';
import Tooltip from '@app/components/Common/Tooltip';
import globalMessages from '@app/i18n/globalMessages';
import { defineMessages, useIntl } from 'react-intl';
const messages = defineMessages({
advancedTooltip:
'Incorrectly configuring this setting may result in broken functionality',
experimentalTooltip:
'Enabling this setting may result in unexpected application behavior',
restartrequiredTooltip:
'Overseerr must be restarted for changes to this setting to take effect',
});
const SettingsBadge = ({
badgeType,
className,
}: {
badgeType: 'advanced' | 'experimental' | 'restartRequired';
className?: string;
}) => {
const intl = useIntl();
switch (badgeType) {
case 'advanced':
return (
<Tooltip content={intl.formatMessage(messages.advancedTooltip)}>
<Badge badgeType="danger" className={className}>
{intl.formatMessage(globalMessages.advanced)}
</Badge>
</Tooltip>
);
case 'experimental':
return (
<Tooltip content={intl.formatMessage(messages.experimentalTooltip)}>
<Badge badgeType="warning">
{intl.formatMessage(globalMessages.experimental)}
</Badge>
</Tooltip>
);
case 'restartRequired':
return (
<Tooltip content={intl.formatMessage(messages.restartrequiredTooltip)}>
<Badge badgeType="primary" className={className}>
{intl.formatMessage(globalMessages.restartRequired)}
</Badge>
</Tooltip>
);
default:
return null;
}
};
export default SettingsBadge;

@ -4,6 +4,7 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import Modal from '@app/components/Common/Modal'; import Modal from '@app/components/Common/Modal';
import PageTitle from '@app/components/Common/PageTitle'; import PageTitle from '@app/components/Common/PageTitle';
import Table from '@app/components/Common/Table'; import Table from '@app/components/Common/Table';
import Tooltip from '@app/components/Common/Tooltip';
import Transition from '@app/components/Transition'; import Transition from '@app/components/Transition';
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams'; import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
import globalMessages from '@app/i18n/globalMessages'; import globalMessages from '@app/i18n/globalMessages';
@ -47,6 +48,7 @@ const messages = defineMessages({
logDetails: 'Log Details', logDetails: 'Log Details',
extraData: 'Additional Data', extraData: 'Additional Data',
copiedLogMessage: 'Copied log message to clipboard.', copiedLogMessage: 'Copied log message to clipboard.',
viewdetails: 'View Details',
}); });
type Filter = 'debug' | 'info' | 'warn' | 'error'; type Filter = 'debug' | 'info' | 'warn' | 'error';
@ -327,23 +329,31 @@ const SettingsLogs = () => {
<Table.TD className="text-gray-300">{row.message}</Table.TD> <Table.TD className="text-gray-300">{row.message}</Table.TD>
<Table.TD className="-m-1 flex flex-wrap items-center justify-end"> <Table.TD className="-m-1 flex flex-wrap items-center justify-end">
{row.data && ( {row.data && (
<Tooltip
content={intl.formatMessage(messages.viewdetails)}
>
<Button
buttonType="primary"
buttonSize="sm"
onClick={() => setActiveLog(row)}
className="m-1"
>
<DocumentSearchIcon className="icon-md" />
</Button>
</Tooltip>
)}
<Tooltip
content={intl.formatMessage(messages.copyToClipboard)}
>
<Button <Button
buttonType="primary" buttonType="primary"
buttonSize="sm" buttonSize="sm"
onClick={() => setActiveLog(row)} onClick={() => copyLogString(row)}
className="m-1" className="m-1"
> >
<DocumentSearchIcon className="icon-md" /> <ClipboardCopyIcon className="icon-md" />
</Button> </Button>
)} </Tooltip>
<Button
buttonType="primary"
buttonSize="sm"
onClick={() => copyLogString(row)}
className="m-1"
>
<ClipboardCopyIcon className="icon-md" />
</Button>
</Table.TD> </Table.TD>
</tr> </tr>
); );

@ -1,11 +1,12 @@
import Badge from '@app/components/Common/Badge';
import Button from '@app/components/Common/Button'; import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner'; import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import PageTitle from '@app/components/Common/PageTitle'; import PageTitle from '@app/components/Common/PageTitle';
import SensitiveInput from '@app/components/Common/SensitiveInput'; import SensitiveInput from '@app/components/Common/SensitiveInput';
import Tooltip from '@app/components/Common/Tooltip';
import LanguageSelector from '@app/components/LanguageSelector'; import LanguageSelector from '@app/components/LanguageSelector';
import RegionSelector from '@app/components/RegionSelector'; import RegionSelector from '@app/components/RegionSelector';
import CopyButton from '@app/components/Settings/CopyButton'; import CopyButton from '@app/components/Settings/CopyButton';
import SettingsBadge from '@app/components/Settings/SettingsBadge';
import type { AvailableLocale } from '@app/context/LanguageContext'; import type { AvailableLocale } from '@app/context/LanguageContext';
import { availableLanguages } from '@app/context/LanguageContext'; import { availableLanguages } from '@app/context/LanguageContext';
import useLocale from '@app/hooks/useLocale'; import useLocale from '@app/hooks/useLocale';
@ -258,9 +259,7 @@ const SettingsMain = () => {
<span className="mr-2"> <span className="mr-2">
{intl.formatMessage(messages.trustProxy)} {intl.formatMessage(messages.trustProxy)}
</span> </span>
<Badge badgeType="primary"> <SettingsBadge badgeType="restartRequired" />
{intl.formatMessage(globalMessages.restartRequired)}
</Badge>
<span className="label-tip"> <span className="label-tip">
{intl.formatMessage(messages.trustProxyTip)} {intl.formatMessage(messages.trustProxyTip)}
</span> </span>
@ -281,28 +280,30 @@ const SettingsMain = () => {
<span className="mr-2"> <span className="mr-2">
{intl.formatMessage(messages.csrfProtection)} {intl.formatMessage(messages.csrfProtection)}
</span> </span>
<Badge badgeType="danger" className="mr-2"> <SettingsBadge badgeType="advanced" className="mr-2" />
{intl.formatMessage(globalMessages.advanced)} <SettingsBadge badgeType="restartRequired" />
</Badge>
<Badge badgeType="primary">
{intl.formatMessage(globalMessages.restartRequired)}
</Badge>
<span className="label-tip"> <span className="label-tip">
{intl.formatMessage(messages.csrfProtectionTip)} {intl.formatMessage(messages.csrfProtectionTip)}
</span> </span>
</label> </label>
<div className="form-input-area"> <div className="form-input-area">
<Field <Tooltip
type="checkbox" content={intl.formatMessage(
id="csrfProtection"
name="csrfProtection"
title={intl.formatMessage(
messages.csrfProtectionHoverTip messages.csrfProtectionHoverTip
)} )}
onChange={() => { >
setFieldValue('csrfProtection', !values.csrfProtection); <Field
}} type="checkbox"
/> id="csrfProtection"
name="csrfProtection"
onChange={() => {
setFieldValue(
'csrfProtection',
!values.csrfProtection
);
}}
/>
</Tooltip>
</div> </div>
</div> </div>
<div className="form-row"> <div className="form-row">
@ -367,9 +368,7 @@ const SettingsMain = () => {
<span className="mr-2"> <span className="mr-2">
{intl.formatMessage(messages.hideAvailable)} {intl.formatMessage(messages.hideAvailable)}
</span> </span>
<Badge badgeType="warning"> <SettingsBadge badgeType="experimental" />
{intl.formatMessage(globalMessages.experimental)}
</Badge>
</label> </label>
<div className="form-input-area"> <div className="form-input-area">
<Field <Field

@ -5,6 +5,7 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import PageTitle from '@app/components/Common/PageTitle'; import PageTitle from '@app/components/Common/PageTitle';
import SensitiveInput from '@app/components/Common/SensitiveInput'; import SensitiveInput from '@app/components/Common/SensitiveInput';
import LibraryItem from '@app/components/Settings/LibraryItem'; import LibraryItem from '@app/components/Settings/LibraryItem';
import SettingsBadge from '@app/components/Settings/SettingsBadge';
import globalMessages from '@app/i18n/globalMessages'; import globalMessages from '@app/i18n/globalMessages';
import { SaveIcon } from '@heroicons/react/outline'; import { SaveIcon } from '@heroicons/react/outline';
import { RefreshIcon, SearchIcon, XIcon } from '@heroicons/react/solid'; import { RefreshIcon, SearchIcon, XIcon } from '@heroicons/react/solid';
@ -567,9 +568,7 @@ const SettingsPlex = ({ onComplete }: SettingsPlexProps) => {
</a> </a>
), ),
})} })}
<Badge badgeType="danger" className="ml-2"> <SettingsBadge badgeType="advanced" className="ml-2" />
{intl.formatMessage(globalMessages.advanced)}
</Badge>
<span className="label-tip"> <span className="label-tip">
{intl.formatMessage(messages.webAppUrlTip)} {intl.formatMessage(messages.webAppUrlTip)}
</span> </span>

@ -9,6 +9,7 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import PageTitle from '@app/components/Common/PageTitle'; import PageTitle from '@app/components/Common/PageTitle';
import type { PlayButtonLink } from '@app/components/Common/PlayButton'; import type { PlayButtonLink } from '@app/components/Common/PlayButton';
import PlayButton from '@app/components/Common/PlayButton'; import PlayButton from '@app/components/Common/PlayButton';
import Tooltip from '@app/components/Common/Tooltip';
import ExternalLinkBlock from '@app/components/ExternalLinkBlock'; import ExternalLinkBlock from '@app/components/ExternalLinkBlock';
import IssueModal from '@app/components/IssueModal'; import IssueModal from '@app/components/IssueModal';
import ManageSlideOver from '@app/components/ManageSlideOver'; import ManageSlideOver from '@app/components/ManageSlideOver';
@ -68,6 +69,8 @@ const messages = defineMessages({
streamingproviders: 'Currently Streaming On', streamingproviders: 'Currently Streaming On',
productioncountries: productioncountries:
'Production {countryCount, plural, one {Country} other {Countries}}', 'Production {countryCount, plural, one {Country} other {Countries}}',
reportissue: 'Report an Issue',
managemovie: 'Manage Movie',
}); });
interface TvDetailsProps { interface TvDetailsProps {
@ -389,38 +392,42 @@ const TvDetails = ({ tv }: TvDetailsProps) => {
type: 'or', type: 'or',
} }
) && ( ) && (
<Tooltip content={intl.formatMessage(messages.reportissue)}>
<Button
buttonType="warning"
onClick={() => setShowIssueModal(true)}
className="ml-2 first:ml-0"
>
<ExclamationIcon />
</Button>
</Tooltip>
)}
{hasPermission(Permission.MANAGE_REQUESTS) && data.mediaInfo && (
<Tooltip content={intl.formatMessage(messages.managemovie)}>
<Button <Button
buttonType="warning" buttonType="default"
className="ml-2 first:ml-0" onClick={() => setShowManager(true)}
onClick={() => setShowIssueModal(true)} className="relative ml-2 first:ml-0"
> >
<ExclamationIcon className="w-5" /> <CogIcon className="!mr-0" />
{hasPermission(
[Permission.MANAGE_ISSUES, Permission.VIEW_ISSUES],
{
type: 'or',
}
) &&
(
data.mediaInfo?.issues.filter(
(issue) => issue.status === IssueStatus.OPEN
) ?? []
).length > 0 && (
<>
<div className="absolute -right-1 -top-1 h-3 w-3 rounded-full bg-red-600" />
<div className="absolute -right-1 -top-1 h-3 w-3 animate-ping rounded-full bg-red-600" />
</>
)}
</Button> </Button>
)} </Tooltip>
{hasPermission(Permission.MANAGE_REQUESTS) && data.mediaInfo && (
<Button
buttonType="default"
className="relative ml-2 first:ml-0"
onClick={() => setShowManager(true)}
>
<CogIcon className="!mr-0" />
{hasPermission(
[Permission.MANAGE_ISSUES, Permission.VIEW_ISSUES],
{
type: 'or',
}
) &&
(
data.mediaInfo?.issues.filter(
(issue) => issue.status === IssueStatus.OPEN
) ?? []
).length > 0 && (
<>
<div className="absolute -right-1 -top-1 h-3 w-3 rounded-full bg-red-600" />
<div className="absolute -right-1 -top-1 h-3 w-3 animate-ping rounded-full bg-red-600" />
</>
)}
</Button>
)} )}
</div> </div>
</div> </div>

@ -1,4 +1,3 @@
import Badge from '@app/components/Common/Badge';
import Button from '@app/components/Common/Button'; import Button from '@app/components/Common/Button';
import LoadingSpinner from '@app/components/Common/LoadingSpinner'; import LoadingSpinner from '@app/components/Common/LoadingSpinner';
import SensitiveInput from '@app/components/Common/SensitiveInput'; import SensitiveInput from '@app/components/Common/SensitiveInput';
@ -6,6 +5,7 @@ import NotificationTypeSelector, {
ALL_NOTIFICATIONS, ALL_NOTIFICATIONS,
} from '@app/components/NotificationTypeSelector'; } from '@app/components/NotificationTypeSelector';
import { OpenPgpLink } from '@app/components/Settings/Notifications/NotificationsEmail'; import { OpenPgpLink } from '@app/components/Settings/Notifications/NotificationsEmail';
import SettingsBadge from '@app/components/Settings/SettingsBadge';
import { useUser } from '@app/hooks/useUser'; import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages'; import globalMessages from '@app/i18n/globalMessages';
import { SaveIcon } from '@heroicons/react/outline'; import { SaveIcon } from '@heroicons/react/outline';
@ -105,9 +105,7 @@ const UserEmailSettings = () => {
<span className="mr-2"> <span className="mr-2">
{intl.formatMessage(messages.pgpPublicKey)} {intl.formatMessage(messages.pgpPublicKey)}
</span> </span>
<Badge badgeType="danger"> <SettingsBadge badgeType="advanced" />
{intl.formatMessage(globalMessages.advanced)}
</Badge>
<span className="label-tip"> <span className="label-tip">
{intl.formatMessage(messages.pgpPublicKeyTip, { {intl.formatMessage(messages.pgpPublicKeyTip, {
OpenPgpLink: OpenPgpLink, OpenPgpLink: OpenPgpLink,

@ -160,6 +160,7 @@
"components.MovieDetails.budget": "Budget", "components.MovieDetails.budget": "Budget",
"components.MovieDetails.cast": "Cast", "components.MovieDetails.cast": "Cast",
"components.MovieDetails.digitalrelease": "Digital Release", "components.MovieDetails.digitalrelease": "Digital Release",
"components.MovieDetails.managemovie": "Manage Movie",
"components.MovieDetails.mark4kavailable": "Mark as Available in 4K", "components.MovieDetails.mark4kavailable": "Mark as Available in 4K",
"components.MovieDetails.markavailable": "Mark as Available", "components.MovieDetails.markavailable": "Mark as Available",
"components.MovieDetails.originallanguage": "Original Language", "components.MovieDetails.originallanguage": "Original Language",
@ -172,6 +173,7 @@
"components.MovieDetails.productioncountries": "Production {countryCount, plural, one {Country} other {Countries}}", "components.MovieDetails.productioncountries": "Production {countryCount, plural, one {Country} other {Countries}}",
"components.MovieDetails.recommendations": "Recommendations", "components.MovieDetails.recommendations": "Recommendations",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Release Date} other {Release Dates}}", "components.MovieDetails.releasedate": "{releaseCount, plural, one {Release Date} other {Release Dates}}",
"components.MovieDetails.reportissue": "Report an Issue",
"components.MovieDetails.revenue": "Revenue", "components.MovieDetails.revenue": "Revenue",
"components.MovieDetails.runtime": "{minutes} minutes", "components.MovieDetails.runtime": "{minutes} minutes",
"components.MovieDetails.showless": "Show Less", "components.MovieDetails.showless": "Show Less",
@ -651,6 +653,7 @@
"components.Settings.SettingsLogs.resumeLogs": "Resume", "components.Settings.SettingsLogs.resumeLogs": "Resume",
"components.Settings.SettingsLogs.showall": "Show All Logs", "components.Settings.SettingsLogs.showall": "Show All Logs",
"components.Settings.SettingsLogs.time": "Timestamp", "components.Settings.SettingsLogs.time": "Timestamp",
"components.Settings.SettingsLogs.viewdetails": "View Details",
"components.Settings.SettingsUsers.defaultPermissions": "Default Permissions", "components.Settings.SettingsUsers.defaultPermissions": "Default Permissions",
"components.Settings.SettingsUsers.defaultPermissionsTip": "Initial permissions assigned to new users", "components.Settings.SettingsUsers.defaultPermissionsTip": "Initial permissions assigned to new users",
"components.Settings.SettingsUsers.localLogin": "Enable Local Sign-In", "components.Settings.SettingsUsers.localLogin": "Enable Local Sign-In",
@ -720,6 +723,7 @@
"components.Settings.addradarr": "Add Radarr Server", "components.Settings.addradarr": "Add Radarr Server",
"components.Settings.address": "Address", "components.Settings.address": "Address",
"components.Settings.addsonarr": "Add Sonarr Server", "components.Settings.addsonarr": "Add Sonarr Server",
"components.Settings.advancedTooltip": "Incorrectly configuring this setting may result in broken functionality",
"components.Settings.apikey": "API Key", "components.Settings.apikey": "API Key",
"components.Settings.applicationTitle": "Application Title", "components.Settings.applicationTitle": "Application Title",
"components.Settings.applicationurl": "Application URL", "components.Settings.applicationurl": "Application URL",
@ -737,6 +741,7 @@
"components.Settings.deleteserverconfirm": "Are you sure you want to delete this server?", "components.Settings.deleteserverconfirm": "Are you sure you want to delete this server?",
"components.Settings.email": "Email", "components.Settings.email": "Email",
"components.Settings.enablessl": "Use SSL", "components.Settings.enablessl": "Use SSL",
"components.Settings.experimentalTooltip": "Enabling this setting may result in unexpected application behavior",
"components.Settings.externalUrl": "External URL", "components.Settings.externalUrl": "External URL",
"components.Settings.general": "General", "components.Settings.general": "General",
"components.Settings.generalsettings": "General Settings", "components.Settings.generalsettings": "General Settings",
@ -777,6 +782,7 @@
"components.Settings.radarrsettings": "Radarr Settings", "components.Settings.radarrsettings": "Radarr Settings",
"components.Settings.region": "Discover Region", "components.Settings.region": "Discover Region",
"components.Settings.regionTip": "Filter content by regional availability", "components.Settings.regionTip": "Filter content by regional availability",
"components.Settings.restartrequiredTooltip": "Overseerr must be restarted for changes to this setting to take effect",
"components.Settings.scan": "Sync Libraries", "components.Settings.scan": "Sync Libraries",
"components.Settings.scanning": "Syncing…", "components.Settings.scanning": "Syncing…",
"components.Settings.serverLocal": "local", "components.Settings.serverLocal": "local",
@ -853,6 +859,7 @@
"components.TvDetails.episodeRuntime": "Episode Runtime", "components.TvDetails.episodeRuntime": "Episode Runtime",
"components.TvDetails.episodeRuntimeMinutes": "{runtime} minutes", "components.TvDetails.episodeRuntimeMinutes": "{runtime} minutes",
"components.TvDetails.firstAirDate": "First Air Date", "components.TvDetails.firstAirDate": "First Air Date",
"components.TvDetails.managemovie": "Manage Movie",
"components.TvDetails.network": "{networkCount, plural, one {Network} other {Networks}}", "components.TvDetails.network": "{networkCount, plural, one {Network} other {Networks}}",
"components.TvDetails.nextAirDate": "Next Air Date", "components.TvDetails.nextAirDate": "Next Air Date",
"components.TvDetails.originallanguage": "Original Language", "components.TvDetails.originallanguage": "Original Language",
@ -863,6 +870,7 @@
"components.TvDetails.playonplex": "Play on Plex", "components.TvDetails.playonplex": "Play on Plex",
"components.TvDetails.productioncountries": "Production {countryCount, plural, one {Country} other {Countries}}", "components.TvDetails.productioncountries": "Production {countryCount, plural, one {Country} other {Countries}}",
"components.TvDetails.recommendations": "Recommendations", "components.TvDetails.recommendations": "Recommendations",
"components.TvDetails.reportissue": "Report an Issue",
"components.TvDetails.seasons": "{seasonCount, plural, one {# Season} other {# Seasons}}", "components.TvDetails.seasons": "{seasonCount, plural, one {# Season} other {# Seasons}}",
"components.TvDetails.showtype": "Series Type", "components.TvDetails.showtype": "Series Type",
"components.TvDetails.similar": "Similar Series", "components.TvDetails.similar": "Similar Series",

Loading…
Cancel
Save