Merge branch 'develop'

This commit is contained in:
sct
2020-12-23 21:39:00 +09:00
38 changed files with 632 additions and 165 deletions

View File

@@ -2,7 +2,7 @@
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: '' title: ''
labels: bug labels: 'awaiting-triage, type:bug'
assignees: '' assignees: ''
--- ---

View File

@@ -2,7 +2,7 @@
name: Feature request name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
title: '' title: ''
labels: enhancement labels: 'awaiting-triage, type:enhancement'
assignees: '' assignees: ''
--- ---

2
.gitignore vendored
View File

@@ -36,7 +36,7 @@ config/db/db.sqlite3
config/settings.json config/settings.json
# logs # logs
config/logs/*.log config/logs/*.log*
# dist files # dist files
dist dist

View File

@@ -824,7 +824,9 @@ components:
authPass: authPass:
type: string type: string
nullable: true nullable: true
allowSelfSigned:
type: boolean
example: false
PersonDetail: PersonDetail:
type: object type: object
properties: properties:

View File

@@ -44,6 +44,7 @@
"react-spring": "^8.0.27", "react-spring": "^8.0.27",
"react-toast-notifications": "^2.4.0", "react-toast-notifications": "^2.4.0",
"react-transition-group": "^4.4.1", "react-transition-group": "^4.4.1",
"react-truncate-markup": "^5.0.1",
"react-use-clipboard": "1.0.2", "react-use-clipboard": "1.0.2",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"sqlite3": "^5.0.0", "sqlite3": "^5.0.0",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -71,7 +71,7 @@ export interface TmdbTvResult extends TmdbMediaResult {
name: string; name: string;
original_name: string; original_name: string;
origin_country: string[]; origin_country: string[];
first_air_Date: string; first_air_date: string;
} }
export interface TmdbPersonResult { export interface TmdbPersonResult {

View File

@@ -88,6 +88,7 @@ export class MediaRequest {
message: movie.overview, message: movie.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
notifyUser: this.requestedBy, notifyUser: this.requestedBy,
media,
}); });
} }
@@ -98,6 +99,7 @@ export class MediaRequest {
message: tv.overview, message: tv.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
notifyUser: this.requestedBy, notifyUser: this.requestedBy,
media,
extra: [ extra: [
{ {
name: 'Seasons', name: 'Seasons',
@@ -136,6 +138,7 @@ export class MediaRequest {
message: movie.overview, message: movie.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
notifyUser: this.requestedBy, notifyUser: this.requestedBy,
media,
}); });
} else if (this.media.mediaType === MediaType.TV) { } else if (this.media.mediaType === MediaType.TV) {
const tv = await tmdb.getTvShow({ tvId: this.media.tmdbId }); const tv = await tmdb.getTvShow({ tvId: this.media.tmdbId });
@@ -144,6 +147,7 @@ export class MediaRequest {
message: tv.overview, message: tv.overview,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
notifyUser: this.requestedBy, notifyUser: this.requestedBy,
media,
extra: [ extra: [
{ {
name: 'Seasons', name: 'Seasons',

View File

@@ -17,7 +17,7 @@ const UPDATE_RATE = 4 * 1000;
const imdbRegex = new RegExp(/imdb:\/\/(tt[0-9]+)/); const imdbRegex = new RegExp(/imdb:\/\/(tt[0-9]+)/);
const tmdbRegex = new RegExp(/tmdb:\/\/([0-9]+)/); const tmdbRegex = new RegExp(/tmdb:\/\/([0-9]+)/);
const tvdbRegex = new RegExp(/tvdb:\/\/([0-9]+)/); const tvdbRegex = new RegExp(/tvdb:\/\/([0-9]+)|hama:\/\/tvdb-([0-9]+)/);
const tmdbShowRegex = new RegExp(/themoviedb:\/\/([0-9]+)/); const tmdbShowRegex = new RegExp(/themoviedb:\/\/([0-9]+)/);
const plexRegex = new RegExp(/plex:\/\//); const plexRegex = new RegExp(/plex:\/\//);
@@ -100,7 +100,7 @@ class JobPlexSync {
let tmdbMovie: TmdbMovieDetails | undefined; let tmdbMovie: TmdbMovieDetails | undefined;
const imdbMatch = plexitem.guid.match(imdbRegex); const imdbMatch = plexitem.guid.match(imdbRegex);
const tmdbMatch = plexitem.guid.match(tmdbRegex); const tmdbMatch = plexitem.guid.match(tmdbShowRegex);
if (imdbMatch) { if (imdbMatch) {
tmdbMovie = await this.tmdb.getMovieByImdbId({ tmdbMovie = await this.tmdb.getMovieByImdbId({

View File

@@ -20,7 +20,7 @@ export const startJobs = (): void => {
jobPlexRecentSync.run(); jobPlexRecentSync.run();
}), }),
}); });
// Run full plex sync every 6 hours // Run full plex sync every 24 hours
scheduledJobs.push({ scheduledJobs.push({
name: 'Plex Full Library Sync', name: 'Plex Full Library Sync',
job: schedule.scheduleJob('0 0 3 * * *', () => { job: schedule.scheduleJob('0 0 3 * * *', () => {

View File

@@ -1,10 +1,12 @@
import { Notification } from '..'; import { Notification } from '..';
import Media from '../../../entity/Media';
import { User } from '../../../entity/User'; import { User } from '../../../entity/User';
import { NotificationAgentConfig } from '../../settings'; import { NotificationAgentConfig } from '../../settings';
export interface NotificationPayload { export interface NotificationPayload {
subject: string; subject: string;
notifyUser: User; notifyUser: User;
media?: Media;
image?: string; image?: string;
message?: string; message?: string;
extra?: { name: string; value: string }[]; extra?: { name: string; value: string }[];

View File

@@ -93,7 +93,8 @@ class DiscordAgent
type: Notification, type: Notification,
payload: NotificationPayload payload: NotificationPayload
): DiscordRichEmbed { ): DiscordRichEmbed {
let color = EmbedColors.DEFAULT; const settings = getSettings();
let color = EmbedColors.DARK_PURPLE;
const fields: Field[] = []; const fields: Field[] = [];
@@ -112,6 +113,13 @@ class DiscordAgent
inline: true, inline: true,
} }
); );
if (settings.main.applicationUrl) {
fields.push({
name: 'View Media',
value: `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`,
});
}
break; break;
case Notification.MEDIA_APPROVED: case Notification.MEDIA_APPROVED:
color = EmbedColors.PURPLE; color = EmbedColors.PURPLE;
@@ -127,6 +135,13 @@ class DiscordAgent
inline: true, inline: true,
} }
); );
if (settings.main.applicationUrl) {
fields.push({
name: 'View Media',
value: `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`,
});
}
break; break;
case Notification.MEDIA_AVAILABLE: case Notification.MEDIA_AVAILABLE:
color = EmbedColors.GREEN; color = EmbedColors.GREEN;
@@ -142,6 +157,13 @@ class DiscordAgent
inline: true, inline: true,
} }
); );
if (settings.main.applicationUrl) {
fields.push({
name: 'View Media',
value: `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`,
});
}
break; break;
} }
@@ -150,7 +172,7 @@ class DiscordAgent
description: payload.message, description: payload.message,
color, color,
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
author: { name: 'Overseerr' }, author: { name: 'Overseerr', url: settings.main.applicationUrl },
fields: [ fields: [
...fields, ...fields,
// If we have extra data, map it to fields for discord notifications // If we have extra data, map it to fields for discord notifications

View File

@@ -41,6 +41,11 @@ class EmailAgent
host: emailSettings.smtpHost, host: emailSettings.smtpHost,
port: emailSettings.smtpPort, port: emailSettings.smtpPort,
secure: emailSettings.secure, secure: emailSettings.secure,
tls: emailSettings.allowSelfSigned
? {
rejectUnauthorized: false,
}
: undefined,
auth: auth:
emailSettings.authUser && emailSettings.authPass emailSettings.authUser && emailSettings.authPass
? { ? {
@@ -89,7 +94,10 @@ class EmailAgent
imageUrl: payload.image, imageUrl: payload.image,
timestamp: new Date().toTimeString(), timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.username, requestedBy: payload.notifyUser.username,
actionUrl: applicationUrl, actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
applicationUrl,
requestType: 'New Request', requestType: 'New Request',
}, },
}); });
@@ -110,7 +118,7 @@ class EmailAgent
try { try {
const email = this.getNewEmail(); const email = this.getNewEmail();
email.send({ await email.send({
template: path.join( template: path.join(
__dirname, __dirname,
'../../../templates/email/media-request' '../../../templates/email/media-request'
@@ -124,7 +132,10 @@ class EmailAgent
imageUrl: payload.image, imageUrl: payload.image,
timestamp: new Date().toTimeString(), timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.username, requestedBy: payload.notifyUser.username,
actionUrl: applicationUrl, actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
applicationUrl,
requestType: 'Request Approved', requestType: 'Request Approved',
}, },
}); });
@@ -144,7 +155,7 @@ class EmailAgent
try { try {
const email = this.getNewEmail(); const email = this.getNewEmail();
email.send({ await email.send({
template: path.join( template: path.join(
__dirname, __dirname,
'../../../templates/email/media-request' '../../../templates/email/media-request'
@@ -158,7 +169,10 @@ class EmailAgent
imageUrl: payload.image, imageUrl: payload.image,
timestamp: new Date().toTimeString(), timestamp: new Date().toTimeString(),
requestedBy: payload.notifyUser.username, requestedBy: payload.notifyUser.username,
actionUrl: applicationUrl, actionUrl: applicationUrl
? `${applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`
: undefined,
applicationUrl,
requestType: 'Now Available', requestType: 'Now Available',
}, },
}); });
@@ -178,14 +192,14 @@ class EmailAgent
try { try {
const email = this.getNewEmail(); const email = this.getNewEmail();
email.send({ await email.send({
template: path.join(__dirname, '../../../templates/email/test-email'), template: path.join(__dirname, '../../../templates/email/test-email'),
message: { message: {
to: payload.notifyUser.email, to: payload.notifyUser.email,
}, },
locals: { locals: {
body: payload.message, body: payload.message,
actionUrl: applicationUrl, applicationUrl,
}, },
}); });
return true; return true;

View File

@@ -74,6 +74,7 @@ export interface NotificationAgentEmail extends NotificationAgentConfig {
secure: boolean; secure: boolean;
authUser?: string; authUser?: string;
authPass?: string; authPass?: string;
allowSelfSigned: boolean;
}; };
} }
@@ -129,8 +130,9 @@ class Settings {
options: { options: {
emailFrom: '', emailFrom: '',
smtpHost: '127.0.0.1', smtpHost: '127.0.0.1',
smtpPort: 465, smtpPort: 587,
secure: false, secure: false,
allowSelfSigned: false,
}, },
}, },
discord: { discord: {

View File

@@ -16,15 +16,23 @@ const hformat = winston.format.printf(
const logger = winston.createLogger({ const logger = winston.createLogger({
level: process.env.LOG_LEVEL || 'debug', level: process.env.LOG_LEVEL || 'debug',
format: winston.format.combine( format: winston.format.combine(
winston.format.colorize(),
winston.format.splat(), winston.format.splat(),
winston.format.timestamp(), winston.format.timestamp(),
hformat hformat
), ),
transports: [ transports: [
new winston.transports.Console(), new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.splat(),
winston.format.timestamp(),
hformat
),
}),
new winston.transports.File({ new winston.transports.File({
filename: path.join(__dirname, '../config/logs/overseerr.log'), filename: path.join(__dirname, '../config/logs/overseerr.log'),
maxsize: 20971520,
maxFiles: 6,
}), }),
], ],
}); });

View File

@@ -78,7 +78,7 @@ export const mapTvResult = (
media?: Media media?: Media
): TvResult => ({ ): TvResult => ({
id: tvResult.id, id: tvResult.id,
firstAirDate: tvResult.first_air_Date, firstAirDate: tvResult.first_air_date,
genreIds: tvResult.genre_ids, genreIds: tvResult.genre_ids,
// Some results from tmdb dont return the mediaType so we force it here! // Some results from tmdb dont return the mediaType so we force it here!
mediaType: tvResult.media_type || 'tv', mediaType: tvResult.media_type || 'tv',

View File

@@ -29,6 +29,7 @@ export class MediaSubscriber implements EntitySubscriberInterface {
notifyUser: request.requestedBy, notifyUser: request.requestedBy,
subject: movie.title, subject: movie.title,
message: movie.overview, message: movie.overview,
media: entity,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${movie.poster_path}`,
}); });
}); });
@@ -79,6 +80,7 @@ export class MediaSubscriber implements EntitySubscriberInterface {
message: tv.overview, message: tv.overview,
notifyUser: request.requestedBy, notifyUser: request.requestedBy,
image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`, image: `https://image.tmdb.org/t/p/w600_and_h900_bestv2${tv.poster_path}`,
media: entity,
extra: [ extra: [
{ {
name: 'Seasons', name: 'Seasons',

View File

@@ -47,7 +47,7 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en')
padding-bottom: 25px;\ padding-bottom: 25px;\
text-align: center;\ text-align: center;\
') ')
a(href=actionUrl style='\ a(href=applicationUrl style='\
text-shadow: 0 1px 0 #ffffff;\ text-shadow: 0 1px 0 #ffffff;\
font-weight: 700;\ font-weight: 700;\
font-size: 16px;\ font-size: 16px;\
@@ -92,7 +92,7 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en')
margin-bottom: 20px;\ margin-bottom: 20px;\
color: #51545e;\ color: #51545e;\
') ')
a(href=actionUrl style='color: #3869d4') Open Overseerr a(href=actionUrl style='color: #3869d4') Open Media in Overseerr
tr tr
td td
table.sm-w-full(align='center' style='\ table.sm-w-full(align='center' style='\

View File

@@ -47,7 +47,7 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en')
padding-bottom: 25px;\ padding-bottom: 25px;\
text-align: center;\ text-align: center;\
') ')
a(href=actionUrl style='\ a(href=applicationUrl style='\
text-shadow: 0 1px 0 #ffffff;\ text-shadow: 0 1px 0 #ffffff;\
font-weight: 700;\ font-weight: 700;\
font-size: 16px;\ font-size: 16px;\
@@ -74,7 +74,7 @@ div(role='article' aria-roledescription='email' aria-label='' lang='en')
margin-bottom: 20px;\ margin-bottom: 20px;\
color: #51545e;\ color: #51545e;\
') ')
a(href=actionUrl style='color: #3869d4') Open Overseerr a(href=applicationUrl style='color: #3869d4') Open Overseerr
tr tr
td td
table.sm-w-full(align='center' style='\ table.sm-w-full(align='center' style='\

6
src/assets/ellipsis.svg Normal file
View File

@@ -0,0 +1,6 @@
<svg width="22" height="10" viewBox="0 0 22 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="22" height="10" rx="2" fill="#718096"/>
<circle cx="5" cy="5" r="2" fill="#E2E8F0"/>
<circle cx="11" cy="5" r="2" fill="#E2E8F0"/>
<circle cx="17" cy="5" r="2" fill="#E2E8F0"/>
</svg>

After

Width:  |  Height:  |  Size: 293 B

View File

@@ -8,12 +8,18 @@ import React, {
interface ImageFaderProps extends HTMLAttributes<HTMLDivElement> { interface ImageFaderProps extends HTMLAttributes<HTMLDivElement> {
backgroundImages: string[]; backgroundImages: string[];
rotationSpeed?: number; rotationSpeed?: number;
isDarker?: boolean;
} }
const DEFAULT_ROTATION_SPEED = 6000; const DEFAULT_ROTATION_SPEED = 6000;
const ImageFader: ForwardRefRenderFunction<HTMLDivElement, ImageFaderProps> = ( const ImageFader: ForwardRefRenderFunction<HTMLDivElement, ImageFaderProps> = (
{ backgroundImages, rotationSpeed = DEFAULT_ROTATION_SPEED, ...props }, {
backgroundImages,
rotationSpeed = DEFAULT_ROTATION_SPEED,
isDarker,
...props
},
ref ref
) => { ) => {
const [activeIndex, setIndex] = useState(0); const [activeIndex, setIndex] = useState(0);
@@ -29,6 +35,14 @@ const ImageFader: ForwardRefRenderFunction<HTMLDivElement, ImageFaderProps> = (
}; };
}, [backgroundImages, rotationSpeed]); }, [backgroundImages, rotationSpeed]);
let gradient =
'linear-gradient(180deg, rgba(45, 55, 72, 0.47) 0%, #1A202E 100%)';
if (isDarker) {
gradient =
'linear-gradient(180deg, rgba(17, 24, 39, 0.47) 0%, rgba(17, 24, 39, 1) 100%)';
}
return ( return (
<div ref={ref}> <div ref={ref}>
{backgroundImages.map((imageUrl, i) => ( {backgroundImages.map((imageUrl, i) => (
@@ -38,7 +52,7 @@ const ImageFader: ForwardRefRenderFunction<HTMLDivElement, ImageFaderProps> = (
i === activeIndex ? 'opacity-100' : 'opacity-0' i === activeIndex ? 'opacity-100' : 'opacity-0'
}`} }`}
style={{ style={{
backgroundImage: `linear-gradient(180deg, rgba(45, 55, 72, 0.47) 0%, #1A202E 100%), url(${imageUrl})`, backgroundImage: `${gradient}, url(${imageUrl})`,
}} }}
{...props} {...props}
/> />

View File

@@ -1,5 +1,6 @@
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import React, { useContext, useState } from 'react'; import React, { useContext, useState } from 'react';
import TruncateMarkup from 'react-truncate-markup';
import useSWR from 'swr'; import useSWR from 'swr';
import type { PersonDetail } from '../../../server/models/Person'; import type { PersonDetail } from '../../../server/models/Person';
import type { PersonCombinedCreditsResponse } from '../../../server/interfaces/api/personInterfaces'; import type { PersonCombinedCreditsResponse } from '../../../server/interfaces/api/personInterfaces';
@@ -8,6 +9,8 @@ import LoadingSpinner from '../Common/LoadingSpinner';
import TitleCard from '../TitleCard'; import TitleCard from '../TitleCard';
import { defineMessages, useIntl } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import { LanguageContext } from '../../context/LanguageContext'; import { LanguageContext } from '../../context/LanguageContext';
import ImageFader from '../Common/ImageFader';
import Ellipsis from '../../assets/ellipsis.svg';
const messages = defineMessages({ const messages = defineMessages({
appearsin: 'Appears in', appearsin: 'Appears in',
@@ -74,7 +77,21 @@ const PersonDetails: React.FC = () => {
return ( return (
<> <>
<div className="flex flex-col items-center mt-8 mb-8 md:flex-row md:items-start"> {(sortedCrew || sortedCast) && (
<div className="absolute top-0 left-0 right-0 z-0 h-96">
<ImageFader
isDarker
backgroundImages={[...(sortedCast ?? []), ...(sortedCrew ?? [])]
.filter((media) => media.backdropPath)
.map(
(media) =>
`//image.tmdb.org/t/p/w1920_and_h800_multi_faces/${media.backdropPath}`
)
.slice(0, 6)}
/>
</div>
)}
<div className="relative z-10 flex flex-col items-center mt-8 mb-8 md:flex-row md:items-start">
{data.profilePath && ( {data.profilePath && (
<div <div
style={{ style={{
@@ -88,30 +105,30 @@ const PersonDetails: React.FC = () => {
<div className="relative"> <div className="relative">
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
<div <div
className={`transition-max-height duration-300 ${ className="outline-none group ring-0"
showBio
? 'overflow-visible extra-max-height'
: 'overflow-hidden max-h-44'
}`}
onClick={() => setShowBio((show) => !show)} onClick={() => setShowBio((show) => !show)}
role="button" role="button"
tabIndex={-1} tabIndex={-1}
> >
<div className={showBio ? 'h-auto' : 'h-36'}> <TruncateMarkup
{data.biography lines={showBio ? 200 : 6}
? data.biography ellipsis={
: intl.formatMessage(messages.nobiography)} <Ellipsis className="relative inline-block ml-2 -top-0.5 opacity-70 group-hover:opacity-100 transition duration-300" />
</div> }
{!showBio && ( >
<div className="absolute bottom-0 left-0 right-0 w-full h-8 bg-gradient-to-t from-gray-900" /> <div>
)} {data.biography
? data.biography
: intl.formatMessage(messages.nobiography)}
</div>
</TruncateMarkup>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{(sortedCast ?? []).length > 0 && ( {(sortedCast ?? []).length > 0 && (
<> <>
<div className="mt-6 mb-4 md:flex md:items-center md:justify-between"> <div className="relative z-10 mt-6 mb-4 md:flex md:items-center md:justify-between">
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="inline-flex items-center text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate"> <div className="inline-flex items-center text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate">
<span>{intl.formatMessage(messages.appearsin)}</span> <span>{intl.formatMessage(messages.appearsin)}</span>
@@ -157,7 +174,7 @@ const PersonDetails: React.FC = () => {
)} )}
{(sortedCrew ?? []).length > 0 && ( {(sortedCrew ?? []).length > 0 && (
<> <>
<div className="mt-6 mb-4 md:flex md:items-center md:justify-between"> <div className="relative z-10 mt-6 mb-4 md:flex md:items-center md:justify-between">
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="inline-flex items-center text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate"> <div className="inline-flex items-center text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate">
<span>{intl.formatMessage(messages.crewmember)}</span> <span>{intl.formatMessage(messages.crewmember)}</span>

View File

@@ -84,7 +84,7 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
</div> </div>
)} )}
</div> </div>
<div className="ml-2 flex-shrink-0 flex"> <div className="ml-2 flex-shrink-0 flex flex-wrap">
{request.status === MediaRequestStatus.PENDING && ( {request.status === MediaRequestStatus.PENDING && (
<> <>
<span className="mr-1"> <span className="mr-1">

View File

@@ -25,6 +25,9 @@ const messages = defineMessages({
emailsettingsfailed: 'Email notification settings failed to save.', emailsettingsfailed: 'Email notification settings failed to save.',
test: 'Test', test: 'Test',
testsent: 'Test notification sent!', testsent: 'Test notification sent!',
allowselfsigned: 'Allow Self-Signed Certificates',
ssldisabletip:
'SSL should be disabled on standard TLS connections (Port 587)',
}); });
const NotificationsEmail: React.FC = () => { const NotificationsEmail: React.FC = () => {
@@ -61,6 +64,7 @@ const NotificationsEmail: React.FC = () => {
secure: data.options.secure, secure: data.options.secure,
authUser: data.options.authUser, authUser: data.options.authUser,
authPass: data.options.authPass, authPass: data.options.authPass,
allowSelfSigned: data.options.allowSelfSigned,
}} }}
validationSchema={NotificationsDiscordSchema} validationSchema={NotificationsDiscordSchema}
onSubmit={async (values) => { onSubmit={async (values) => {
@@ -75,6 +79,7 @@ const NotificationsEmail: React.FC = () => {
secure: values.secure, secure: values.secure,
authUser: values.authUser, authUser: values.authUser,
authPass: values.authPass, authPass: values.authPass,
allowSelfSigned: values.allowSelfSigned,
}, },
}); });
addToast(intl.formatMessage(messages.emailsettingssaved), { addToast(intl.formatMessage(messages.emailsettingssaved), {
@@ -116,7 +121,7 @@ const NotificationsEmail: React.FC = () => {
<Form> <Form>
<div className="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5"> <div className="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label <label
htmlFor="isDefault" htmlFor="enabled"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2" className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
> >
{intl.formatMessage(messages.agentenabled)} {intl.formatMessage(messages.agentenabled)}
@@ -126,131 +131,152 @@ const NotificationsEmail: React.FC = () => {
type="checkbox" type="checkbox"
id="enabled" id="enabled"
name="enabled" name="enabled"
className="form-checkbox rounded-md h-6 w-6 text-indigo-600 transition duration-150 ease-in-out" className="w-6 h-6 text-indigo-600 transition duration-150 ease-in-out rounded-md form-checkbox"
/> />
</div> </div>
</div> </div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5"> <div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label <label
htmlFor="name" htmlFor="emailFrom"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2" className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
> >
{intl.formatMessage(messages.emailsender)} {intl.formatMessage(messages.emailsender)}
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2"> <div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<Field <Field
id="emailFrom" id="emailFrom"
name="emailFrom" name="emailFrom"
type="text" type="text"
placeholder="no-reply@example.com" placeholder="no-reply@example.com"
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500" className="flex-1 block w-full min-w-0 transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
/> />
</div> </div>
{errors.emailFrom && touched.emailFrom && ( {errors.emailFrom && touched.emailFrom && (
<div className="text-red-500 mt-2">{errors.emailFrom}</div> <div className="mt-2 text-red-500">{errors.emailFrom}</div>
)} )}
</div> </div>
</div> </div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5"> <div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label <label
htmlFor="name" htmlFor="smtpHost"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2" className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
> >
{intl.formatMessage(messages.smtpHost)} {intl.formatMessage(messages.smtpHost)}
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2"> <div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<Field <Field
id="smtpHost" id="smtpHost"
name="smtpHost" name="smtpHost"
type="text" type="text"
placeholder="localhost" placeholder="localhost"
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500" className="flex-1 block w-full min-w-0 transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
/> />
</div> </div>
{errors.smtpHost && touched.smtpHost && ( {errors.smtpHost && touched.smtpHost && (
<div className="text-red-500 mt-2">{errors.smtpHost}</div> <div className="mt-2 text-red-500">{errors.smtpHost}</div>
)} )}
</div> </div>
</div> </div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5"> <div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label <label
htmlFor="name" htmlFor="smtpPort"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2" className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
> >
{intl.formatMessage(messages.smtpPort)} {intl.formatMessage(messages.smtpPort)}
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2"> <div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<Field <Field
id="smtpPort" id="smtpPort"
name="smtpPort" name="smtpPort"
type="text" type="text"
placeholder="465" placeholder="465"
className="form-input block w-24 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500" className="block w-24 transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
/> />
</div> </div>
{errors.smtpPort && touched.smtpPort && ( {errors.smtpPort && touched.smtpPort && (
<div className="text-red-500 mt-2">{errors.smtpPort}</div> <div className="mt-2 text-red-500">{errors.smtpPort}</div>
)} )}
</div> </div>
</div> </div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5"> <div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label <label
htmlFor="isDefault" htmlFor="secure"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2" className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
> >
{intl.formatMessage(messages.enableSsl)} <div className="flex flex-col">
<span>{intl.formatMessage(messages.enableSsl)}</span>
<span className="text-gray-500">
{intl.formatMessage(messages.ssldisabletip)}
</span>
</div>
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2"> <div className="mt-1 sm:mt-0 sm:col-span-2">
<Field <Field
type="checkbox" type="checkbox"
id="secure" id="secure"
name="secure" name="secure"
className="form-checkbox rounded-md h-6 w-6 text-indigo-600 transition duration-150 ease-in-out" className="w-6 h-6 text-indigo-600 transition duration-150 ease-in-out rounded-md form-checkbox"
/>
</div>
</div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label
htmlFor="allowSelfSigned"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
>
{intl.formatMessage(messages.allowselfsigned)}
</label>
<div className="mt-1 sm:mt-0 sm:col-span-2">
<Field
type="checkbox"
id="allowSelfSigned"
name="allowSelfSigned"
className="w-6 h-6 text-indigo-600 transition duration-150 ease-in-out rounded-md form-checkbox"
/> />
</div> </div>
</div> </div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5"> <div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label <label
htmlFor="name" htmlFor="authUser"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2" className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
> >
{intl.formatMessage(messages.authUser)} {intl.formatMessage(messages.authUser)}
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2"> <div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<Field <Field
id="authUser" id="authUser"
name="authUser" name="authUser"
type="text" type="text"
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500" className="flex-1 block w-full min-w-0 transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
/> />
</div> </div>
</div> </div>
</div> </div>
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5"> <div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
<label <label
htmlFor="name" htmlFor="authPass"
className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2" className="block text-sm font-medium leading-5 text-gray-400 sm:mt-px sm:pt-2"
> >
{intl.formatMessage(messages.authPass)} {intl.formatMessage(messages.authPass)}
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2"> <div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<Field <Field
id="authPass" id="authPass"
name="authPass" name="authPass"
type="password" type="password"
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500" className="flex-1 block w-full min-w-0 transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
/> />
</div> </div>
</div> </div>
</div> </div>
<div className="mt-8 border-t border-gray-700 pt-5"> <div className="pt-5 mt-8 border-t border-gray-700">
<div className="flex justify-end"> <div className="flex justify-end">
<span className="ml-3 inline-flex rounded-md shadow-sm"> <span className="inline-flex ml-3 rounded-md shadow-sm">
<Button <Button
buttonType="warning" buttonType="warning"
disabled={isSubmitting || !isValid} disabled={isSubmitting || !isValid}
@@ -263,7 +289,7 @@ const NotificationsEmail: React.FC = () => {
{intl.formatMessage(messages.test)} {intl.formatMessage(messages.test)}
</Button> </Button>
</span> </span>
<span className="ml-3 inline-flex rounded-md shadow-sm"> <span className="inline-flex ml-3 rounded-md shadow-sm">
<Button <Button
buttonType="primary" buttonType="primary"
type="submit" type="submit"

View File

@@ -28,7 +28,7 @@ const messages = defineMessages({
sync: 'Sync Plex Libraries', sync: 'Sync Plex Libraries',
manualscan: 'Manual Library Scan', manualscan: 'Manual Library Scan',
manualscanDescription: manualscanDescription:
"Normally, this will only be run once every 6 hours. Overseerr will check your Plex server's recently added more aggressively. If this is your first time configuring Plex, a one time full manual library scan is recommended!", "Normally, this will only be run once every 24 hours. Overseerr will check your Plex server's recently added more aggressively. If this is your first time configuring Plex, a one time full manual library scan is recommended!",
notrunning: 'Not Running', notrunning: 'Not Running',
currentlibrary: 'Current Library: {name}', currentlibrary: 'Current Library: {name}',
librariesRemaining: 'Libraries Remaining: {count}', librariesRemaining: 'Libraries Remaining: {count}',
@@ -143,10 +143,10 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
return ( return (
<> <>
<div> <div>
<h3 className="text-lg leading-6 font-medium text-gray-200"> <h3 className="text-lg font-medium leading-6 text-gray-200">
<FormattedMessage {...messages.plexsettings} /> <FormattedMessage {...messages.plexsettings} />
</h3> </h3>
<p className="mt-1 max-w-2xl text-sm leading-5 text-gray-500"> <p className="max-w-2xl mt-1 text-sm leading-5 text-gray-500">
<FormattedMessage {...messages.plexsettingsDescription} /> <FormattedMessage {...messages.plexsettingsDescription} />
</p> </p>
</div> </div>
@@ -188,7 +188,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div className="mt-6 sm:mt-5"> <div className="mt-6 sm:mt-5">
{submitError && ( {submitError && (
<div className="bg-red-700 text-white p-4 rounded-md mb-6"> <div className="p-4 mb-6 text-white bg-red-700 rounded-md">
{submitError} {submitError}
</div> </div>
)} )}
@@ -200,7 +200,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
<FormattedMessage {...messages.servername} /> <FormattedMessage {...messages.servername} />
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2"> <div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<input <input
type="text" type="text"
id="name" id="name"
@@ -210,7 +210,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
)} )}
value={data?.name} value={data?.name}
readOnly readOnly
className="flex-1 form-input block w-full min-w-0 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500" className="flex-1 block w-full min-w-0 transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
/> />
</div> </div>
</div> </div>
@@ -223,8 +223,8 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
<FormattedMessage {...messages.hostname} /> <FormattedMessage {...messages.hostname} />
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2"> <div className="mt-1 sm:mt-0 sm:col-span-2">
<div className="max-w-lg flex rounded-md shadow-sm"> <div className="flex max-w-lg rounded-md shadow-sm">
<span className="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-500 bg-gray-800 text-gray-100 sm:text-sm cursor-default"> <span className="inline-flex items-center px-3 text-gray-100 bg-gray-800 border border-r-0 border-gray-500 cursor-default rounded-l-md sm:text-sm">
{values.useSsl ? 'https://' : 'http://'} {values.useSsl ? 'https://' : 'http://'}
</span> </span>
<Field <Field
@@ -232,11 +232,11 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
id="hostname" id="hostname"
name="hostname" name="hostname"
placeholder="127.0.0.1" placeholder="127.0.0.1"
className="flex-1 form-input block w-full min-w-0 rounded-r-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500" className="flex-1 block w-full min-w-0 transition duration-150 ease-in-out bg-gray-700 border border-gray-500 form-input rounded-r-md sm:text-sm sm:leading-5"
/> />
</div> </div>
{errors.hostname && touched.hostname && ( {errors.hostname && touched.hostname && (
<div className="text-red-500 mt-2">{errors.hostname}</div> <div className="mt-2 text-red-500">{errors.hostname}</div>
)} )}
</div> </div>
</div> </div>
@@ -254,11 +254,11 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
id="port" id="port"
name="port" name="port"
placeholder="32400" placeholder="32400"
className="form-input block w-24 rounded-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500" className="block w-24 transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5"
/> />
</div> </div>
{errors.port && touched.port && ( {errors.port && touched.port && (
<div className="text-red-500 mt-2">{errors.port}</div> <div className="mt-2 text-red-500">{errors.port}</div>
)} )}
</div> </div>
</div> </div>
@@ -278,13 +278,13 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
onChange={() => { onChange={() => {
setFieldValue('useSsl', !values.useSsl); setFieldValue('useSsl', !values.useSsl);
}} }}
className="form-checkbox h-6 w-6 rounded-md text-indigo-600 transition duration-150 ease-in-out" className="w-6 h-6 text-indigo-600 transition duration-150 ease-in-out rounded-md form-checkbox"
/> />
</div> </div>
</div> </div>
<div className="mt-8 border-t border-gray-700 pt-5"> <div className="pt-5 mt-8 border-t border-gray-700">
<div className="flex justify-end"> <div className="flex justify-end">
<span className="ml-3 inline-flex rounded-md shadow-sm"> <span className="inline-flex ml-3 rounded-md shadow-sm">
<Button <Button
buttonType="primary" buttonType="primary"
type="submit" type="submit"
@@ -302,10 +302,10 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
}} }}
</Formik> </Formik>
<div className="mt-10"> <div className="mt-10">
<h3 className="text-lg leading-6 font-medium text-gray-200"> <h3 className="text-lg font-medium leading-6 text-gray-200">
<FormattedMessage {...messages.plexlibraries} /> <FormattedMessage {...messages.plexlibraries} />
</h3> </h3>
<p className="mt-1 max-w-2xl text-sm leading-5 text-gray-500"> <p className="max-w-2xl mt-1 text-sm leading-5 text-gray-500">
<FormattedMessage {...messages.plexlibrariesDescription} /> <FormattedMessage {...messages.plexlibrariesDescription} />
</p> </p>
<div className="mt-6"> <div className="mt-6">
@@ -327,7 +327,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
: intl.formatMessage(messages.sync)} : intl.formatMessage(messages.sync)}
</Button> </Button>
</div> </div>
<ul className="mt-6 grid grid-cols-1 gap-5 sm:gap-6 sm:grid-cols-2 lg:grid-cols-4"> <ul className="grid grid-cols-1 gap-5 mt-6 sm:gap-6 sm:grid-cols-2 lg:grid-cols-4">
{data?.libraries.map((library) => ( {data?.libraries.map((library) => (
<LibraryItem <LibraryItem
name={library.name} name={library.name}
@@ -339,18 +339,18 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
</ul> </ul>
</div> </div>
<div className="mt-10"> <div className="mt-10">
<h3 className="text-lg leading-6 font-medium text-gray-200"> <h3 className="text-lg font-medium leading-6 text-gray-200">
<FormattedMessage {...messages.manualscan} /> <FormattedMessage {...messages.manualscan} />
</h3> </h3>
<p className="mt-1 max-w-2xl text-sm leading-5 text-gray-500"> <p className="max-w-2xl mt-1 text-sm leading-5 text-gray-500">
<FormattedMessage {...messages.manualscanDescription} /> <FormattedMessage {...messages.manualscanDescription} />
</p> </p>
<div className="mt-6"> <div className="mt-6">
<div className="bg-gray-800 p-4 rounded-md"> <div className="p-4 bg-gray-800 rounded-md">
<div className="w-full h-8 rounded-full bg-gray-600 mb-6 relative overflow-hidden"> <div className="relative w-full h-8 mb-6 overflow-hidden bg-gray-600 rounded-full">
{dataSync?.running && ( {dataSync?.running && (
<div <div
className="h-8 bg-indigo-600 transition-all ease-in-out duration-200" className="h-8 transition-all duration-200 ease-in-out bg-indigo-600"
style={{ style={{
width: `${Math.round( width: `${Math.round(
(dataSync.progress / dataSync.total) * 100 (dataSync.progress / dataSync.total) * 100
@@ -358,7 +358,7 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
}} }}
/> />
)} )}
<div className="absolute inset-0 text-sm w-full h-8 flex items-center justify-center"> <div className="absolute inset-0 flex items-center justify-center w-full h-8 text-sm">
<span> <span>
{dataSync?.running {dataSync?.running
? `${dataSync.progress} of ${dataSync.total}` ? `${dataSync.progress} of ${dataSync.total}`
@@ -366,10 +366,10 @@ const SettingsPlex: React.FC<SettingsPlexProps> = ({ onComplete }) => {
</span> </span>
</div> </div>
</div> </div>
<div className="flex w-full flex-col sm:flex-row"> <div className="flex flex-col w-full sm:flex-row">
{dataSync?.running && ( {dataSync?.running && (
<> <>
<div className="flex items-center mr-0 mb-2 sm:mb-0 sm:mr-2"> <div className="flex items-center mb-2 mr-0 sm:mb-0 sm:mr-2">
<Badge> <Badge>
<FormattedMessage <FormattedMessage
{...messages.currentlibrary} {...messages.currentlibrary}

View File

@@ -99,7 +99,7 @@ const ServerInstance: React.FC<ServerInstanceProps> = ({
</p> </p>
</div> </div>
<img <img
className="w-10 h-10 bg-gray-300 rounded-full flex-shrink-0" className="w-10 h-10 flex-shrink-0"
src={`/images/${isSonarr ? 'sonarr' : 'radarr'}_logo.png`} src={`/images/${isSonarr ? 'sonarr' : 'radarr'}_logo.png`}
alt="" alt=""
/> />

View File

@@ -1,5 +1,10 @@
import React, { useState, useContext, useMemo } from 'react'; import React, { useState, useContext, useMemo } from 'react';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import {
FormattedMessage,
FormattedDate,
defineMessages,
useIntl,
} from 'react-intl';
import useSWR from 'swr'; import useSWR from 'swr';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import Button from '../Common/Button'; import Button from '../Common/Button';
@@ -34,6 +39,7 @@ import { sortCrewPriority } from '../../utils/creditHelpers';
import { Crew } from '../../../server/models/common'; import { Crew } from '../../../server/models/common';
const messages = defineMessages({ const messages = defineMessages({
firstAirDate: 'First Air Date',
userrating: 'User Rating', userrating: 'User Rating',
status: 'Status', status: 'Status',
originallanguage: 'Original Language', originallanguage: 'Original Language',
@@ -519,6 +525,21 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
</span> </span>
</div> </div>
)} )}
{data.firstAirDate && (
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
<span className="text-sm">
<FormattedMessage {...messages.firstAirDate} />
</span>
<span className="flex-1 text-sm text-right text-gray-400">
<FormattedDate
value={new Date(data.firstAirDate)}
year="numeric"
month="long"
day="numeric"
/>
</span>
</div>
)}
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0"> <div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
<span className="text-sm"> <span className="text-sm">
<FormattedMessage {...messages.status} /> <FormattedMessage {...messages.status} />

View File

@@ -88,8 +88,8 @@
"components.RequestModal.status": "Status", "components.RequestModal.status": "Status",
"components.Search.searchresults": "Suchergebnisse", "components.Search.searchresults": "Suchergebnisse",
"components.Settings.Notifications.agentenabled": "Agent aktiviert", "components.Settings.Notifications.agentenabled": "Agent aktiviert",
"components.Settings.Notifications.authPass": "Passwort", "components.Settings.Notifications.authPass": "Auth Pass",
"components.Settings.Notifications.authUser": "Benutzername", "components.Settings.Notifications.authUser": "Auth User",
"components.Settings.Notifications.emailsender": "E-Mail-Absenderadresse", "components.Settings.Notifications.emailsender": "E-Mail-Absenderadresse",
"components.Settings.Notifications.enableSsl": "SSL aktivieren", "components.Settings.Notifications.enableSsl": "SSL aktivieren",
"components.Settings.Notifications.save": "Änderungen speichern", "components.Settings.Notifications.save": "Änderungen speichern",
@@ -183,7 +183,7 @@
"components.Settings.jobname": "Auftragsname", "components.Settings.jobname": "Auftragsname",
"components.Settings.librariesRemaining": "Verbleibende Bibliotheken: {count}", "components.Settings.librariesRemaining": "Verbleibende Bibliotheken: {count}",
"components.Settings.manualscan": "Manueller Bibliotheksscan", "components.Settings.manualscan": "Manueller Bibliotheksscan",
"components.Settings.manualscanDescription": "Normalerweise wird dies nur einmal alle 6 Stunden ausgeführt. Overseerr überprüft die kürzlich hinzugefügten Plex-Server aggressiver. Wenn Sie Plex zum ersten Mal konfigurieren, wird ein einmaliger vollständiger manueller Bibliotheksscan empfohlen!", "components.Settings.manualscanDescription": "Normalerweise wird dies nur einmal alle 24 Stunden ausgeführt. Overseerr überprüft die kürzlich hinzugefügten Plex-Server aggressiver. Wenn Sie Plex zum ersten Mal konfigurieren, wird ein einmaliger vollständiger manueller Bibliotheksscan empfohlen!",
"components.Settings.menuAbout": "Über", "components.Settings.menuAbout": "Über",
"components.Settings.menuGeneralSettings": "Allgemeine Einstellungen", "components.Settings.menuGeneralSettings": "Allgemeine Einstellungen",
"components.Settings.menuJobs": "Anträge", "components.Settings.menuJobs": "Anträge",
@@ -348,5 +348,32 @@
"components.Settings.toastApiKeyFailure": "Bei der Generierung eines neuen API-Schlüssels kam es zu einem Fehler.", "components.Settings.toastApiKeyFailure": "Bei der Generierung eines neuen API-Schlüssels kam es zu einem Fehler.",
"components.Settings.SonarrModal.animerootfolder": "Animestammverzeichnis", "components.Settings.SonarrModal.animerootfolder": "Animestammverzeichnis",
"components.Settings.SonarrModal.animequalityprofile": "Animequalitätsprofil", "components.Settings.SonarrModal.animequalityprofile": "Animequalitätsprofil",
"components.MovieDetails.studio": "Studio" "components.MovieDetails.studio": "Studio",
"i18n.close": "Schließen",
"components.Settings.SettingsAbout.timezone": "Zeitzone",
"components.Settings.SettingsAbout.supportoverseerr": "Unterstützen Sie Overseerr",
"components.Settings.SettingsAbout.helppaycoffee": "Helfen Sie uns, für Kaffee zu bezahlen",
"components.Settings.SettingsAbout.Releases.viewongithub": "Ansicht auf GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Änderungsprotokoll anzeigen",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Änderungsprotokoll",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Die Änderungen in Ihrer Version sind unten nicht verfügbar. Die neuesten Aktualisierungen finden Sie im <GithubLink>GitHub-Repository</GithubLink>.",
"components.Settings.SettingsAbout.Releases.runningDevelop": "Sie führen eine Entwicklungsversion von Overseerr aus!",
"components.Settings.SettingsAbout.Releases.releases": "Veröffentlichungen",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Informationen der Version nicht verfügbar. Ist GitHub offline?",
"components.Settings.SettingsAbout.Releases.latestversion": "Neuste Version",
"components.Settings.SettingsAbout.Releases.currentversion": "Aktuelle Version",
"components.Settings.Notifications.testsent": "Testbenachrichtigung gesendet!",
"components.Settings.Notifications.test": "Test",
"components.Settings.defaultPermissions": "Standardbenutzerberechtigungen",
"components.UserList.importfromplexerror": "Beim Importieren von Benutzern aus Plex ist ein Fehler aufgetreten",
"components.UserList.importfromplex": "Benutzer/innen aus Plex importieren",
"components.TvDetails.viewfullcrew": "Volles Team anzeigen",
"components.TvDetails.TvCrew.fullseriescrew": "Volles Serienteam",
"components.PersonDetails.crewmember": "Teammitglied",
"components.MovieDetails.viewfullcrew": "Volles Team anzeigen",
"components.MovieDetails.MovieCrew.fullcrew": "Volles Team",
"components.UserList.importedfromplex": "{userCount, plural, =0 {Keine neue Benutzer} one {# neuer Benutzer} other {# neue Benutzer}} aus Plex importiert",
"components.TvDetails.firstAirDate": "Erster Sendetermin",
"components.Settings.Notifications.ssldisabletip": "SSL sollte bei Standard-TLS-Verbindungen deaktiviert werden (Port 587)",
"components.Settings.Notifications.allowselfsigned": "Selbstsignierte Zertifikate zulassen"
} }

View File

@@ -93,6 +93,7 @@
"components.RequestModal.status": "Status", "components.RequestModal.status": "Status",
"components.Search.searchresults": "Search Results", "components.Search.searchresults": "Search Results",
"components.Settings.Notifications.agentenabled": "Agent Enabled", "components.Settings.Notifications.agentenabled": "Agent Enabled",
"components.Settings.Notifications.allowselfsigned": "Allow Self-Signed Certificates",
"components.Settings.Notifications.authPass": "Auth Pass", "components.Settings.Notifications.authPass": "Auth Pass",
"components.Settings.Notifications.authUser": "Auth User", "components.Settings.Notifications.authUser": "Auth User",
"components.Settings.Notifications.discordsettingsfailed": "Discord notification settings failed to save.", "components.Settings.Notifications.discordsettingsfailed": "Discord notification settings failed to save.",
@@ -105,6 +106,7 @@
"components.Settings.Notifications.saving": "Saving…", "components.Settings.Notifications.saving": "Saving…",
"components.Settings.Notifications.smtpHost": "SMTP Host", "components.Settings.Notifications.smtpHost": "SMTP Host",
"components.Settings.Notifications.smtpPort": "SMTP Port", "components.Settings.Notifications.smtpPort": "SMTP Port",
"components.Settings.Notifications.ssldisabletip": "SSL should be disabled on standard TLS connections (Port 587)",
"components.Settings.Notifications.test": "Test", "components.Settings.Notifications.test": "Test",
"components.Settings.Notifications.testsent": "Test notification sent!", "components.Settings.Notifications.testsent": "Test notification sent!",
"components.Settings.Notifications.validationFromRequired": "You must provide an email sender address", "components.Settings.Notifications.validationFromRequired": "You must provide an email sender address",
@@ -227,7 +229,7 @@
"components.Settings.jobname": "Job Name", "components.Settings.jobname": "Job Name",
"components.Settings.librariesRemaining": "Libraries Remaining: {count}", "components.Settings.librariesRemaining": "Libraries Remaining: {count}",
"components.Settings.manualscan": "Manual Library Scan", "components.Settings.manualscan": "Manual Library Scan",
"components.Settings.manualscanDescription": "Normally, this will only be run once every 6 hours. Overseerr will check your Plex server's recently added more aggressively. If this is your first time configuring Plex, a one time full manual library scan is recommended!", "components.Settings.manualscanDescription": "Normally, this will only be run once every 24 hours. Overseerr will check your Plex server's recently added more aggressively. If this is your first time configuring Plex, a one time full manual library scan is recommended!",
"components.Settings.menuAbout": "About", "components.Settings.menuAbout": "About",
"components.Settings.menuGeneralSettings": "General Settings", "components.Settings.menuGeneralSettings": "General Settings",
"components.Settings.menuJobs": "Jobs", "components.Settings.menuJobs": "Jobs",
@@ -289,6 +291,7 @@
"components.TvDetails.cast": "Cast", "components.TvDetails.cast": "Cast",
"components.TvDetails.decline": "Decline", "components.TvDetails.decline": "Decline",
"components.TvDetails.declinerequests": "Decline {requestCount} {requestCount, plural, one {Request} other {Requests}}", "components.TvDetails.declinerequests": "Decline {requestCount} {requestCount, plural, one {Request} other {Requests}}",
"components.TvDetails.firstAirDate": "First Air Date",
"components.TvDetails.manageModalClearMedia": "Clear All Media Data", "components.TvDetails.manageModalClearMedia": "Clear All Media Data",
"components.TvDetails.manageModalClearMediaWarning": "This will remove all media data including all requests for this item, irreversibly. If this item exists in your Plex library, the media info will be recreated next sync.", "components.TvDetails.manageModalClearMediaWarning": "This will remove all media data including all requests for this item, irreversibly. If this item exists in your Plex library, the media info will be recreated next sync.",
"components.TvDetails.manageModalNoRequests": "No Requests", "components.TvDetails.manageModalNoRequests": "No Requests",

View File

@@ -338,5 +338,31 @@
"components.Settings.RadarrModal.testFirstRootFolders": "Prueba la conexión para cargar carpetas raíz", "components.Settings.RadarrModal.testFirstRootFolders": "Prueba la conexión para cargar carpetas raíz",
"components.Settings.RadarrModal.testFirstQualityProfiles": "Prueba la conexión para cargar perfiles de calidad", "components.Settings.RadarrModal.testFirstQualityProfiles": "Prueba la conexión para cargar perfiles de calidad",
"components.Settings.RadarrModal.loadingrootfolders": "Cargando carpetas raíz…", "components.Settings.RadarrModal.loadingrootfolders": "Cargando carpetas raíz…",
"components.Settings.RadarrModal.loadingprofiles": "Cargando perfiles de calidad…" "components.Settings.RadarrModal.loadingprofiles": "Cargando perfiles de calidad…",
"i18n.close": "Cerrar",
"components.TvDetails.showtype": "Tipo de Serie",
"components.TvDetails.network": "Red",
"components.TvDetails.anime": "Anime",
"components.Settings.toastSettingsSuccess": "Ajustes guardados.",
"components.Settings.toastSettingsFailure": "Algo salió mal guardando la configuración.",
"components.Settings.toastApiKeySuccess": "¡Nueva clave API generada!",
"components.Settings.toastApiKeyFailure": "Algo salió mal generando una nueva clave API.",
"components.Settings.defaultPermissions": "Permisos de usuario predeterminados",
"components.Settings.SonarrModal.animerootfolder": "Carpeta raíz de anime",
"components.Settings.SonarrModal.animequalityprofile": "Perfil de calidad de anime",
"components.Settings.SettingsAbout.timezone": "Zona horaria",
"components.Settings.SettingsAbout.supportoverseerr": "Apoya a Overseerr",
"components.Settings.SettingsAbout.helppaycoffee": "Págame un café",
"components.Settings.SettingsAbout.Releases.viewongithub": "Ver en GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Ver registro de cambios",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Cambios de la versión",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Los cambios en su versión no estarán disponibles a continuación. Consulte el <GithubLink> repositorio de GitHub </GithubLink> para obtener las últimas actualizaciones.",
"components.Settings.SettingsAbout.Releases.runningDevelop": "¡Está ejecutando una versión de desarrollo de Overseerr!",
"components.Settings.SettingsAbout.Releases.releases": "Versiones",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Faltan datos de la versión. ¿GitHub está caído?",
"components.Settings.SettingsAbout.Releases.latestversion": "Última Versión",
"components.Settings.SettingsAbout.Releases.currentversion": "Versión Actual",
"components.Settings.Notifications.testsent": "¡Notificación de prueba enviada!",
"components.Settings.Notifications.test": "Comprobar",
"components.MovieDetails.studio": "Estudio"
} }

View File

@@ -183,7 +183,7 @@
"components.Settings.jobname": "Nom de la tâche", "components.Settings.jobname": "Nom de la tâche",
"components.Settings.librariesRemaining": "Bibliothèques restantes : {count}", "components.Settings.librariesRemaining": "Bibliothèques restantes : {count}",
"components.Settings.manualscan": "Scan manuel des bibliothèques", "components.Settings.manualscan": "Scan manuel des bibliothèques",
"components.Settings.manualscanDescription": "Normalement, le scan sera effectué une fois toutes les 6 heures seulement. Overseerr va vérifier les ajouts récents de votre serveur Plex de manière plus agressive. Si c'est votre première configuration de Plex, un scan complet unique de la bibliothèque est recommandé !", "components.Settings.manualscanDescription": "Normalement, le scan sera effectué une fois toutes les 24 heures seulement. Overseerr va vérifier les ajouts récents de votre serveur Plex de manière plus agressive. Si c'est votre première configuration de Plex, un scan complet unique de la bibliothèque est recommandé !",
"components.Settings.menuAbout": "À propos", "components.Settings.menuAbout": "À propos",
"components.Settings.menuGeneralSettings": "Paramètres généraux", "components.Settings.menuGeneralSettings": "Paramètres généraux",
"components.Settings.menuJobs": "Tâches", "components.Settings.menuJobs": "Tâches",
@@ -348,5 +348,32 @@
"components.Settings.toastApiKeyFailure": "Une erreur s'est produite lors de la génération de la nouvelle clé API.", "components.Settings.toastApiKeyFailure": "Une erreur s'est produite lors de la génération de la nouvelle clé API.",
"components.Settings.SonarrModal.animerootfolder": "Dossier racine pour anime", "components.Settings.SonarrModal.animerootfolder": "Dossier racine pour anime",
"components.Settings.SonarrModal.animequalityprofile": "Profil qualité pour anime", "components.Settings.SonarrModal.animequalityprofile": "Profil qualité pour anime",
"components.MovieDetails.studio": "Studio" "components.MovieDetails.studio": "Studio",
"components.Settings.SettingsAbout.supportoverseerr": "Soutenez Overseerr",
"i18n.close": "Fermer",
"components.Settings.SettingsAbout.timezone": "Fuseau horaire",
"components.Settings.SettingsAbout.helppaycoffee": "Aidez à payer le café",
"components.Settings.SettingsAbout.Releases.viewongithub": "Voir sur GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Voir le journal des modifications",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Journal des modifications de version",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Les modifications apportées à votre version ne seront pas disponibles ci-dessous. Veuillez consulter le <GithubLink>dépôt GitHub</GithubLink> pour les dernières mises à jour.",
"components.Settings.SettingsAbout.Releases.runningDevelop": "Vous utilisez une version de développement d'Overseerr !",
"components.Settings.SettingsAbout.Releases.releases": "Versions",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Données de sortie manquantes. GitHub est-il en panne ?",
"components.Settings.SettingsAbout.Releases.latestversion": "Dernière version",
"components.Settings.SettingsAbout.Releases.currentversion": "Version actuelle",
"components.Settings.Notifications.testsent": "Notification de test envoyée !",
"components.Settings.Notifications.test": "Test",
"components.Settings.defaultPermissions": "Autorisations utilisateur par défaut",
"components.UserList.importfromplexerror": "Une erreur s'est produite lors de l'importation d'utilisateurs depuis Plex",
"components.UserList.importfromplex": "Importer des utilisateurs depuis Plex",
"components.UserList.importedfromplex": "{userCount, plural, =0 {Aucun nouvel utilisateur} one {# nouvel utilisateur} other {# nouveaux utilisateurs}} importé(s) depuis Plex",
"components.TvDetails.viewfullcrew": "Voir l'équipe complète de la série",
"components.TvDetails.TvCrew.fullseriescrew": "Équipe complète de la série",
"components.PersonDetails.crewmember": "Membre de l'équipe",
"components.MovieDetails.viewfullcrew": "Voir l'équipe complète",
"components.MovieDetails.MovieCrew.fullcrew": "Équipe complète",
"components.TvDetails.firstAirDate": "Date de première diffusion",
"components.Settings.Notifications.ssldisabletip": "Le SSL doit être désactivé sur les connexions TLS standard (Port 587)",
"components.Settings.Notifications.allowselfsigned": "Autoriser les certificats autosignés"
} }

View File

@@ -49,7 +49,7 @@
"components.RequestList.requestedAt": "Richiesto", "components.RequestList.requestedAt": "Richiesto",
"components.RequestList.previous": "Precedente", "components.RequestList.previous": "Precedente",
"components.RequestList.next": "Successivo", "components.RequestList.next": "Successivo",
"components.RequestList.modifiedBy": "Ultima modifica da", "components.RequestList.modifiedBy": "Ultima modifica",
"components.RequestList.mediaInfo": "Media", "components.RequestList.mediaInfo": "Media",
"components.RequestList.RequestItem.seasons": "Stagioni", "components.RequestList.RequestItem.seasons": "Stagioni",
"components.RequestList.RequestItem.requestedby": "Richiesto da {username}", "components.RequestList.RequestItem.requestedby": "Richiesto da {username}",
@@ -92,7 +92,7 @@
"components.MovieDetails.approve": "Approva", "components.MovieDetails.approve": "Approva",
"components.MovieDetails.MovieCast.fullcast": "Cast completo", "components.MovieDetails.MovieCast.fullcast": "Cast completo",
"components.Login.signinplex": "Accedi per continuare", "components.Login.signinplex": "Accedi per continuare",
"components.Layout.alphawarning": "Questo software è in ALPHA. Tutto può smettere di funzionare o diventare instabile. Aiutaci riportando i problemi su Overseerr GitHub!", "components.Layout.alphawarning": "Questo programma è in ALPHA. Tutto può smettere di funzionare o diventare instabile. Aiutaci segnalando i problemi su Overseerr GitHub!",
"components.Layout.UserDropdown.signout": "Esci", "components.Layout.UserDropdown.signout": "Esci",
"components.Layout.Sidebar.users": "Utenti", "components.Layout.Sidebar.users": "Utenti",
"components.Layout.Sidebar.settings": "Impostazioni", "components.Layout.Sidebar.settings": "Impostazioni",
@@ -142,18 +142,18 @@
"i18n.deleting": "Eliminazione…", "i18n.deleting": "Eliminazione…",
"i18n.delete": "Elimina", "i18n.delete": "Elimina",
"pages.oops": "Ops", "pages.oops": "Ops",
"components.Settings.RadarrModal.rootfolder": "Cartella radice", "components.Settings.RadarrModal.rootfolder": "Cartella principale",
"components.Settings.RadarrModal.selectRootFolder": "Seleziona una cartella radice", "components.Settings.RadarrModal.selectRootFolder": "Seleziona una cartella principale",
"components.Settings.RadarrModal.selectQualityProfile": "Seleziona un profilo qualità", "components.Settings.RadarrModal.selectQualityProfile": "Seleziona un profilo qualità",
"components.Settings.RadarrModal.selectMinimumAvailability": "Seleziona la disponibilità minima", "components.Settings.RadarrModal.selectMinimumAvailability": "Seleziona la disponibilità minima",
"components.Settings.RadarrModal.save": "Salva i cambiamenti", "components.Settings.RadarrModal.save": "Salva le modifiche",
"components.Settings.RadarrModal.qualityprofile": "Profilo qualità", "components.Settings.RadarrModal.qualityprofile": "Profilo qualità",
"components.Settings.RadarrModal.minimumAvailability": "Disponibilità minima", "components.Settings.RadarrModal.minimumAvailability": "Disponibilità minima",
"components.Settings.RadarrModal.editradarr": "Modifica server Radarr", "components.Settings.RadarrModal.editradarr": "Modifica server Radarr",
"components.Settings.RadarrModal.defaultserver": "Server predefinito", "components.Settings.RadarrModal.defaultserver": "Server predefinito",
"components.Settings.RadarrModal.apiKey": "Chiave API", "components.Settings.RadarrModal.apiKey": "Chiave API",
"components.Settings.RadarrModal.add": "Aggiungi un server", "components.Settings.RadarrModal.add": "Aggiungi un server",
"components.Settings.Notifications.save": "Salva i cambiamenti", "components.Settings.Notifications.save": "Salva le modifiche",
"components.Settings.Notifications.discordsettingsfailed": "Impossibile salvare le impostazioni di notifica Discord.", "components.Settings.Notifications.discordsettingsfailed": "Impossibile salvare le impostazioni di notifica Discord.",
"components.RequestModal.requesttitle": "Richiedi {title}", "components.RequestModal.requesttitle": "Richiedi {title}",
"components.RequestModal.requestfrom": "Al momento è in sospeso una richiesta da {username}", "components.RequestModal.requestfrom": "Al momento è in sospeso una richiesta da {username}",
@@ -187,7 +187,7 @@
"components.Settings.startscan": "Avvia la scansione", "components.Settings.startscan": "Avvia la scansione",
"components.Settings.ssl": "SSL", "components.Settings.ssl": "SSL",
"components.Settings.saving": "Salvataggio…", "components.Settings.saving": "Salvataggio…",
"components.Settings.save": "Salva i cambiamenti", "components.Settings.save": "Salva le modifiche",
"components.Settings.runnow": "Esegui ora", "components.Settings.runnow": "Esegui ora",
"components.Settings.radarrsettings": "Impostazioni Radarr", "components.Settings.radarrsettings": "Impostazioni Radarr",
"components.Settings.plexsettings": "Impostazioni Plex", "components.Settings.plexsettings": "Impostazioni Plex",
@@ -201,10 +201,10 @@
"components.Settings.menuServices": "Servizi", "components.Settings.menuServices": "Servizi",
"components.Settings.menuPlexSettings": "Plex", "components.Settings.menuPlexSettings": "Plex",
"components.Settings.menuNotifications": "Notifiche", "components.Settings.menuNotifications": "Notifiche",
"components.Settings.menuLogs": "Registri", "components.Settings.menuLogs": "Log",
"components.Settings.menuGeneralSettings": "Impostazioni generali", "components.Settings.menuGeneralSettings": "Impostazioni generali",
"components.Settings.menuAbout": "Informazioni", "components.Settings.menuAbout": "Info",
"components.Settings.manualscan": "Scansione manuale della biblioteca", "components.Settings.manualscan": "Scansione manuale della libreria",
"components.Settings.librariesRemaining": "Biblioteche rimanenti: {count}", "components.Settings.librariesRemaining": "Biblioteche rimanenti: {count}",
"components.Settings.hostname": "Nome host/IP", "components.Settings.hostname": "Nome host/IP",
"components.Settings.generalsettingsDescription": "Queste sono impostazioni relative alla configurazione generale di Overseerr.", "components.Settings.generalsettingsDescription": "Queste sono impostazioni relative alla configurazione generale di Overseerr.",
@@ -214,15 +214,15 @@
"components.Settings.delete": "Elimina", "components.Settings.delete": "Elimina",
"components.Settings.default4k": "4K predefinito", "components.Settings.default4k": "4K predefinito",
"components.Settings.default": "Predefinito", "components.Settings.default": "Predefinito",
"components.Settings.currentlibrary": "Biblioteca corrente: {name}", "components.Settings.currentlibrary": "Libreria corrente: {name}",
"components.Settings.copied": "Chiave API copiata negli appunti", "components.Settings.copied": "Chiave API copiata negli appunti",
"components.Settings.cancelscan": "Annulla l'analisi", "components.Settings.cancelscan": "Annulla l'analisi",
"components.Settings.applicationurl": "URL applicazione", "components.Settings.applicationurl": "URL applicazione",
"components.Settings.apikey": "Chiave API", "components.Settings.apikey": "Chiave API",
"components.Settings.addsonarr": "Aggiungi un server Sonarr", "components.Settings.addsonarr": "Aggiungi un server Sonarr",
"components.Settings.addradarr": "Aggiungi un server radarr", "components.Settings.addradarr": "Aggiungi un server Radarr",
"components.Settings.activeProfile": "Profilo attivo", "components.Settings.activeProfile": "Profilo attivo",
"components.Settings.SonarrModal.validationRootFolderRequired": "È necessario selezionare una cartella radice", "components.Settings.SonarrModal.validationRootFolderRequired": "È necessario selezionare una cartella principale",
"components.Settings.SonarrModal.validationProfileRequired": "È necessario selezionare un profilo", "components.Settings.SonarrModal.validationProfileRequired": "È necessario selezionare un profilo",
"components.Settings.SonarrModal.validationPortRequired": "È necessario fornire una porta", "components.Settings.SonarrModal.validationPortRequired": "È necessario fornire una porta",
"components.Settings.SonarrModal.validationNameRequired": "È necessario fornire un nome di server", "components.Settings.SonarrModal.validationNameRequired": "È necessario fornire un nome di server",
@@ -230,18 +230,18 @@
"components.Settings.SonarrModal.validationApiKeyRequired": "È necessario fornire una chiave API", "components.Settings.SonarrModal.validationApiKeyRequired": "È necessario fornire una chiave API",
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Stabilita la connessione Sonarr!", "components.Settings.SonarrModal.toastRadarrTestSuccess": "Stabilita la connessione Sonarr!",
"components.Settings.SonarrModal.toastRadarrTestFailure": "Impossibile connettersi a Sonarr Server", "components.Settings.SonarrModal.toastRadarrTestFailure": "Impossibile connettersi a Sonarr Server",
"components.Settings.SonarrModal.testFirstRootFolders": "Testa la connessione per caricare le cartelle radice", "components.Settings.SonarrModal.testFirstRootFolders": "Testa la connessione per caricare le cartelle",
"components.Settings.SonarrModal.testFirstQualityProfiles": "Testa la connessione per caricare profili di qualità", "components.Settings.SonarrModal.testFirstQualityProfiles": "Testa la connessione per caricare profili di qualità",
"components.Settings.SonarrModal.servernamePlaceholder": "Un server Sonarr", "components.Settings.SonarrModal.servernamePlaceholder": "Un server Sonarr",
"components.Settings.SonarrModal.servername": "Nome server", "components.Settings.SonarrModal.servername": "Nome server",
"components.Settings.SonarrModal.server4k": "Server 4K", "components.Settings.SonarrModal.server4k": "Server 4K",
"components.Settings.SonarrModal.selectRootFolder": "Seleziona una cartella radice", "components.Settings.SonarrModal.selectRootFolder": "Seleziona una cartella principale",
"components.Settings.SonarrModal.selectQualityProfile": "Seleziona un profilo qualità", "components.Settings.SonarrModal.selectQualityProfile": "Seleziona un profilo qualità",
"components.Settings.SonarrModal.seasonfolders": "Cartelle stagione", "components.Settings.SonarrModal.seasonfolders": "Cartelle stagione",
"components.Settings.SonarrModal.save": "Salva i cambiamenti", "components.Settings.SonarrModal.save": "Salva le modifiche",
"components.Settings.SonarrModal.rootfolder": "Cartella radice", "components.Settings.SonarrModal.rootfolder": "Cartella principale",
"components.Settings.SonarrModal.qualityprofile": "Profilo qualità", "components.Settings.SonarrModal.qualityprofile": "Profilo qualità",
"components.Settings.SonarrModal.loadingrootfolders": "Caricamento delle cartelle radice in…", "components.Settings.SonarrModal.loadingrootfolders": "Caricamento delle cartelle…",
"components.Settings.SonarrModal.loadingprofiles": "Caricamento profili qualità…", "components.Settings.SonarrModal.loadingprofiles": "Caricamento profili qualità…",
"components.Settings.SonarrModal.editsonarr": "Modifica server Sonarr", "components.Settings.SonarrModal.editsonarr": "Modifica server Sonarr",
"components.Settings.SonarrModal.defaultserver": "Server predefinito", "components.Settings.SonarrModal.defaultserver": "Server predefinito",
@@ -250,16 +250,16 @@
"components.Settings.SonarrModal.baseUrl": "URL di base", "components.Settings.SonarrModal.baseUrl": "URL di base",
"components.Settings.SonarrModal.apiKeyPlaceholder": "La tua chiave API Sonarr", "components.Settings.SonarrModal.apiKeyPlaceholder": "La tua chiave API Sonarr",
"components.Settings.SonarrModal.apiKey": "Chiave API", "components.Settings.SonarrModal.apiKey": "Chiave API",
"components.Settings.SonarrModal.animerootfolder": "Cartella radice anime", "components.Settings.SonarrModal.animerootfolder": "Cartella principale Anime",
"components.Settings.SonarrModal.animequalityprofile": "Profilo qualità anime", "components.Settings.SonarrModal.animequalityprofile": "Profilo qualità anime",
"components.Settings.SonarrModal.add": "Aggiungi un server", "components.Settings.SonarrModal.add": "Aggiungi un server",
"components.Settings.SettingsAbout.totalrequests": "Totale richieste", "components.Settings.SettingsAbout.totalrequests": "Totale richieste",
"components.Settings.SettingsAbout.totalmedia": "Media totali", "components.Settings.SettingsAbout.totalmedia": "Media totali",
"components.Settings.SettingsAbout.overseerrinformation": "Informazioni su Overseerr", "components.Settings.SettingsAbout.overseerrinformation": "Info su Overseerr",
"components.Settings.SettingsAbout.githubdiscussions": "Discussioni su GitHub", "components.Settings.SettingsAbout.githubdiscussions": "Discussioni su GitHub",
"components.Settings.SettingsAbout.gettingsupport": "Ottieni aiuto", "components.Settings.SettingsAbout.gettingsupport": "Ottieni aiuto",
"components.Settings.SettingsAbout.clickheretojoindiscord": "Clicca qui per unirti al nostro server Discord.", "components.Settings.SettingsAbout.clickheretojoindiscord": "Clicca qui per unirti al nostro server Discord.",
"components.Settings.RadarrModal.validationRootFolderRequired": "È necessario selezionare una cartella radice", "components.Settings.RadarrModal.validationRootFolderRequired": "È necessario selezionare una cartella principale",
"components.Settings.RadarrModal.validationProfileRequired": "È necessario selezionare un profilo", "components.Settings.RadarrModal.validationProfileRequired": "È necessario selezionare un profilo",
"components.Settings.RadarrModal.validationPortRequired": "È necessario fornire una porta", "components.Settings.RadarrModal.validationPortRequired": "È necessario fornire una porta",
"components.Settings.RadarrModal.validationNameRequired": "È necessario fornire un nome di server", "components.Settings.RadarrModal.validationNameRequired": "È necessario fornire un nome di server",
@@ -268,12 +268,12 @@
"components.Settings.RadarrModal.validationApiKeyRequired": "È necessario fornire una chiave API", "components.Settings.RadarrModal.validationApiKeyRequired": "È necessario fornire una chiave API",
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Stabilita la connessione Radarr!", "components.Settings.RadarrModal.toastRadarrTestSuccess": "Stabilita la connessione Radarr!",
"components.Settings.RadarrModal.toastRadarrTestFailure": "Impossibile connettersi al server Radarr", "components.Settings.RadarrModal.toastRadarrTestFailure": "Impossibile connettersi al server Radarr",
"components.Settings.RadarrModal.testFirstRootFolders": "Testa la connessione per caricare le cartelle radice", "components.Settings.RadarrModal.testFirstRootFolders": "Testa la connessione per caricare le cartelle",
"components.Settings.RadarrModal.testFirstQualityProfiles": "Testa la connessione per caricare profili qualità", "components.Settings.RadarrModal.testFirstQualityProfiles": "Testa la connessione per caricare profili qualità",
"components.Settings.RadarrModal.servernamePlaceholder": "Un server Radarr", "components.Settings.RadarrModal.servernamePlaceholder": "Un server Radarr",
"components.Settings.RadarrModal.servername": "Nome server", "components.Settings.RadarrModal.servername": "Nome server",
"components.Settings.RadarrModal.server4k": "Server 4K", "components.Settings.RadarrModal.server4k": "Server 4K",
"components.Settings.RadarrModal.loadingrootfolders": "Caricamento delle cartelle radice in…", "components.Settings.RadarrModal.loadingrootfolders": "Caricamento delle cartelle…",
"components.Settings.RadarrModal.loadingprofiles": "Caricamento profili di qualità…", "components.Settings.RadarrModal.loadingprofiles": "Caricamento profili di qualità…",
"components.Settings.RadarrModal.createradarr": "Crea un nuovo server Radarr", "components.Settings.RadarrModal.createradarr": "Crea un nuovo server Radarr",
"components.Settings.RadarrModal.baseUrlPlaceholder": "Esempio: /radarr", "components.Settings.RadarrModal.baseUrlPlaceholder": "Esempio: /radarr",
@@ -288,8 +288,8 @@
"components.Settings.Notifications.smtpHost": "Host SMTP", "components.Settings.Notifications.smtpHost": "Host SMTP",
"components.Settings.Notifications.enableSsl": "Abilita SSL", "components.Settings.Notifications.enableSsl": "Abilita SSL",
"components.Settings.Notifications.discordsettingssaved": "Impostazioni di notifica Discord salvate!", "components.Settings.Notifications.discordsettingssaved": "Impostazioni di notifica Discord salvate!",
"components.Settings.Notifications.authUser": "Nome utente", "components.Settings.Notifications.authUser": "Auth User",
"components.Settings.Notifications.authPass": "Password", "components.Settings.Notifications.authPass": "Auth Pass",
"components.RequestModal.requestseasons": "Richiedi {seasonCount} {seasonCount, plural, one {Season} other {Seasons}}", "components.RequestModal.requestseasons": "Richiedi {seasonCount} {seasonCount, plural, one {Season} other {Seasons}}",
"components.RequestList.showingresults": "Visualizzazione dei risultati da <strong>{from}</strong> a <strong>{to}</strong> di <strong>{total}</strong>", "components.RequestList.showingresults": "Visualizzazione dei risultati da <strong>{from}</strong> a <strong>{to}</strong> di <strong>{total}</strong>",
"components.UserEdit.userfail": "Qualcosa è andato storto salvando l'utente.", "components.UserEdit.userfail": "Qualcosa è andato storto salvando l'utente.",
@@ -306,12 +306,12 @@
"components.TvDetails.unavailable": "Non disponibile", "components.TvDetails.unavailable": "Non disponibile",
"components.TvDetails.status": "Stato", "components.TvDetails.status": "Stato",
"components.TvDetails.similarsubtext": "Altre serie simili a {title}", "components.TvDetails.similarsubtext": "Altre serie simili a {title}",
"components.TvDetails.similar": "Serie simile", "components.TvDetails.similar": "Serie simili",
"components.TvDetails.showtype": "Tipo di serie", "components.TvDetails.showtype": "Tipo di serie",
"components.TvDetails.requestmore": "Richiedi di più", "components.TvDetails.requestmore": "Richiedi di più",
"components.TvDetails.request": "Richiesta", "components.TvDetails.request": "Richiesta",
"components.TvDetails.recommendationssubtext": "Se ti è piaciuto {title}, potrebbe anche piacerti…", "components.TvDetails.recommendationssubtext": "Se ti è piaciuto {title}, potrebbe anche piacerti…",
"components.TvDetails.recommendations": "Consigli", "components.TvDetails.recommendations": "Consigliati",
"components.TvDetails.pending": "In sospeso", "components.TvDetails.pending": "In sospeso",
"components.TvDetails.overviewunavailable": "Trama non disponibile", "components.TvDetails.overviewunavailable": "Trama non disponibile",
"components.TvDetails.overview": "Trama", "components.TvDetails.overview": "Trama",
@@ -328,12 +328,12 @@
"components.Setup.signinMessage": "Comincia accedendo con il tuo account Plex", "components.Setup.signinMessage": "Comincia accedendo con il tuo account Plex",
"components.Settings.sync": "Sincronizza le librerie di Plex", "components.Settings.sync": "Sincronizza le librerie di Plex",
"components.Settings.sonarrsettings": "Impostazioni Sonarr", "components.Settings.sonarrsettings": "Impostazioni Sonarr",
"components.Settings.sonarrSettingsDescription": "Imposta la connessione al tuo Sonarr qui sotto. È possibile avere più instanze, ma solo due attive come predefinite nello stesso momento (uno per l'HD standard e uno per 4K). Gli amministratori possono ignorare quale server è utilizzato per le nuove richieste.", "components.Settings.sonarrSettingsDescription": "Configura Sonarr qui sotto. È possibile avere più istanze, ma solo due predefinite contemporaneamente (uno per l'HD standard e uno per 4K). Gli amministratori possono ignorare quale server è utilizzato per le nuove richieste.",
"components.Settings.radarrSettingsDescription": "Imposta la connessione al tuo Radarr qui sotto. È possibile avere più instanze, ma solo due attive come predefinite nello stesso momento (uno per l'HD standard e uno per 4K). Gli amministratori possono ignorare quale server è utilizzato per le nuove richieste.", "components.Settings.radarrSettingsDescription": "Configura Radarr qui sotto. È possibile avere più istanze, ma solo due predefinite contemporaneamente (uno per l'HD standard e uno per 4K). Gli amministratori possono ignorare quale server è utilizzato per le nuove richieste.",
"components.Settings.plexsettingsDescription": "Configura le impostazioni per il tuo server Plex. Overseerr utilizza il tuo server Plex per scansionare la tua libreria a intervealli per vedere quali elementi sono disponibili.", "components.Settings.plexsettingsDescription": "Configura le impostazioni del tuo server Plex. Overseerr scansiona la tua libreria Plex a intervalli regolari alla ricerca di nuovi contenuti.",
"components.Settings.plexlibrariesDescription": "Le librerie che verranno scansionate da Overseerr alla ricerca di titoli. Se non ci sono librerie, configura e salva le impostazioni di connessione a Plex e fai click sul pulsante qui sotto.", "components.Settings.plexlibrariesDescription": "Le librerie che verranno scansionate da Overseerr alla ricerca di titoli. Se non ci sono librerie, configura e salva le impostazioni di connessione a Plex e fai click sul pulsante qui sotto.",
"components.Settings.plexlibraries": "Librerie Plex", "components.Settings.plexlibraries": "Librerie Plex",
"components.Settings.manualscanDescription": "Normalmente, questo verrà eseguito ogni 6 ore. Overseerr controllerà in modo più aggressivo i server Plex aggiunti di recente. Se è la prima volta che configuri Plex, si consiglia una scansione manuale completa della libreria!", "components.Settings.manualscanDescription": "Normalmente, questo verrà eseguito ogni 24 ore. Overseerr controllerà in modo più aggressivo i server Plex aggiunti di recente. Se è la prima volta che configuri Plex, si consiglia una scansione manuale completa della libreria!",
"components.Settings.port": "Porta", "components.Settings.port": "Porta",
"components.Settings.servername": "Nome server (impostato automaticamente dopo il salvataggio)", "components.Settings.servername": "Nome server (impostato automaticamente dopo il salvataggio)",
"components.Settings.servernamePlaceholder": "Nome server Plex", "components.Settings.servernamePlaceholder": "Nome server Plex",
@@ -348,5 +348,31 @@
"pages.somethingWentWrong": "{statusCode} — Qualcosa è andato storto", "pages.somethingWentWrong": "{statusCode} — Qualcosa è andato storto",
"pages.serviceUnavailable": "{statusCode} — Servizio non disponibile", "pages.serviceUnavailable": "{statusCode} — Servizio non disponibile",
"pages.returnHome": "Ritorna alla pagina iniziale", "pages.returnHome": "Ritorna alla pagina iniziale",
"pages.pageNotFound": "404 — Pagina non trovata" "pages.pageNotFound": "404 — Pagina non trovata",
"i18n.close": "Chiudi",
"components.Settings.SettingsAbout.timezone": "Fuso orario",
"components.Settings.SettingsAbout.supportoverseerr": "Sostieni Overseerr",
"components.Settings.SettingsAbout.helppaycoffee": "Offri un caffè",
"components.Settings.SettingsAbout.Releases.viewongithub": "Visualizza su GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Visualizza il changelog",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Changelog versione",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Il changelog di questa versione non è disponibile qui sotto. Puoi andare su<GithubLink>repository GitHub</GithubLink> per gli ultimi aggiornamenti.",
"components.Settings.SettingsAbout.Releases.runningDevelop": "Stai eseguendo una versione in sviluppo di Overseerr!",
"components.Settings.SettingsAbout.Releases.releases": "Versioni",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Dati di versione mancanti. GitHub è down?",
"components.Settings.SettingsAbout.Releases.latestversion": "Ultima versione",
"components.Settings.SettingsAbout.Releases.currentversion": "Versione attuale",
"components.Settings.Notifications.testsent": "Notifica di prova inviata!",
"components.Settings.Notifications.test": "Test",
"components.Settings.defaultPermissions": "Autorizzazioni utente predefinite",
"components.UserList.importfromplexerror": "Qualcosa è andato storto durante l'importazione degli utenti da Plex",
"components.UserList.importfromplex": "Importa utenti da Plex",
"components.UserList.importedfromplex": "{userCount, plural, =0 {Nessun utente importato} one {# nuovo utente importato} other {# nuovi utenti importati}} da Plex",
"components.TvDetails.viewfullcrew": "Vedi troupe completa",
"components.TvDetails.TvCrew.fullseriescrew": "Troupe completa serie",
"components.PersonDetails.crewmember": "Membro della troupe",
"components.MovieDetails.MovieCrew.fullcrew": "Troupe completa",
"components.MovieDetails.viewfullcrew": "Vedi troupe completa",
"components.Settings.Notifications.ssldisabletip": "SSL dovrebbe essere disabilitato sulle connessioni standard TLS (Porta 587)",
"components.Settings.Notifications.allowselfsigned": "Consenti i certificati autofirmati"
} }

View File

@@ -348,5 +348,22 @@
"components.Settings.RadarrModal.testFirstQualityProfiles": "画質プロファイルをロードするには先に接続をテストしてください", "components.Settings.RadarrModal.testFirstQualityProfiles": "画質プロファイルをロードするには先に接続をテストしてください",
"components.Settings.RadarrModal.loadingprofiles": "画質プロファイルの読込中…", "components.Settings.RadarrModal.loadingprofiles": "画質プロファイルの読込中…",
"components.Settings.RadarrModal.loadingrootfolders": "ルートフォルダー読込中…", "components.Settings.RadarrModal.loadingrootfolders": "ルートフォルダー読込中…",
"components.MovieDetails.studio": "スタジオ" "components.MovieDetails.studio": "スタジオ",
"components.Settings.Notifications.test": "テスト",
"i18n.close": "閉じる",
"components.Settings.defaultPermissions": "デフォルトのユーザー権限",
"components.Settings.SettingsAbout.timezone": "タイムゾーン",
"components.Settings.SettingsAbout.supportoverseerr": "Overseerrを応援",
"components.Settings.SettingsAbout.helppaycoffee": "開発者のコーヒーのためにチップを",
"components.Settings.SettingsAbout.Releases.viewongithub": "GitHubで見る",
"components.Settings.SettingsAbout.Releases.viewchangelog": "変更履歴参照",
"components.Settings.SettingsAbout.Releases.versionChangelog": "バージョン変更履歴",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "お使いのバージョンのパッチノート以下に記載されていません。最新のアップデートは<GithubLink>GitHubリポジトリ</GithubLink>をご覧ください。",
"components.Settings.SettingsAbout.Releases.runningDevelop": "Overseerrの開発バージョンを実行しています。",
"components.Settings.SettingsAbout.Releases.releases": "リリース",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "リリースデータがありません。GitHubはダウンしていますか",
"components.Settings.SettingsAbout.Releases.latestversion": "最新バージョン",
"components.Settings.SettingsAbout.Releases.currentversion": "現在のバージョン",
"components.Settings.Notifications.testsent": "テスト通知が送信されました。",
"components.MovieDetails.MovieCrew.fullcrew": "フルクルー"
} }

View File

@@ -333,5 +333,11 @@
"components.Settings.RadarrModal.testFirstRootFolders": "Test je connectie om hoofdfolders te laden", "components.Settings.RadarrModal.testFirstRootFolders": "Test je connectie om hoofdfolders te laden",
"components.Settings.RadarrModal.testFirstQualityProfiles": "Test je connectie om kwaliteitsprofielen te laden", "components.Settings.RadarrModal.testFirstQualityProfiles": "Test je connectie om kwaliteitsprofielen te laden",
"components.Settings.RadarrModal.loadingrootfolders": "Bezig met laden van hoofdfolders…", "components.Settings.RadarrModal.loadingrootfolders": "Bezig met laden van hoofdfolders…",
"components.Settings.RadarrModal.loadingprofiles": "Bezig met laden van kwaliteitsprofielen…" "components.Settings.RadarrModal.loadingprofiles": "Bezig met laden van kwaliteitsprofielen…",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Publicatiedatum mist. Is GitHub offline?",
"components.Settings.SettingsAbout.Releases.latestversion": "Laatste versie",
"components.Settings.SettingsAbout.Releases.currentversion": "Huidige versie",
"components.Settings.Notifications.testsent": "Test notificatie verzonden!",
"components.Settings.Notifications.test": "Test",
"components.MovieDetails.studio": "Studio"
} }

View File

@@ -8,8 +8,8 @@
"components.RequestCard.requestedby": "Solicitado por {username}", "components.RequestCard.requestedby": "Solicitado por {username}",
"components.RequestBlock.seasons": "Temporadas", "components.RequestBlock.seasons": "Temporadas",
"components.PlexLoginButton.loginwithplex": "Entrar com", "components.PlexLoginButton.loginwithplex": "Entrar com",
"components.PlexLoginButton.loggingin": "Fazendo login...", "components.PlexLoginButton.loggingin": "Fazendo login",
"components.PlexLoginButton.loading": "Carregando...", "components.PlexLoginButton.loading": "Carregando",
"components.PersonDetails.nobiography": "Biografia não disponível.", "components.PersonDetails.nobiography": "Biografia não disponível.",
"components.PersonDetails.ascharacter": "como {character}", "components.PersonDetails.ascharacter": "como {character}",
"components.PersonDetails.appearsin": "Aparece em", "components.PersonDetails.appearsin": "Aparece em",
@@ -24,11 +24,11 @@
"components.MovieDetails.revenue": "Receita", "components.MovieDetails.revenue": "Receita",
"components.MovieDetails.request": "Solicitar", "components.MovieDetails.request": "Solicitar",
"components.MovieDetails.releasedate": "Data de Lançamento", "components.MovieDetails.releasedate": "Data de Lançamento",
"components.MovieDetails.recommendationssubtext": "Se você gostou {title}, você provavelmente irá gostar...", "components.MovieDetails.recommendationssubtext": "Se você gostou {title}, você provavelmente irá gostar",
"components.MovieDetails.recommendations": "Recomendações", "components.MovieDetails.recommendations": "Recomendações",
"components.MovieDetails.pending": "Pendente", "components.MovieDetails.pending": "Pendente",
"components.MovieDetails.overviewunavailable": "Visão Geral Indisponível", "components.MovieDetails.overviewunavailable": "Sinopse indisponível",
"components.MovieDetails.overview": "Visão Geral", "components.MovieDetails.overview": "Sinopse",
"components.MovieDetails.originallanguage": "Língua original", "components.MovieDetails.originallanguage": "Língua original",
"components.MovieDetails.manageModalTitle": "Gerenciar Filme", "components.MovieDetails.manageModalTitle": "Gerenciar Filme",
"components.MovieDetails.manageModalRequests": "Solicitações", "components.MovieDetails.manageModalRequests": "Solicitações",
@@ -61,12 +61,12 @@
"components.Discover.nopending": "Nenhuma Solicitação Pendente", "components.Discover.nopending": "Nenhuma Solicitação Pendente",
"components.Discover.discovertv": "Séries Populares", "components.Discover.discovertv": "Séries Populares",
"components.Discover.discovermovies": "Filmes Populares", "components.Discover.discovermovies": "Filmes Populares",
"components.Settings.SonarrModal.testing": "Testando...", "components.Settings.SonarrModal.testing": "Testando",
"components.Settings.SonarrModal.saving": "Salvando...", "components.Settings.SonarrModal.saving": "Salvando",
"components.Settings.RadarrModal.testing": "Testando...", "components.Settings.RadarrModal.testing": "Testando",
"components.Settings.RadarrModal.saving": "Salvando...", "components.Settings.RadarrModal.saving": "Salvando",
"components.Settings.Notifications.saving": "Salvando...", "components.Settings.Notifications.saving": "Salvando",
"components.RequestModal.cancelling": "Cancelando...", "components.RequestModal.cancelling": "Cancelando",
"components.Settings.plexlibraries": "Bibliotecas do Plex", "components.Settings.plexlibraries": "Bibliotecas do Plex",
"components.Settings.notrunning": "Parado", "components.Settings.notrunning": "Parado",
"components.Settings.notificationsettingsDescription": "Aqui você pode escolher e selecionar os tipos de notificações e através de quais serviços deseja enviar.", "components.Settings.notificationsettingsDescription": "Aqui você pode escolher e selecionar os tipos de notificações e através de quais serviços deseja enviar.",
@@ -84,7 +84,7 @@
"components.Settings.menuJobs": "Tarefas", "components.Settings.menuJobs": "Tarefas",
"components.Settings.menuGeneralSettings": "Configurações Gerais", "components.Settings.menuGeneralSettings": "Configurações Gerais",
"components.Settings.menuAbout": "Sobre", "components.Settings.menuAbout": "Sobre",
"components.Settings.manualscanDescription": "Normalmente, isso só será executado uma vez a cada 6 horas. Overseerr irá checar em detalhes items recentemente adicionados ao seu servidor Plex. Se essa é a primeira vez que você configura um servidor Plex, é recomendado a varredura completa de sua biblioteca!", "components.Settings.manualscanDescription": "Normalmente, isso só será executado uma vez a cada 24 horas. Overseerr irá checar em detalhes items recentemente adicionados ao seu servidor Plex. Se essa é a primeira vez que você configura um servidor Plex, é recomendado a varredura completa de sua biblioteca!",
"components.Settings.manualscan": "Varredura Manual da Biblioteca", "components.Settings.manualscan": "Varredura Manual da Biblioteca",
"components.Settings.librariesRemaining": "Bibliotecas Restantes: {count}", "components.Settings.librariesRemaining": "Bibliotecas Restantes: {count}",
"components.Settings.jobname": "Nome da Tarefa", "components.Settings.jobname": "Nome da Tarefa",
@@ -228,5 +228,149 @@
"components.RequestList.previous": "Anterior", "components.RequestList.previous": "Anterior",
"components.RequestList.RequestItem.seasons": "Temporadas", "components.RequestList.RequestItem.seasons": "Temporadas",
"components.RequestList.RequestItem.notavailable": "N/A", "components.RequestList.RequestItem.notavailable": "N/A",
"components.RequestCard.all": "Todas" "components.RequestCard.all": "Todas",
"components.Setup.continue": "Continuar",
"components.Setup.configureservices": "Configurar Serviços",
"components.Setup.configureplex": "Configurar Plex",
"components.Settings.validationPortRequired": "Você deve prover uma porta",
"components.Settings.validationHostnameRequired": "Você deve prover o Nome do Servidor/IP",
"components.Settings.toastSettingsSuccess": "Configurações salvas.",
"components.Settings.toastSettingsFailure": "Algo de errado ao salvar configurações.",
"components.Settings.toastApiKeySuccess": "Nova chave de API gerada!",
"components.Settings.toastApiKeyFailure": "Algo deu errado ao gerar a nova chave de API.",
"components.Settings.syncing": "Sincronizando…",
"components.Settings.sync": "Sincronizar Bibliotecas do Plex",
"components.Settings.startscan": "Iniciar Varredura",
"components.Settings.ssl": "SSL",
"components.Settings.sonarrsettings": "Configurações do Sonarr",
"components.Settings.servernamePlaceholder": "Nome do Servidor Plex",
"components.Settings.servername": "Nome do Servidor (Automaticamente definido após você salvar)",
"components.Settings.saving": "Salvando…",
"components.Settings.save": "Salvar Mudanças",
"components.Settings.runnow": "Executar Agora",
"components.Settings.radarrsettings": "Configurações do Radarr",
"components.Settings.port": "Porta",
"components.Settings.plexsettingsDescription": "Configure os dados de conexão com servidor Plex. Overseerr irá escanear sua biblioteca em intervalos e checar por novo conteúdo.",
"components.Settings.plexsettings": "Configurações do Plex",
"components.Settings.plexlibrariesDescription": "Bibliotecas que Overseerr irá buscar por títulos. Configure e salve as informações de conexão com Plex e click no botão abaixo se nenhuma biblioteca é listada.",
"components.Settings.SettingsAbout.timezone": "Fuso Horário",
"components.Settings.SettingsAbout.helppaycoffee": "Ajude a Pagar o Café",
"components.Settings.SettingsAbout.supportoverseerr": "Apoie Overseerr",
"components.Settings.SettingsAbout.Releases.viewongithub": "Ver no GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Ver Mudanças",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Mudanças Nessa Versão",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "As mudanças em sua versão não serão exibidas abaixo. Por favor acesso o <GithubLink> repositório do GitHub</GithubLink> para saber o que mudou.",
"components.Settings.SettingsAbout.Releases.runningDevelop": "Você está usando uma versão de desenvolvimento do Overseerr!",
"components.Settings.SettingsAbout.Releases.releases": "Versões",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Informações de versão faltando. O GitHub está indisponível?",
"components.Settings.SettingsAbout.Releases.latestversion": "Última Versão",
"components.Settings.SettingsAbout.Releases.currentversion": "Versão Atual",
"components.TvDetails.request": "Solicitar",
"components.TvDetails.recommendationssubtext": "Se você gostou {title}, você provavelmente irá gostar…",
"components.TvDetails.recommendations": "Recomendações",
"components.TvDetails.pending": "Pendente",
"components.TvDetails.overviewunavailable": "Sinopse indisponível",
"components.TvDetails.overview": "Sinopse",
"components.TvDetails.originallanguage": "Língua original",
"components.TvDetails.network": "Estúdio",
"components.TvDetails.manageModalTitle": "Gerenciar Séries",
"components.TvDetails.manageModalRequests": "Solicitações",
"components.TvDetails.manageModalNoRequests": "Nenhuma Solicitação",
"components.TvDetails.manageModalClearMedia": "Limpar Todos Dados de Mídia",
"components.TvDetails.declinerequests": "Rejeitar {requestCount} {requestCount, plural, one {Solicitação} other {Solicitações}}",
"components.TvDetails.decline": "Rejeitar",
"components.TvDetails.cast": "Elenco",
"components.TvDetails.cancelrequest": "Cancelar Solicitação",
"components.TvDetails.available": "Disponível",
"components.TvDetails.approverequests": "Aprovar {requestCount} {requestCount, plural, one {Solicitação} other {Solicitações}}",
"components.TvDetails.approve": "Aprovar",
"components.TvDetails.anime": "Animes",
"components.TvDetails.TvCast.fullseriescast": "Elenco Completo da Série",
"components.TitleCard.tvshow": "Séries",
"components.TitleCard.movie": "Filme",
"components.Slider.noresults": "Nenhum Resultado",
"components.Setup.welcome": "Bem-Vindo ao Overseerr",
"components.Setup.tip": "Dica",
"components.Setup.syncingbackground": "A sincronização será executada em segundo plano. Você pode continuar a configuração enquanto isso.",
"components.Setup.signinMessage": "Comece fazendo login com sua conta Plex",
"components.Setup.loginwithplex": "Entrar com Plex",
"components.Setup.finishing": "Finalizando…",
"components.Setup.finish": "Finalizar Configurações",
"components.TvDetails.requestmore": "Solicitar Mais",
"pages.somethingWentWrong": "{statusCode} - Algo deu errado",
"pages.serviceUnavailable": "{statusCode} - Serviço Indisponível",
"pages.returnHome": "Voltar Para Página Inicial",
"pages.oops": "Opa",
"pages.internalServerError": "{statusCode} - Erro Interno no Servidor",
"i18n.unavailable": "Indisponível",
"i18n.tvshows": "Séries",
"i18n.processing": "Processando…",
"i18n.pending": "Pendente",
"i18n.partiallyavailable": "Parcialmente Disponível",
"i18n.movies": "Filmes",
"i18n.declined": "Rejeitado",
"i18n.decline": "Rejeitar",
"i18n.close": "Fechar",
"i18n.cancel": "Cancelar",
"i18n.available": "Disponível",
"i18n.approved": "Aprovada",
"i18n.approve": "Aprovar",
"components.UserList.usertype": "Tipo de Usuário",
"components.UserList.username": "Usuário",
"components.UserList.userlist": "Lista de Usuários",
"components.UserList.userdeleteerror": "Algo deu errado ao apagar usuário",
"components.UserList.userdeleted": "Usuário deletado",
"components.UserList.user": "Usuário",
"components.UserList.totalrequests": "Total de Solicitações",
"components.UserList.role": "Privilégio",
"components.UserList.plexuser": "Usuário Plex",
"components.UserList.lastupdated": "Última Atualização",
"components.UserList.edit": "Editar",
"components.UserList.deleteuser": "Deletar Usuário",
"components.UserList.deleteconfirm": "Tem certeza que deseja deletar esse usuário? Todas informações de solicitação desse usuário serão removidas.",
"components.UserList.created": "Criado",
"components.UserList.admin": "Administrador",
"components.UserEdit.voteDescription": "Concede permissão para votar em solicitações (sistema de votos ainda não implementado)",
"components.UserEdit.vote": "Votar",
"components.UserEdit.usersaved": "Usuário salvo",
"components.UserEdit.usersDescription": "Concede permissão para gerenciar usuários do Overseerr. Usuários com essa permissão não conseguem modificar usuários de Adminitradores ou conceder esse privilégio .",
"components.UserEdit.users": "Gerenciar Usuários",
"components.UserEdit.username": "Usuário",
"components.UserEdit.userfail": "Algo deu errado ao salvar edições do usuário.",
"components.UserEdit.settingsDescription": "Concede permissão para modificar todas configurações do Overseerr. Um usuário precisa dessa permissão para concedê-la para outros usuários.",
"components.UserEdit.settings": "Gerenciar Configurações",
"components.UserEdit.saving": "Salvando…",
"components.UserEdit.save": "Salvar",
"components.UserEdit.requestDescription": "Concede permissão para solicitar filmes e séries.",
"components.UserEdit.request": "Solicitação",
"components.UserEdit.permissions": "Permissões",
"components.UserEdit.managerequestsDescription": "Concede permissão para gerenciar solicitações no Overseerr. Isso inclui aprová-las e negá-las.",
"components.UserEdit.managerequests": "Gerenciar Solicitações",
"components.UserEdit.email": "E-mail",
"components.UserEdit.edituser": "Editar Usuário",
"components.UserEdit.avatar": "Avatar",
"components.UserEdit.autoapproveDescription": "Concede aprovação automática para todas as solicitações feitas por este usuário.",
"components.UserEdit.autoapprove": "Aprovação Automática",
"components.UserEdit.adminDescription": "Acesso total de administrador. Ignora todas as verificações de permissão.",
"components.UserEdit.admin": "Administrador",
"components.TvDetails.userrating": "Avaliação do usuário",
"components.TvDetails.unavailable": "Indisponível",
"components.TvDetails.similarsubtext": "Outras séries similares a {title}",
"components.TvDetails.similar": "Séries Similares",
"components.TvDetails.showtype": "Categoria",
"components.TvDetails.manageModalClearMediaWarning": "Isso irá remover em definitivo todos dados de mídia, incluindo todas solicitações para esse item. Se este item existir in sua biblioteca do Plex, os dados de mídia serão recriados na próxima sincronia.",
"components.Settings.sonarrSettingsDescription": "Configure sua conexão com Sonarr abaixo. Você pode criar várias, mas apenas duas por vez como padrão (uma para padrão HD, e outra para 4K). Administradores podem alterar qual conexão será usada para novas solicitações.",
"components.Settings.radarrSettingsDescription": "Configure sua conexão com Radarr abaixo. Você pode criar várias, mas apenas duas por vez como padrão (uma para padrão HD, e outra para 4K). Administradores podem alterar qual conexão será usada para novas solicitações.",
"components.Settings.Notifications.testsent": "Notificação de teste enviada!",
"components.Settings.Notifications.test": "Testar",
"components.RequestModal.requestseasons": "Solicitar {seasonCount} {seasonCount, plural, one {Temporada} other {Temporadas}}",
"components.TvDetails.viewfullcrew": "Ver Toda Equipe Técnica",
"components.TvDetails.TvCrew.fullseriescrew": "Equipe Técnica Completa da Série",
"components.PersonDetails.crewmember": "Membro da Equipe Técnica",
"components.MovieDetails.viewfullcrew": "Ver Equipe Técnica Completa",
"components.MovieDetails.MovieCrew.fullcrew": "Equipe Técnica Completa",
"components.UserList.importfromplexerror": "Algo deu errado ao importar usuários do Plex",
"components.UserList.importfromplex": "Importar Usuários do Plex",
"components.UserList.importedfromplex": "{userCount, plural, =0 {Nenhum novo usuário} one {# novo usuário} other {# novos usuários}} importado(s) do Plex",
"components.Settings.defaultPermissions": "Permissões Padrões de Usúarios"
} }

View File

@@ -42,7 +42,7 @@
"components.Settings.menuJobs": "Jobb", "components.Settings.menuJobs": "Jobb",
"components.Settings.menuGeneralSettings": "Generella Inställningar", "components.Settings.menuGeneralSettings": "Generella Inställningar",
"components.Settings.menuAbout": "Om", "components.Settings.menuAbout": "Om",
"components.Settings.manualscanDescription": "Normalt körs denna var sjätte timme. Overseerr kommer kontrollera till Plex Servers \"senast tillagda\" oftare. Om detta är första gången du konfigurerar din Plex Server är det starkt rekommenderat att göra en manuell full scan av ditt mediabibliotek!", "components.Settings.manualscanDescription": "Normalt körs denna var tjugofjärde timme. Overseerr kommer kontrollera till Plex Servers \"senast tillagda\" oftare. Om detta är första gången du konfigurerar din Plex Server är det starkt rekommenderat att göra en manuell full scan av ditt mediabibliotek!",
"components.Settings.manualscan": "Manuell Biblioteksscan", "components.Settings.manualscan": "Manuell Biblioteksscan",
"components.Settings.librariesRemaining": "Kvarvarande Bibliotek: {count}", "components.Settings.librariesRemaining": "Kvarvarande Bibliotek: {count}",
"components.Settings.jobname": "Jobbnamn", "components.Settings.jobname": "Jobbnamn",
@@ -51,7 +51,7 @@
"components.Settings.generalsettings": "Generella Inställningar", "components.Settings.generalsettings": "Generella Inställningar",
"components.Settings.edit": "Ändra", "components.Settings.edit": "Ändra",
"components.Settings.deleteserverconfirm": "Är du säker på att du vill radera servern?", "components.Settings.deleteserverconfirm": "Är du säker på att du vill radera servern?",
"components.Settings.delete": "Radera", "components.Settings.delete": "Ta bort",
"components.Settings.default4k": "Standard 4K", "components.Settings.default4k": "Standard 4K",
"components.Settings.default": "Standard", "components.Settings.default": "Standard",
"components.Settings.currentlibrary": "Nuvarande Bibliotek: {name}", "components.Settings.currentlibrary": "Nuvarande Bibliotek: {name}",
@@ -162,7 +162,7 @@
"components.Settings.Notifications.discordsettingssaved": "Notiferingsinställningar för Discord sparade!", "components.Settings.Notifications.discordsettingssaved": "Notiferingsinställningar för Discord sparade!",
"components.Settings.Notifications.authUser": "Användarnamn", "components.Settings.Notifications.authUser": "Användarnamn",
"components.Settings.Notifications.authPass": "Lösenord", "components.Settings.Notifications.authPass": "Lösenord",
"components.Settings.Notifications.agentenabled": "Agent Aktiverad", "components.Settings.Notifications.agentenabled": "Aktiverad",
"components.Search.searchresults": "Sökresultat", "components.Search.searchresults": "Sökresultat",
"components.RequestModal.status": "Status", "components.RequestModal.status": "Status",
"components.RequestModal.selectseason": "Välj säsong(er)", "components.RequestModal.selectseason": "Välj säsong(er)",
@@ -185,7 +185,7 @@
"components.RequestModal.cancel": "Avbryt förfrågan", "components.RequestModal.cancel": "Avbryt förfrågan",
"components.RequestList.status": "Status", "components.RequestList.status": "Status",
"components.RequestList.showingresults": "Visar <strong>{from}</strong> till <strong>{to}</strong> av <strong>{total}</strong> sökresultat", "components.RequestList.showingresults": "Visar <strong>{from}</strong> till <strong>{to}</strong> av <strong>{total}</strong> sökresultat",
"components.RequestList.requests": "Förfrågan", "components.RequestList.requests": "Förfrågningar",
"components.RequestList.requestedAt": "Begärd", "components.RequestList.requestedAt": "Begärd",
"components.RequestList.previous": "Föregående", "components.RequestList.previous": "Föregående",
"components.RequestList.next": "Nästa", "components.RequestList.next": "Nästa",
@@ -255,7 +255,7 @@
"components.TvDetails.approve": "Godkänn", "components.TvDetails.approve": "Godkänn",
"components.TvDetails.anime": "Anime", "components.TvDetails.anime": "Anime",
"components.TvDetails.TvCast.fullseriescast": "Rollista", "components.TvDetails.TvCast.fullseriescast": "Rollista",
"components.TitleCard.tvshow": "TV-serier", "components.TitleCard.tvshow": "TV-serie",
"components.TitleCard.movie": "Film", "components.TitleCard.movie": "Film",
"components.Slider.noresults": "Inga resultat", "components.Slider.noresults": "Inga resultat",
"components.Setup.welcome": "Välkommen till Overseerr", "components.Setup.welcome": "Välkommen till Overseerr",
@@ -276,8 +276,8 @@
"i18n.pending": "Väntande", "i18n.pending": "Väntande",
"i18n.partiallyavailable": "Delvis Tillgänglig", "i18n.partiallyavailable": "Delvis Tillgänglig",
"i18n.movies": "Filmer", "i18n.movies": "Filmer",
"i18n.deleting": "Raderar…", "i18n.deleting": "Tar bort…",
"i18n.delete": "Radera", "i18n.delete": "Ta bort",
"i18n.declined": "Avböjd", "i18n.declined": "Avböjd",
"i18n.decline": "Avböj", "i18n.decline": "Avböj",
"i18n.cancel": "Avbryt", "i18n.cancel": "Avbryt",
@@ -292,12 +292,12 @@
"components.UserList.user": "Användare", "components.UserList.user": "Användare",
"components.UserList.totalrequests": "Totalt antal förfrågningar", "components.UserList.totalrequests": "Totalt antal förfrågningar",
"components.UserList.role": "Roll", "components.UserList.role": "Roll",
"components.UserList.plexuser": "Plexanvändare", "components.UserList.plexuser": "Plex",
"components.UserList.lastupdated": "Senast uppdaterad", "components.UserList.lastupdated": "Senast uppdaterad",
"components.UserList.edit": "Redigera", "components.UserList.edit": "Redigera",
"components.UserList.deleteuser": "Ta bort användare", "components.UserList.deleteuser": "Ta bort användare",
"components.UserList.deleteconfirm": "Är du säker på att du vill ta bort användaren? All data för användaren kommer att raderas.", "components.UserList.deleteconfirm": "Är du säker på att du vill ta bort användaren? All data för användaren kommer att raderas.",
"components.UserList.delete": "Radera", "components.UserList.delete": "Ta bort",
"components.UserList.created": "Skapad", "components.UserList.created": "Skapad",
"components.UserList.admin": "Administratör", "components.UserList.admin": "Administratör",
"components.UserEdit.voteDescription": "Ger behörighet att rösta på förfrågningar (röstning är inte implementerat ännu)", "components.UserEdit.voteDescription": "Ger behörighet att rösta på förfrågningar (röstning är inte implementerat ännu)",
@@ -346,5 +346,23 @@
"components.TvDetails.decline": "Avböj", "components.TvDetails.decline": "Avböj",
"components.TvDetails.cast": "Roller", "components.TvDetails.cast": "Roller",
"components.TvDetails.cancelrequest": "Avbryt begäran", "components.TvDetails.cancelrequest": "Avbryt begäran",
"components.TvDetails.available": "Tillgänglig" "components.TvDetails.available": "Tillgänglig",
"i18n.close": "Stäng",
"components.TvDetails.approverequests": "Godkänn {requestCount} {requestCount, plural, one {Request} other {Requests}}",
"components.Setup.loginwithplex": "Logga in med Plex",
"components.Settings.SettingsAbout.timezone": "Tidzon",
"components.Settings.SettingsAbout.supportoverseerr": "Hjälp Overseerr",
"components.Settings.SettingsAbout.helppaycoffee": "Stötta med en kopp kaffe",
"components.Settings.SettingsAbout.Releases.viewongithub": "Visa på GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Visa ändringslogg",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Ändringslogg",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Ändringarna nedan är inte tillgängliga i din version. Vänligen se <GithubLink>GitHub repository</GithubLink> för dom senaste uppdateringarna.",
"components.Settings.SettingsAbout.Releases.runningDevelop": "Du kör en utvecklingsversion av Overseerr!",
"components.Settings.SettingsAbout.Releases.releases": "Versioner",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Versionsdata saknas. Ligger GitHub nere?",
"components.Settings.SettingsAbout.Releases.latestversion": "Senaste Version",
"components.Settings.SettingsAbout.Releases.currentversion": "Aktuell Version",
"components.Settings.Notifications.testsent": "Test-notifikation skickad!",
"components.Settings.Notifications.test": "Testa",
"components.UserList.importfromplex": "Importera användare från Plex"
} }

View File

@@ -62,7 +62,7 @@ module.exports = {
borderWidth: ['first', 'last'], borderWidth: ['first', 'last'],
margin: ['first', 'last', 'responsive'], margin: ['first', 'last', 'responsive'],
boxShadow: ['group-focus'], boxShadow: ['group-focus'],
opacity: ['disabled', 'hover'], opacity: ['disabled', 'hover', 'group-hover'],
}, },
plugins: [ plugins: [
require('@tailwindcss/forms'), require('@tailwindcss/forms'),

View File

@@ -4162,6 +4162,11 @@ compose-function@3.0.3:
dependencies: dependencies:
arity-n "^1.0.4" arity-n "^1.0.4"
computed-style@~0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/computed-style/-/computed-style-0.1.4.tgz#7f344fd8584b2e425bedca4a1afc0e300bb05d74"
integrity sha1-fzRP2FhLLkJb7cpKGvwOMAuwXXQ=
concat-map@0.0.1: concat-map@0.0.1:
version "0.0.1" version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -8155,6 +8160,13 @@ line-column@^1.0.2:
isarray "^1.0.0" isarray "^1.0.0"
isobject "^2.0.0" isobject "^2.0.0"
line-height@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/line-height/-/line-height-0.3.1.tgz#4b1205edde182872a5efa3c8f620b3187a9c54c9"
integrity sha1-SxIF7d4YKHKl76PI9iCzGHqcVMk=
dependencies:
computed-style "~0.1.3"
lines-and-columns@^1.1.6: lines-and-columns@^1.1.6:
version "1.1.6" version "1.1.6"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
@@ -8713,6 +8725,11 @@ mem@^1.1.0:
dependencies: dependencies:
mimic-fn "^1.0.0" mimic-fn "^1.0.0"
memoize-one@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==
memory-fs@^0.4.1: memory-fs@^0.4.1:
version "0.4.1" version "0.4.1"
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
@@ -11019,7 +11036,7 @@ promzard@^0.3.0:
dependencies: dependencies:
read "1" read "1"
prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.2, prop-types@^15.7.2: prop-types@15.7.2, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2" version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@@ -11448,6 +11465,16 @@ react-transition-group@^4.3.0, react-transition-group@^4.4.1:
loose-envify "^1.4.0" loose-envify "^1.4.0"
prop-types "^15.6.2" prop-types "^15.6.2"
react-truncate-markup@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/react-truncate-markup/-/react-truncate-markup-5.0.1.tgz#5c52bda712f7e185e84969b2b79440ec8b422441"
integrity sha512-WG1E9FLyTrq5ERaDbIq0DjWVs3JrAdr93fasdQqbVlEifBUp27kGM7ws4xCBIh2keDjumTPjw3iiHNNmD+YtcQ==
dependencies:
line-height "0.3.1"
memoize-one "^5.1.1"
prop-types "^15.6.0"
resize-observer-polyfill "1.5.x"
react-use-clipboard@1.0.2: react-use-clipboard@1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/react-use-clipboard/-/react-use-clipboard-1.0.2.tgz#e00254ffc70b989daa41638325fa6557c7b89dd2" resolved "https://registry.yarnpkg.com/react-use-clipboard/-/react-use-clipboard-1.0.2.tgz#e00254ffc70b989daa41638325fa6557c7b89dd2"
@@ -11852,6 +11879,11 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
resize-observer-polyfill@1.5.x:
version "1.5.1"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
resolve-dir@^1.0.0, resolve-dir@^1.0.1: resolve-dir@^1.0.0, resolve-dir@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"