Merge branch 'develop'

pull/570/head
sct 4 years ago
commit 191f39e8bd

@ -153,6 +153,24 @@
"contributions": [ "contributions": [
"code" "code"
] ]
},
{
"login": "mazzetta86",
"name": "mazzetta86",
"avatar_url": "https://avatars2.githubusercontent.com/u/45591560?v=4",
"profile": "https://github.com/mazzetta86",
"contributions": [
"translation"
]
},
{
"login": "Panzer1119",
"name": "Paul Hagedorn",
"avatar_url": "https://avatars1.githubusercontent.com/u/23016343?v=4",
"profile": "https://github.com/Panzer1119",
"contributions": [
"translation"
]
} }
], ],
"badgeTemplate": "<a href=\"#contributors-\"><img alt=\"All Contributors\" src=\"https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg\"/></a>", "badgeTemplate": "<a href=\"#contributors-\"><img alt=\"All Contributors\" src=\"https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg\"/></a>",

@ -0,0 +1,2 @@
github: [sct]
patreon: overseerr

@ -52,6 +52,8 @@ jobs:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
push: true push: true
build-args: |
COMMIT_TAG=${{ github.sha }}
tags: | tags: |
sctx/overseerr:develop sctx/overseerr:develop
sctx/overseerr:${{ github.sha }} sctx/overseerr:${{ github.sha }}

@ -15,6 +15,8 @@ FROM node:12.18-alpine
ARG COMMIT_TAG ARG COMMIT_TAG
ENV COMMIT_TAG=${COMMIT_TAG} ENV COMMIT_TAG=${COMMIT_TAG}
RUN apk add tzdata
COPY . /app COPY . /app
WORKDIR /app WORKDIR /app

@ -16,7 +16,7 @@
<a href="https://lgtm.com/projects/g/sct/overseerr/context:javascript"><img alt="Language grade: JavaScript" src="https://img.shields.io/lgtm/grade/javascript/g/sct/overseerr.svg?logo=lgtm&logoWidth=18"/></a> <a href="https://lgtm.com/projects/g/sct/overseerr/context:javascript"><img alt="Language grade: JavaScript" src="https://img.shields.io/lgtm/grade/javascript/g/sct/overseerr.svg?logo=lgtm&logoWidth=18"/></a>
<img alt="GitHub" src="https://img.shields.io/github/license/sct/overseerr"> <img alt="GitHub" src="https://img.shields.io/github/license/sct/overseerr">
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a href="#contributors-"><img alt="All Contributors" src="https://img.shields.io/badge/all_contributors-16-orange.svg"/></a> <a href="#contributors-"><img alt="All Contributors" src="https://img.shields.io/badge/all_contributors-18-orange.svg"/></a>
<!-- ALL-CONTRIBUTORS-BADGE:END --> <!-- ALL-CONTRIBUTORS-BADGE:END -->
</p> </p>
@ -119,10 +119,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tr> <tr>
<td align="center"><a href="https://github.com/ecelebi29"><img src="https://avatars2.githubusercontent.com/u/8337120?v=4" width="100px;" alt=""/><br /><sub><b>ecelebi29</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=ecelebi29" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=ecelebi29" title="Documentation">📖</a></td> <td align="center"><a href="https://github.com/ecelebi29"><img src="https://avatars2.githubusercontent.com/u/8337120?v=4" width="100px;" alt=""/><br /><sub><b>ecelebi29</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=ecelebi29" title="Code">💻</a> <a href="https://github.com/sct/overseerr/commits?author=ecelebi29" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/mmozeiko"><img src="https://avatars3.githubusercontent.com/u/1665010?v=4" width="100px;" alt=""/><br /><sub><b>Mārtiņš Možeiko</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=mmozeiko" title="Code">💻</a></td> <td align="center"><a href="https://github.com/mmozeiko"><img src="https://avatars3.githubusercontent.com/u/1665010?v=4" width="100px;" alt=""/><br /><sub><b>Mārtiņš Možeiko</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=mmozeiko" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/mazzetta86"><img src="https://avatars2.githubusercontent.com/u/45591560?v=4" width="100px;" alt=""/><br /><sub><b>mazzetta86</b></sub></a><br /><a href="#translation-mazzetta86" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/Panzer1119"><img src="https://avatars1.githubusercontent.com/u/23016343?v=4" width="100px;" alt=""/><br /><sub><b>Paul Hagedorn</b></sub></a><br /><a href="#translation-Panzer1119" title="Translation">🌍</a></td>
</tr> </tr>
</table> </table>
<!-- markdownlint-enable --> <!-- markdownlint-enable -->
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END --> <!-- ALL-CONTRIBUTORS-LIST:END -->

@ -1542,6 +1542,10 @@ paths:
totalMediaItems: totalMediaItems:
type: number type: number
example: 100 example: 100
tz:
type: string
nullable: true
example: Asia/Tokyo
/auth/me: /auth/me:
get: get:
summary: Returns the currently logged in user summary: Returns the currently logged in user

@ -172,7 +172,12 @@
} }
], ],
"semantic-release-docker", "semantic-release-docker",
"@semantic-release/github" [
"@semantic-release/github",
{
"addReleases": "top"
}
]
], ],
"branches": [ "branches": [
"master" "master"
@ -182,7 +187,8 @@
{ {
"path": "semantic-release-docker", "path": "semantic-release-docker",
"name": "sctx/overseerr" "name": "sctx/overseerr"
} },
"@semantic-release/github"
] ]
} }
} }

@ -116,7 +116,7 @@ class RottenTomatoes {
public async getTVRatings( public async getTVRatings(
name: string, name: string,
year: number year?: number
): Promise<RTRating | null> { ): Promise<RTRating | null> {
try { try {
const response = await this.axios.get<RTMultiSearchResponse>( const response = await this.axios.get<RTMultiSearchResponse>(
@ -126,9 +126,13 @@ class RottenTomatoes {
} }
); );
const tvshow = response.data.tvSeries.find( let tvshow: RTTvSearchResult | undefined = response.data.tvSeries[0];
(series) => series.startYear === year
); if (year) {
tvshow = response.data.tvSeries.find(
(series) => series.startYear === year
);
}
if (!tvshow) { if (!tvshow) {
return null; return null;

@ -2,4 +2,5 @@ export interface SettingsAboutResponse {
version: string; version: string;
totalRequests: number; totalRequests: number;
totalMediaItems: number; totalMediaItems: number;
tz?: string;
} }

@ -20,6 +20,7 @@ import { merge } from 'lodash';
import Media from '../entity/Media'; import Media from '../entity/Media';
import { MediaRequest } from '../entity/MediaRequest'; import { MediaRequest } from '../entity/MediaRequest';
import { getAppVersion } from '../utils/appVersion'; import { getAppVersion } from '../utils/appVersion';
import { SettingsAboutResponse } from '../interfaces/api/settingsInterfaces';
const settingsRoutes = Router(); const settingsRoutes = Router();
@ -473,7 +474,8 @@ settingsRoutes.get('/about', async (req, res) => {
version: getAppVersion(), version: getAppVersion(),
totalMediaItems, totalMediaItems,
totalRequests, totalRequests,
}); tz: process.env.TZ,
} as SettingsAboutResponse);
}); });
export default settingsRoutes; export default settingsRoutes;

@ -106,7 +106,7 @@ tvRoutes.get('/:id/ratings', async (req, res, next) => {
const rtratings = await rtapi.getTVRatings( const rtratings = await rtapi.getTVRatings(
tv.name, tv.name,
Number(tv.first_air_date.slice(0, 4)) tv.first_air_date ? Number(tv.first_air_date.slice(0, 4)) : undefined
); );
if (!rtratings) { if (!rtratings) {

@ -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='https://example.com' style='\ a(href=actionUrl 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;\

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid meet" viewBox="0 0 575 289.83"><defs><path d="M575 24.91C573.44 12.15 563.97 1.98 551.91 0C499.05 0 76.18 0 23.32 0C10.11 2.17 0 14.16 0 28.61C0 51.84 0 237.64 0 260.86C0 276.86 12.37 289.83 27.64 289.83C79.63 289.83 495.6 289.83 547.59 289.83C561.65 289.83 573.26 278.82 575 264.57C575 216.64 575 48.87 575 24.91Z" id="d1pwhf9wy2"></path><path d="M69.35 58.24L114.98 58.24L114.98 233.89L69.35 233.89L69.35 58.24Z" id="g5jjnq26yS"></path><path d="M201.2 139.15C197.28 112.38 195.1 97.5 194.67 94.53C192.76 80.2 190.94 67.73 189.2 57.09C185.25 57.09 165.54 57.09 130.04 57.09L130.04 232.74L170.01 232.74L170.15 116.76L186.97 232.74L215.44 232.74L231.39 114.18L231.54 232.74L271.38 232.74L271.38 57.09L211.77 57.09L201.2 139.15Z" id="i3Prh1JpXt"></path><path d="M346.71 93.63C347.21 95.87 347.47 100.95 347.47 108.89C347.47 115.7 347.47 170.18 347.47 176.99C347.47 188.68 346.71 195.84 345.2 198.48C343.68 201.12 339.64 202.43 333.09 202.43C333.09 190.9 333.09 98.66 333.09 87.13C338.06 87.13 341.45 87.66 343.25 88.7C345.05 89.75 346.21 91.39 346.71 93.63ZM367.32 230.95C372.75 229.76 377.31 227.66 381.01 224.67C384.7 221.67 387.29 217.52 388.77 212.21C390.26 206.91 391.14 196.38 391.14 180.63C391.14 174.47 391.14 125.12 391.14 118.95C391.14 102.33 390.49 91.19 389.48 85.53C388.46 79.86 385.93 74.71 381.88 70.09C377.82 65.47 371.9 62.15 364.12 60.13C356.33 58.11 343.63 57.09 321.54 57.09C319.27 57.09 307.93 57.09 287.5 57.09L287.5 232.74L342.78 232.74C355.52 232.34 363.7 231.75 367.32 230.95Z" id="a4ov9rRGQm"></path><path d="M464.76 204.7C463.92 206.93 460.24 208.06 457.46 208.06C454.74 208.06 452.93 206.98 452.01 204.81C451.09 202.65 450.64 197.72 450.64 190C450.64 185.36 450.64 148.22 450.64 143.58C450.64 135.58 451.04 130.59 451.85 128.6C452.65 126.63 454.41 125.63 457.13 125.63C459.91 125.63 463.64 126.76 464.6 129.03C465.55 131.3 466.03 136.15 466.03 143.58C466.03 146.58 466.03 161.58 466.03 188.59C465.74 197.84 465.32 203.21 464.76 204.7ZM406.68 231.21L447.76 231.21C449.47 224.5 450.41 220.77 450.6 220.02C454.32 224.52 458.41 227.9 462.9 230.14C467.37 232.39 474.06 233.51 479.24 233.51C486.45 233.51 492.67 231.62 497.92 227.83C503.16 224.05 506.5 219.57 507.92 214.42C509.34 209.26 510.05 201.42 510.05 190.88C510.05 185.95 510.05 146.53 510.05 141.6C510.05 131 509.81 124.08 509.34 120.83C508.87 117.58 507.47 114.27 505.14 110.88C502.81 107.49 499.42 104.86 494.98 102.98C490.54 101.1 485.3 100.16 479.26 100.16C474.01 100.16 467.29 101.21 462.81 103.28C458.34 105.35 454.28 108.49 450.64 112.7C450.64 108.89 450.64 89.85 450.64 55.56L406.68 55.56L406.68 231.21Z" id="fk968BpsX"></path></defs><g><g><g><use xlink:href="#d1pwhf9wy2" opacity="1" fill="#f6c700" fill-opacity="1"></use><g><use xlink:href="#d1pwhf9wy2" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#g5jjnq26yS" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#g5jjnq26yS" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#i3Prh1JpXt" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#i3Prh1JpXt" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#a4ov9rRGQm" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#a4ov9rRGQm" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g><g><use xlink:href="#fk968BpsX" opacity="1" fill="#000000" fill-opacity="1"></use><g><use xlink:href="#fk968BpsX" opacity="1" fill-opacity="0" stroke="#000000" stroke-width="1" stroke-opacity="0"></use></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.4 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 185.04 133.4"><defs><style>.cls-1{fill:url(#linear-gradient);}</style><linearGradient id="linear-gradient" y1="66.7" x2="185.04" y2="66.7" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#90cea1"/><stop offset="0.56" stop-color="#3cbec9"/><stop offset="1" stop-color="#00b3e5"/></linearGradient></defs><title>Asset 4</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M51.06,66.7h0A17.67,17.67,0,0,1,68.73,49h-.1A17.67,17.67,0,0,1,86.3,66.7h0A17.67,17.67,0,0,1,68.63,84.37h.1A17.67,17.67,0,0,1,51.06,66.7Zm82.67-31.33h32.9A17.67,17.67,0,0,0,184.3,17.7h0A17.67,17.67,0,0,0,166.63,0h-32.9A17.67,17.67,0,0,0,116.06,17.7h0A17.67,17.67,0,0,0,133.73,35.37Zm-113,98h63.9A17.67,17.67,0,0,0,102.3,115.7h0A17.67,17.67,0,0,0,84.63,98H20.73A17.67,17.67,0,0,0,3.06,115.7h0A17.67,17.67,0,0,0,20.73,133.37Zm83.92-49h6.25L125.5,49h-8.35l-8.9,23.2h-.1L99.4,49H90.5Zm32.45,0h7.8V49h-7.8Zm22.2,0h24.95V77.2H167.1V70h15.35V62.8H167.1V56.2h16.25V49h-24ZM10.1,35.4h7.8V6.9H28V0H0V6.9H10.1ZM39,35.4h7.8V20.1H61.9V35.4h7.8V0H61.9V13.2H46.75V0H39Zm41.25,0h25V28.2H88V21h15.35V13.8H88V7.2h16.25V0h-24Zm-79,49H9V57.25h.1l9,27.15H24l9.3-27.15h.1V84.4h7.8V49H29.45l-8.2,23.1h-.1L13,49H1.2Zm112.09,49H126a24.59,24.59,0,0,0,7.56-1.15,19.52,19.52,0,0,0,6.35-3.37,16.37,16.37,0,0,0,4.37-5.5A16.91,16.91,0,0,0,146,115.8a18.5,18.5,0,0,0-1.68-8.25,15.1,15.1,0,0,0-4.52-5.53A18.55,18.55,0,0,0,133.07,99,33.54,33.54,0,0,0,125,98H113.29Zm7.81-28.2h4.6a17.43,17.43,0,0,1,4.67.62,11.68,11.68,0,0,1,3.88,1.88,9,9,0,0,1,2.62,3.18,9.87,9.87,0,0,1,1,4.52,11.92,11.92,0,0,1-1,5.08,8.69,8.69,0,0,1-2.67,3.34,10.87,10.87,0,0,1-4,1.83,21.57,21.57,0,0,1-5,.55H121.1Zm36.14,28.2h14.5a23.11,23.11,0,0,0,4.73-.5,13.38,13.38,0,0,0,4.27-1.65,9.42,9.42,0,0,0,3.1-3,8.52,8.52,0,0,0,1.2-4.68,9.16,9.16,0,0,0-.55-3.2,7.79,7.79,0,0,0-1.57-2.62,8.38,8.38,0,0,0-2.45-1.85,10,10,0,0,0-3.18-1v-.1a9.28,9.28,0,0,0,4.43-2.82,7.42,7.42,0,0,0,1.67-5,8.34,8.34,0,0,0-1.15-4.65,7.88,7.88,0,0,0-3-2.73,12.9,12.9,0,0,0-4.17-1.3,34.42,34.42,0,0,0-4.63-.32h-13.2Zm7.8-28.8h5.3a10.79,10.79,0,0,1,1.85.17,5.77,5.77,0,0,1,1.7.58,3.33,3.33,0,0,1,1.23,1.13,3.22,3.22,0,0,1,.47,1.82,3.63,3.63,0,0,1-.42,1.8,3.34,3.34,0,0,1-1.13,1.2,4.78,4.78,0,0,1-1.57.65,8.16,8.16,0,0,1-1.78.2H165Zm0,14.15h5.9a15.12,15.12,0,0,1,2.05.15,7.83,7.83,0,0,1,2,.55,4,4,0,0,1,1.58,1.17,3.13,3.13,0,0,1,.62,2,3.71,3.71,0,0,1-.47,1.95,4,4,0,0,1-1.23,1.3,4.78,4.78,0,0,1-1.67.7,8.91,8.91,0,0,1-1.83.2h-7Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -0,0 +1,55 @@
import React from 'react';
import TmdbLogo from '../../assets/services/tmdb.svg';
import ImdbLogo from '../../assets/services/imdb.svg';
import RTLogo from '../../assets/services/rt.svg';
interface ExternalLinkBlockProps {
mediaType: 'movie' | 'tv';
imdbId?: string;
tmdbId?: number;
rtUrl?: string;
}
const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
imdbId,
tmdbId,
rtUrl,
mediaType,
}) => {
return (
<div className="flex justify-end items-center">
{tmdbId && (
<a
href={`https://www.themoviedb.org/${mediaType}/${tmdbId}`}
className="w-8 mx-2 opacity-50 hover:opacity-100 transition duration-300"
target="_blank"
rel="noreferrer"
>
<TmdbLogo />
</a>
)}
{imdbId && (
<a
href={`https://www.imdb.com/title/${imdbId}`}
className="w-8 mx-2 opacity-50 hover:opacity-100 transition duration-300"
target="_blank"
rel="noreferrer"
>
<ImdbLogo />
</a>
)}
{rtUrl && (
<a
href={`${rtUrl}`}
className="w-14 mx-2 opacity-50 hover:opacity-100 transition duration-300"
target="_blank"
rel="noreferrer"
>
<RTLogo />
</a>
)}
</div>
);
};
export default ExternalLinkBlock;

@ -58,7 +58,7 @@ const LanguagePicker: React.FC = () => {
useClickOutside(dropdownRef, () => setDropdownOpen(false)); useClickOutside(dropdownRef, () => setDropdownOpen(false));
return ( return (
<div className="ml-3 relative"> <div className="relative">
<div> <div>
<button <button
className="p-1 text-gray-400 rounded-full hover:bg-gray-500 hover:text-white focus:outline-none focus:ring focus:text-white" className="p-1 text-gray-400 rounded-full hover:bg-gray-500 hover:text-white focus:outline-none focus:ring focus:text-white"

@ -27,7 +27,7 @@ const SearchInput: React.FC = () => {
</div> </div>
<input <input
id="search_field" id="search_field"
className="block w-full h-full pl-8 pr-3 py-2 rounded-md border-transparent focus:border-transparent bg-gray-600 text-white placeholder-gray-300 focus:outline-none focus:ring-0 focus:placeholder-gray-400 sm:text-base" className="block w-full h-full pl-8 pr-1 py-2 rounded-md border-transparent focus:border-transparent bg-gray-600 text-white placeholder-gray-300 focus:outline-none focus:ring-0 focus:placeholder-gray-400 sm:text-base"
placeholder={intl.formatMessage(messages.searchPlaceholder)} placeholder={intl.formatMessage(messages.searchPlaceholder)}
type="search" type="search"
value={searchValue} value={searchValue}

@ -44,7 +44,7 @@ const Layout: React.FC = ({ children }) => {
</button> </button>
<div className="flex-1 px-4 flex justify-between"> <div className="flex-1 px-4 flex justify-between">
<SearchInput /> <SearchInput />
<div className="ml-4 flex items-center md:ml-6"> <div className="flex items-center md:ml-6">
<LanguagePicker /> <LanguagePicker />
<UserDropdown /> <UserDropdown />
</div> </div>

@ -37,6 +37,7 @@ import type { RTRating } from '../../../server/api/rottentomatoes';
import Error from '../../pages/_error'; import Error from '../../pages/_error';
import Head from 'next/head'; import Head from 'next/head';
import globalMessages from '../../i18n/globalMessages'; import globalMessages from '../../i18n/globalMessages';
import ExternalLinkBlock from '../ExternalLinkBlock';
const messages = defineMessages({ const messages = defineMessages({
releasedate: 'Release Date', releasedate: 'Release Date',
@ -396,34 +397,36 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
<div className="bg-gray-900 rounded-lg shadow border border-gray-800"> <div className="bg-gray-900 rounded-lg shadow border border-gray-800">
{(data.voteCount > 0 || ratingData) && ( {(data.voteCount > 0 || ratingData) && (
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0 items-center justify-center"> <div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0 items-center justify-center">
{ratingData?.criticsRating && ( {ratingData?.criticsRating &&
<> (ratingData?.criticsScore ?? 0) > 0 && (
<span className="text-sm"> <>
{ratingData.criticsRating === 'Rotten' ? ( <span className="text-sm">
<RTRotten className="w-6 mr-1" /> {ratingData.criticsRating === 'Rotten' ? (
) : ( <RTRotten className="w-6 mr-1" />
<RTFresh className="w-6 mr-1" /> ) : (
)} <RTFresh className="w-6 mr-1" />
</span> )}
<span className="text-gray-400 text-sm mr-4 last:mr-0"> </span>
{ratingData.criticsScore}% <span className="text-gray-400 text-sm mr-4 last:mr-0">
</span> {ratingData.criticsScore}%
</> </span>
)} </>
{ratingData?.audienceRating && ( )}
<> {ratingData?.audienceRating &&
<span className="text-sm"> (ratingData?.audienceScore ?? 0) > 0 && (
{ratingData.audienceRating === 'Spilled' ? ( <>
<RTAudRotten className="w-6 mr-1" /> <span className="text-sm">
) : ( {ratingData.audienceRating === 'Spilled' ? (
<RTAudFresh className="w-6 mr-1" /> <RTAudRotten className="w-6 mr-1" />
)} ) : (
</span> <RTAudFresh className="w-6 mr-1" />
<span className="text-gray-400 text-sm mr-4 last:mr-0"> )}
{ratingData.audienceScore}% </span>
</span> <span className="text-gray-400 text-sm mr-4 last:mr-0">
</> {ratingData.audienceScore}%
)} </span>
</>
)}
{data.voteCount > 0 && ( {data.voteCount > 0 && (
<> <>
<span className="text-sm"> <span className="text-sm">
@ -512,6 +515,14 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
</div> </div>
)} )}
</div> </div>
<div className="mt-4">
<ExternalLinkBlock
mediaType="movie"
tmdbId={data.id}
imdbId={data.externalIds.imdbId}
rtUrl={ratingData?.url}
/>
</div>
</div> </div>
</div> </div>
<div className="md:flex md:items-center md:justify-between mb-4 mt-6"> <div className="md:flex md:items-center md:justify-between mb-4 mt-6">

@ -43,26 +43,30 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
return ( return (
<div className="block"> <div className="block">
<div className="px-4 py-4 sm:px-6 "> <div className="px-4 py-4 sm:px-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="mr-6 flex items-center text-sm leading-5 text-gray-300"> <div className="mr-6 flex-col items-center text-sm leading-5 text-gray-300 flex-1 min-w-0">
<svg <div className="flex flex-nowrap mb-1 white">
className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-300" <svg
fill="currentColor" className="min-w-0 flex-shrink-0 mr-1.5 h-5 w-5 text-gray-300"
viewBox="0 0 20 20" fill="currentColor"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"
> xmlns="http://www.w3.org/2000/svg"
<path >
fillRule="evenodd" <path
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" fillRule="evenodd"
clipRule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
/> clipRule="evenodd"
</svg> />
<span>{request.requestedBy.username}</span> </svg>
<span className="truncate w-40 md:w-auto">
{request.requestedBy.username}
</span>
</div>
{request.modifiedBy && ( {request.modifiedBy && (
<> <div className="flex flex-nowrap">
<svg <svg
className="flex-shrink-0 ml-2 mr-1.5 h-5 w-5 text-gray-300" className="flex-shrink-0 mr-1.5 h-5 w-5 text-gray-300"
fill="currentColor" fill="currentColor"
viewBox="0 0 20 20" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -74,8 +78,10 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
clipRule="evenodd" clipRule="evenodd"
/> />
</svg> </svg>
<span>{request.modifiedBy?.username}</span> <span className="truncate w-40 md:w-auto">
</> {request.modifiedBy?.username}
</span>
</div>
)} )}
</div> </div>
<div className="ml-2 flex-shrink-0 flex"> <div className="ml-2 flex-shrink-0 flex">
@ -189,13 +195,18 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
</div> </div>
</div> </div>
{(request.seasons ?? []).length > 0 && ( {(request.seasons ?? []).length > 0 && (
<div className="mt-2 text-sm flex items-center"> <div className="mt-2 text-sm flex flex-col">
<span className="mr-2">{intl.formatMessage(messages.seasons)}</span> <div className="mb-2">{intl.formatMessage(messages.seasons)}</div>
{request.seasons.map((season) => ( <div>
<span key={`season-${season.id}`} className="mr-2"> {request.seasons.map((season) => (
<Badge>{season.seasonNumber}</Badge> <span
</span> key={`season-${season.id}`}
))} className="mr-2 mb-1 inline-block"
>
<Badge>{season.seasonNumber}</Badge>
</span>
))}
</div>
</div> </div>
)} )}
</div> </div>

@ -14,6 +14,7 @@ const messages = defineMessages({
gettingsupport: 'Getting Support', gettingsupport: 'Getting Support',
githubdiscussions: 'GitHub Discussions', githubdiscussions: 'GitHub Discussions',
clickheretojoindiscord: 'Click here to join our Discord server.', clickheretojoindiscord: 'Click here to join our Discord server.',
timezone: 'Timezone',
}); });
const SettingsAbout: React.FC = () => { const SettingsAbout: React.FC = () => {
@ -47,6 +48,11 @@ const SettingsAbout: React.FC = () => {
<List.Item title={intl.formatMessage(messages.totalrequests)}> <List.Item title={intl.formatMessage(messages.totalrequests)}>
<FormattedNumber value={data.totalRequests} /> <FormattedNumber value={data.totalRequests} />
</List.Item> </List.Item>
{data.tz && (
<List.Item title={intl.formatMessage(messages.timezone)}>
{data.tz}
</List.Item>
)}
</List> </List>
</div> </div>
<div className="mb-8"> <div className="mb-8">

@ -29,6 +29,7 @@ import type { RTRating } from '../../../server/api/rottentomatoes';
import Head from 'next/head'; import Head from 'next/head';
import globalMessages from '../../i18n/globalMessages'; import globalMessages from '../../i18n/globalMessages';
import { ANIME_KEYWORD_ID } from '../../../server/api/themoviedb'; import { ANIME_KEYWORD_ID } from '../../../server/api/themoviedb';
import ExternalLinkBlock from '../ExternalLinkBlock';
const messages = defineMessages({ const messages = defineMessages({
userrating: 'User Rating', userrating: 'User Rating',
@ -137,6 +138,14 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
} }
}; };
const isComplete =
data.seasons.filter((season) => season.seasonNumber !== 0).length <=
(
data.mediaInfo?.seasons.filter(
(season) => season.status === MediaStatus.AVAILABLE
) ?? []
).length;
return ( return (
<div <div
className="bg-cover bg-center -mx-4 -mt-2 px-4 sm:px-8 pt-4 " className="bg-cover bg-center -mx-4 -mt-2 px-4 sm:px-8 pt-4 "
@ -266,89 +275,91 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
<FormattedMessage {...messages.request} /> <FormattedMessage {...messages.request} />
</Button> </Button>
)} )}
{data.mediaInfo && data.mediaInfo.status !== MediaStatus.UNKNOWN && ( {data.mediaInfo &&
<ButtonWithDropdown data.mediaInfo.status !== MediaStatus.UNKNOWN &&
dropdownIcon={ !isComplete && (
<svg <ButtonWithDropdown
className="w-5 h-5" dropdownIcon={
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z"
clipRule="evenodd"
/>
</svg>
}
text={
<>
<svg <svg
className="w-4 mr-1" className="w-5 h-5"
fill="currentColor" fill="currentColor"
viewBox="0 0 20 20" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
<path <path
fillRule="evenodd" fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z"
clipRule="evenodd" clipRule="evenodd"
/> />
</svg> </svg>
<FormattedMessage {...messages.requestmore} /> }
</> text={
}
onClick={() => setShowRequestModal(true)}
>
{hasPermission(Permission.MANAGE_REQUESTS) &&
activeRequests &&
activeRequests.length > 0 && (
<> <>
<ButtonWithDropdown.Item <svg
onClick={() => modifyRequests('approve')} className="w-4 mr-1"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
> >
<svg <path
className="w-4 mr-1" fillRule="evenodd"
fill="currentColor" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
viewBox="0 0 20 20" clipRule="evenodd"
xmlns="http://www.w3.org/2000/svg" />
</svg>
<FormattedMessage {...messages.requestmore} />
</>
}
onClick={() => setShowRequestModal(true)}
>
{hasPermission(Permission.MANAGE_REQUESTS) &&
activeRequests &&
activeRequests.length > 0 && (
<>
<ButtonWithDropdown.Item
onClick={() => modifyRequests('approve')}
> >
<path <svg
fillRule="evenodd" className="w-4 mr-1"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" fill="currentColor"
clipRule="evenodd" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
<FormattedMessage
{...messages.approverequests}
values={{ requestCount: activeRequests.length }}
/> />
</svg> </ButtonWithDropdown.Item>
<FormattedMessage <ButtonWithDropdown.Item
{...messages.approverequests} onClick={() => modifyRequests('decline')}
values={{ requestCount: activeRequests.length }}
/>
</ButtonWithDropdown.Item>
<ButtonWithDropdown.Item
onClick={() => modifyRequests('decline')}
>
<svg
className="w-4 mr-1"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
> >
<path <svg
fillRule="evenodd" className="w-4 mr-1"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" fill="currentColor"
clipRule="evenodd" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clipRule="evenodd"
/>
</svg>
<FormattedMessage
{...messages.declinerequests}
values={{ requestCount: activeRequests.length }}
/> />
</svg> </ButtonWithDropdown.Item>
<FormattedMessage </>
{...messages.declinerequests} )}
values={{ requestCount: activeRequests.length }} </ButtonWithDropdown>
/> )}
</ButtonWithDropdown.Item>
</>
)}
</ButtonWithDropdown>
)}
{hasPermission(Permission.MANAGE_REQUESTS) && ( {hasPermission(Permission.MANAGE_REQUESTS) && (
<Button <Button
buttonType="default" buttonType="default"
@ -395,34 +406,36 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
<div className="bg-gray-900 rounded-lg shadow border border-gray-800"> <div className="bg-gray-900 rounded-lg shadow border border-gray-800">
{(data.voteCount > 0 || ratingData) && ( {(data.voteCount > 0 || ratingData) && (
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0 items-center justify-center"> <div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0 items-center justify-center">
{ratingData?.criticsRating && ( {ratingData?.criticsRating &&
<> (ratingData?.criticsScore ?? 0) > 0 && (
<span className="text-sm"> <>
{ratingData.criticsRating === 'Rotten' ? ( <span className="text-sm">
<RTRotten className="w-6 mr-1" /> {ratingData.criticsRating === 'Rotten' ? (
) : ( <RTRotten className="w-6 mr-1" />
<RTFresh className="w-6 mr-1" /> ) : (
)} <RTFresh className="w-6 mr-1" />
</span> )}
<span className="text-gray-400 text-sm mr-4 last:mr-0"> </span>
{ratingData.criticsScore}% <span className="text-gray-400 text-sm mr-4 last:mr-0">
</span> {ratingData.criticsScore}%
</> </span>
)} </>
{ratingData?.audienceRating && ( )}
<> {ratingData?.audienceRating &&
<span className="text-sm"> (ratingData?.audienceScore ?? 0) > 0 && (
{ratingData.audienceRating === 'Spilled' ? ( <>
<RTAudRotten className="w-6 mr-1" /> <span className="text-sm">
) : ( {ratingData.audienceRating === 'Spilled' ? (
<RTAudFresh className="w-6 mr-1" /> <RTAudRotten className="w-6 mr-1" />
)} ) : (
</span> <RTAudFresh className="w-6 mr-1" />
<span className="text-gray-400 text-sm mr-4 last:mr-0"> )}
{ratingData.audienceScore}% </span>
</span> <span className="text-gray-400 text-sm mr-4 last:mr-0">
</> {ratingData.audienceScore}%
)} </span>
</>
)}
{data.voteCount > 0 && ( {data.voteCount > 0 && (
<> <>
<span className="text-sm"> <span className="text-sm">
@ -482,6 +495,14 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
</div> </div>
)} )}
</div> </div>
<div className="mt-4">
<ExternalLinkBlock
mediaType="tv"
tmdbId={data.id}
imdbId={data.externalIds.imdbId}
rtUrl={ratingData?.url}
/>
</div>
</div> </div>
</div> </div>
<div className="md:flex md:items-center md:justify-between mb-4 mt-6"> <div className="md:flex md:items-center md:justify-between mb-4 mt-6">

@ -1,42 +1,42 @@
{ {
"components.Discover.discovermovies": "Beliebte Filme", "components.Discover.discovermovies": "Beliebte Filme",
"components.Discover.discovertv": "Beliebte Serien", "components.Discover.discovertv": "Beliebte Serien",
"components.Discover.nopending": "Keine ausstehenden Anträge", "components.Discover.nopending": "Keine ausstehenden Anfragen",
"components.Discover.popularmovies": "Beliebte Filme", "components.Discover.popularmovies": "Beliebte Filme",
"components.Discover.populartv": "Beliebte Serien", "components.Discover.populartv": "Beliebte Serien",
"components.Discover.recentlyAdded": "Kürzlich hinzugefügt", "components.Discover.recentlyAdded": "Kürzlich hinzugefügt",
"components.Discover.recentrequests": "Letzte Anträge", "components.Discover.recentrequests": "Aktuelle Anfragen",
"components.Discover.trending": "Trends", "components.Discover.trending": "Trends",
"components.Discover.upcoming": "Bald erscheinende Filme", "components.Discover.upcoming": "Bald erscheinende Filme",
"components.Discover.upcomingmovies": "Bald erscheinende Filme", "components.Discover.upcomingmovies": "Bald erscheinende Filme",
"components.Layout.LanguagePicker.changelanguage": "Sprache ändern", "components.Layout.LanguagePicker.changelanguage": "Sprache ändern",
"components.Layout.SearchInput.searchPlaceholder": "Nach Filme und Fernsehsendungen suchen", "components.Layout.SearchInput.searchPlaceholder": "Nach Filmen und Serien suchen",
"components.Layout.Sidebar.dashboard": "Entdecken", "components.Layout.Sidebar.dashboard": "Entdecken",
"components.Layout.Sidebar.requests": "Anträge", "components.Layout.Sidebar.requests": "Anträge",
"components.Layout.Sidebar.settings": "Einstellungen", "components.Layout.Sidebar.settings": "Einstellungen",
"components.Layout.Sidebar.users": "Benutzer", "components.Layout.Sidebar.users": "Benutzer",
"components.Layout.UserDropdown.signout": "Abmelden", "components.Layout.UserDropdown.signout": "Abmelden",
"components.Layout.alphawarning": "Dies ist ALPHA-Software. Fast alles muss fast kaputt und/oder instabil sein. Bitte melden Sie Probleme auf der GitHub-Seite!", "components.Layout.alphawarning": "Dies ist ALPHA-Software. Fast alles kann kaputt und/oder instabil sein. Bitte melde Probleme auf der GitHub-Seite!",
"components.Login.signinplex": "Melden Sie sich an, um fortzufahren", "components.Login.signinplex": "Melden Sie sich an, um fortzufahren",
"components.MovieDetails.approve": "Genehmigen", "components.MovieDetails.approve": "Genehmigen",
"components.MovieDetails.available": "Verfügbar", "components.MovieDetails.available": "Verfügbar",
"components.MovieDetails.budget": "Budget", "components.MovieDetails.budget": "Budget",
"components.MovieDetails.cancelrequest": "Antrag abbrechen", "components.MovieDetails.cancelrequest": "Anfrage zurücknehmen",
"components.MovieDetails.cast": "Besetzung", "components.MovieDetails.cast": "Besetzung",
"components.MovieDetails.decline": "Ablehnen", "components.MovieDetails.decline": "Ablehnen",
"components.MovieDetails.manageModalClearMedia": "Alle Mediendaten löschen", "components.MovieDetails.manageModalClearMedia": "Alle Mediendaten löschen",
"components.MovieDetails.manageModalClearMediaWarning": "Dadurch werden alle Mediendaten einschließlich aller Anträge für dieses Element entfernt. Diese Aktion ist irreversibel. Wenn dieses Element in Ihrer Plex-Bibliothek vorhanden ist, werden die Medieninformationen bei der nächsten Synchronisierung neu erstellt.", "components.MovieDetails.manageModalClearMediaWarning": "Dadurch werden alle Mediendaten einschließlich aller Anfragen für dieses Element entfernt. Diese Aktion ist irreversibel. Wenn dieses Element in Ihrer Plex-Bibliothek vorhanden ist, werden die Medieninformationen bei der nächsten Synchronisierung neu erstellt.",
"components.MovieDetails.manageModalNoRequests": "Keine Anträge", "components.MovieDetails.manageModalNoRequests": "Keine Anträge",
"components.MovieDetails.manageModalRequests": "Anträge", "components.MovieDetails.manageModalRequests": "Anfragen",
"components.MovieDetails.manageModalTitle": "Filme verwalten", "components.MovieDetails.manageModalTitle": "Film verwalten",
"components.MovieDetails.originallanguage": "Originalsprache", "components.MovieDetails.originallanguage": "Originalsprache",
"components.MovieDetails.overview": "Übersicht", "components.MovieDetails.overview": "Übersicht",
"components.MovieDetails.overviewunavailable": "Übersicht nicht verfügbar", "components.MovieDetails.overviewunavailable": "Übersicht nicht verfügbar",
"components.MovieDetails.pending": "Ausstehend", "components.MovieDetails.pending": "Ausstehend",
"components.MovieDetails.recommendations": "Empfehlungen", "components.MovieDetails.recommendations": "Empfehlungen",
"components.MovieDetails.recommendationssubtext": "Wenn Ihnen {title} gefallen hat, könnte Ihnen auch gefallen …", "components.MovieDetails.recommendationssubtext": "Wenn dir {title} gefallen hat, könnte dir auch gefallen …",
"components.MovieDetails.releasedate": "Erscheinungsdatum", "components.MovieDetails.releasedate": "Erscheinungsdatum",
"components.MovieDetails.request": "Antrag", "components.MovieDetails.request": "Anfrage",
"components.MovieDetails.revenue": "Einnahmen", "components.MovieDetails.revenue": "Einnahmen",
"components.MovieDetails.runtime": "{minutes} Minuten", "components.MovieDetails.runtime": "{minutes} Minuten",
"components.MovieDetails.similar": "Ähnliche Titel", "components.MovieDetails.similar": "Ähnliche Titel",
@ -44,7 +44,7 @@
"components.MovieDetails.status": "Status", "components.MovieDetails.status": "Status",
"components.MovieDetails.unavailable": "Nicht verfügbar", "components.MovieDetails.unavailable": "Nicht verfügbar",
"components.MovieDetails.userrating": "Benutzerbewertung", "components.MovieDetails.userrating": "Benutzerbewertung",
"components.MovieDetails.viewrequest": "Antrag anzeigen", "components.MovieDetails.viewrequest": "Anfrage anzeigen",
"components.PersonDetails.appearsin": "Erscheint in", "components.PersonDetails.appearsin": "Erscheint in",
"components.PersonDetails.ascharacter": "als {character}", "components.PersonDetails.ascharacter": "als {character}",
"components.PersonDetails.nobiography": "Keine Biografie verfügbar.", "components.PersonDetails.nobiography": "Keine Biografie verfügbar.",
@ -53,35 +53,35 @@
"components.PlexLoginButton.loginwithplex": "Anmeldung mit Plex", "components.PlexLoginButton.loginwithplex": "Anmeldung mit Plex",
"components.RequestBlock.seasons": "Staffeln", "components.RequestBlock.seasons": "Staffeln",
"components.RequestCard.all": "Alle", "components.RequestCard.all": "Alle",
"components.RequestCard.requestedby": "Antrag von {username}", "components.RequestCard.requestedby": "Anfrage von {username}",
"components.RequestCard.seasons": "Staffeln", "components.RequestCard.seasons": "Staffeln",
"components.RequestList.RequestItem.notavailable": "entf.", "components.RequestList.RequestItem.notavailable": "entf.",
"components.RequestList.RequestItem.requestedby": "Antrag von {username}", "components.RequestList.RequestItem.requestedby": "Angefragt von {username}",
"components.RequestList.RequestItem.seasons": "Staffeln", "components.RequestList.RequestItem.seasons": "Staffeln",
"components.RequestList.mediaInfo": "Medieninfos", "components.RequestList.mediaInfo": "Medieninfos",
"components.RequestList.modifiedBy": "Zuletzt geändert von", "components.RequestList.modifiedBy": "Zuletzt geändert von",
"components.RequestList.next": "Nächste", "components.RequestList.next": "Nächste",
"components.RequestList.previous": "Vorherige", "components.RequestList.previous": "Vorherige",
"components.RequestList.requestedAt": "Antrag erstellt am", "components.RequestList.requestedAt": "Angefragt am",
"components.RequestList.requests": "Anträge", "components.RequestList.requests": "Anfragen",
"components.RequestList.showingresults": "Anzeigen von <strong>{from}</strong> bis <strong> {to} </strong> von <strong> {total} </strong> Ergebnissen", "components.RequestList.showingresults": "Anzeigen von <strong>{from}</strong> bis <strong> {to} </strong> von <strong> {total} </strong> Ergebnissen",
"components.RequestList.status": "Status", "components.RequestList.status": "Status",
"components.RequestModal.cancel": "Antrag abbrechen", "components.RequestModal.cancel": "Anfrage abbrechen",
"components.RequestModal.cancelling": "Abbrechen …", "components.RequestModal.cancelling": "Abbrechen …",
"components.RequestModal.cancelrequest": "Dadurch wird Ihre Antrag entfernt. Sind Sie sicher, dass Sie weitermachen wollen?", "components.RequestModal.cancelrequest": "Dadurch wird deine Anfrage entfernt. Bist du dir sicher, dass du weitermachen willst?",
"components.RequestModal.close": "Schließen", "components.RequestModal.close": "Schließen",
"components.RequestModal.extras": "Extras", "components.RequestModal.extras": "Extras",
"components.RequestModal.notrequested": "Nicht angefordert", "components.RequestModal.notrequested": "Nicht angefragt",
"components.RequestModal.numberofepisodes": "Anzahl der Folgen", "components.RequestModal.numberofepisodes": "Anzahl der Folgen",
"components.RequestModal.pendingrequest": "Ausstehender Antrag für {title}", "components.RequestModal.pendingrequest": "Ausstehende Anfrage für {title}",
"components.RequestModal.request": "Antrag", "components.RequestModal.request": "Anfrage",
"components.RequestModal.requestCancel": "Antrag für <strong>{title}</strong> storniert", "components.RequestModal.requestCancel": "Anfrage für <strong>{title}</strong> abgebrochen",
"components.RequestModal.requestSuccess": "<strong>{title}</strong> angefordert.", "components.RequestModal.requestSuccess": "<strong>{title}</strong> angefragt.",
"components.RequestModal.requestadmin": "Ihr Antrag wird sofort genehmigt.", "components.RequestModal.requestadmin": "Deine Anfrage wird direkt genehmigt.",
"components.RequestModal.requestfrom": "Derzeit ist ein Antrag von {username} ausstehend", "components.RequestModal.requestfrom": "Derzeit steht eine Anfrage von {username} aus",
"components.RequestModal.requesting": "Antrag wird erstellt …", "components.RequestModal.requesting": "Wird angefragt…",
"components.RequestModal.requestseasons": "{seasonCount} {seasonCount, plural, one {Season} other {Seasons}} anfordern", "components.RequestModal.requestseasons": "{seasonCount} {seasonCount, plural, one {Season} other {Seasons}} anfragen",
"components.RequestModal.requesttitle": "{title} anfordern", "components.RequestModal.requesttitle": "{title} anfragen",
"components.RequestModal.season": "Staffel", "components.RequestModal.season": "Staffel",
"components.RequestModal.seasonnumber": "Staffel {number}", "components.RequestModal.seasonnumber": "Staffel {number}",
"components.RequestModal.selectseason": "Staffel(n) auswählen", "components.RequestModal.selectseason": "Staffel(n) auswählen",
@ -306,9 +306,9 @@
"components.TvDetails.TvCast.fullseriescast": "Vollserienbesetzung", "components.TvDetails.TvCast.fullseriescast": "Vollserienbesetzung",
"components.MovieDetails.MovieCast.fullcast": "Vollständige Besetzung", "components.MovieDetails.MovieCast.fullcast": "Vollständige Besetzung",
"components.Settings.Notifications.emailsettingssaved": "E-Mail-Benachrichtigungseinstellungen gespeichert!", "components.Settings.Notifications.emailsettingssaved": "E-Mail-Benachrichtigungseinstellungen gespeichert!",
"components.Settings.Notifications.emailsettingsfailed": "Die Einstellungen für die E-Mail-Benachrichtigungen konnten nicht gespeichert werden.", "components.Settings.Notifications.emailsettingsfailed": "Fehler beim Speichern der E-Mail-Benachrichtigungseinstellungen.",
"components.Settings.Notifications.discordsettingssaved": "Discord-Benachrichtigungseinstellungen gespeichert!", "components.Settings.Notifications.discordsettingssaved": "Discord-Benachrichtigungseinstellungen gespeichert!",
"components.Settings.Notifications.discordsettingsfailed": "Die Einstellungen für die Discord-Benachrichtigungen konnten nicht gespeichert werden.", "components.Settings.Notifications.discordsettingsfailed": "Fehler beim Speichern der Discord-Benachrichtigungseinstellungen.",
"components.Settings.validationPortRequired": "Sie müssen einen Port angeben", "components.Settings.validationPortRequired": "Sie müssen einen Port angeben",
"components.Settings.validationHostnameRequired": "Sie müssen einen Hostnamen/IP angeben", "components.Settings.validationHostnameRequired": "Sie müssen einen Hostnamen/IP angeben",
"components.Settings.SonarrModal.validationNameRequired": "Sie müssen einen Servernamen angeben", "components.Settings.SonarrModal.validationNameRequired": "Sie müssen einen Servernamen angeben",
@ -321,5 +321,32 @@
"components.Settings.SettingsAbout.clickheretojoindiscord": "Klicken Sie hier, um unserem Discord-Server beizutreten.", "components.Settings.SettingsAbout.clickheretojoindiscord": "Klicken Sie hier, um unserem Discord-Server beizutreten.",
"components.Settings.RadarrModal.validationNameRequired": "Sie müssen einen Servernamen angeben", "components.Settings.RadarrModal.validationNameRequired": "Sie müssen einen Servernamen angeben",
"components.Setup.tip": "Tipp", "components.Setup.tip": "Tipp",
"components.Setup.syncingbackground": "Die Synchronisierung wird im Hintergrund ausgeführt. Sie können die Konfiguration in der Zwischenzeit fortsetzen." "components.Setup.syncingbackground": "Die Synchronisierung wird im Hintergrund ausgeführt. Sie können die Konfiguration in der Zwischenzeit fortsetzen.",
"i18n.deleting": "Löschen …",
"components.UserList.userdeleteerror": "Beim Löschen des Benutzers ist ein Fehler aufgetreten",
"components.UserList.userdeleted": "Benutzer gelöscht",
"components.UserList.deleteuser": "Benutzer löschen",
"components.UserList.deleteconfirm": "Wollen Sie diesen Benutzer wirklich löschen? Alle vorhandenen Anforderungsdaten dieses Benutzers werden entfernt.",
"components.Settings.nodefaultdescription": "Mindestens ein Server muss als Standard markiert sein, bevor Anforderungen an Ihre Dienste weitergeleitet werden.",
"components.Settings.nodefault": "Kein Standardserver ausgewählt!",
"components.Settings.no4kimplemented": "(Standard-4K-Server sind derzeit nicht implementiert.)",
"components.Settings.SonarrModal.testFirstRootFolders": "Testen Sie Ihre Verbindung, um Stammordner zu laden",
"components.Settings.SonarrModal.testFirstQualityProfiles": "Testen Sie Ihre Verbindung, um Qualitätsprofile zu laden",
"components.Settings.SonarrModal.loadingrootfolders": "Laden von Stammordnern…",
"components.Settings.SonarrModal.loadingprofiles": "Qualitätsprofile werden geladen…",
"components.Settings.RadarrModal.validationMinimumAvailabilityRequired": "Sie müssen die Mindestverfügbarkeit auswählen",
"components.Settings.RadarrModal.testFirstRootFolders": "Testen Sie Ihre Verbindung, um Stammordner zu laden",
"components.Settings.RadarrModal.testFirstQualityProfiles": "Testen Sie Ihre Verbindung zu Lastqualitätsprofilen",
"components.Settings.RadarrModal.loadingrootfolders": "Laden von Stammordnern…",
"components.Settings.RadarrModal.loadingprofiles": "Qualitätsprofile werden geladen…",
"components.TvDetails.anime": "Anime",
"components.Settings.toastApiKeySuccess": "Neuer API Schlüssel generiert!",
"components.TvDetails.showtype": "Serientyp",
"components.TvDetails.network": "Netzwerk",
"components.Settings.toastSettingsSuccess": "Einstellungen gespeichert.",
"components.Settings.toastSettingsFailure": "Beim Speichern der Einstellungen ging etwas schief.",
"components.Settings.toastApiKeyFailure": "Bei der Generierung eines neuen API Schlüssels kam es zu einem Fehler.",
"components.Settings.SonarrModal.animerootfolder": "Animestammverzeichnis",
"components.Settings.SonarrModal.animequalityprofile": "Animequalitätsprofil",
"components.MovieDetails.studio": "Studio"
} }

@ -321,5 +321,22 @@
"components.Settings.applicationurl": "URL de la aplicación", "components.Settings.applicationurl": "URL de la aplicación",
"components.Settings.apikey": "Clave API", "components.Settings.apikey": "Clave API",
"components.Setup.tip": "Consejo", "components.Setup.tip": "Consejo",
"components.Setup.syncingbackground": "La sincronización se ejecutará en segundo plano. Mientras tanto, puede continuar con el proceso de configuración." "components.Setup.syncingbackground": "La sincronización se ejecutará en segundo plano. Mientras tanto, puede continuar con el proceso de configuración.",
"i18n.deleting": "Eliminando…",
"components.UserList.userdeleteerror": "Algo salió mal al eliminar al usuario",
"components.UserList.userdeleted": "Usuario eliminado",
"components.UserList.deleteuser": "Eliminar usuario",
"components.UserList.deleteconfirm": "¿Está seguro de que desea eliminar este usuario? Se eliminarán todas las solicitudes existentes de este usuario.",
"components.Settings.nodefaultdescription": "Al menos un servidor debe estar marcado como predeterminado antes de que cualquier solicitud llegue a sus servicios.",
"components.Settings.nodefault": "¡Ningún servidor predeterminado seleccionado!",
"components.Settings.no4kimplemented": "(Los servidores 4K predeterminados no están implementados actualmente)",
"components.Settings.SonarrModal.testFirstRootFolders": "Prueba la conexión para cargar carpetas raíz",
"components.Settings.SonarrModal.testFirstQualityProfiles": "Prueba la conexión para cargar perfiles de calidad",
"components.Settings.SonarrModal.loadingrootfolders": "Cargando carpetas raíz…",
"components.Settings.SonarrModal.loadingprofiles": "Cargando perfiles de calidad…",
"components.Settings.RadarrModal.validationMinimumAvailabilityRequired": "Debes seleccionar disponibilidad mínima",
"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.loadingrootfolders": "Cargando carpetas raíz…",
"components.Settings.RadarrModal.loadingprofiles": "Cargando perfiles de calidad…"
} }

@ -321,5 +321,32 @@
"components.Settings.SettingsAbout.clickheretojoindiscord": "Cliquez ici pour rejoindre notre serveur Discord.", "components.Settings.SettingsAbout.clickheretojoindiscord": "Cliquez ici pour rejoindre notre serveur Discord.",
"components.Settings.RadarrModal.validationNameRequired": "Vous devez fournir un nom de serveur", "components.Settings.RadarrModal.validationNameRequired": "Vous devez fournir un nom de serveur",
"components.Setup.tip": "Astuce", "components.Setup.tip": "Astuce",
"components.Setup.syncingbackground": "La synchronisation s'exécutera en arrière-plan. Vous pouvez continuer le processus de configuration en attendant." "components.Setup.syncingbackground": "La synchronisation s'exécutera en arrière-plan. Vous pouvez continuer le processus de configuration en attendant.",
"i18n.deleting": "Suppression…",
"components.UserList.userdeleteerror": "Une erreur s'est produite lors de la suppression de l'utilisateur",
"components.UserList.userdeleted": "Utilisateur supprimé",
"components.UserList.deleteuser": "Supprimer l'utilisateur",
"components.UserList.deleteconfirm": "Voulez-vous vraiment supprimer cet utilisateur ? Toutes les données de demande existantes de cet utilisateur seront supprimées.",
"components.Settings.nodefaultdescription": "Au moins un serveur doit être marqué par défaut avant que toute demande parvienne à vos services.",
"components.Settings.nodefault": "Aucun serveur par défaut sélectionné !",
"components.Settings.no4kimplemented": "(Les serveurs 4K par défaut ne sont actuellement pas implémentés)",
"components.Settings.SonarrModal.testFirstRootFolders": "Testez votre connexion pour charger les dossiers racine",
"components.Settings.SonarrModal.testFirstQualityProfiles": "Testez votre connexion pour charger des profils qualité",
"components.Settings.SonarrModal.loadingrootfolders": "Chargement des dossiers racine…",
"components.Settings.SonarrModal.loadingprofiles": "Chargement des profils qualité…",
"components.Settings.RadarrModal.validationMinimumAvailabilityRequired": "Vous devez sélectionner une disponibilité minimale",
"components.Settings.RadarrModal.testFirstRootFolders": "Testez votre connexion pour charger les dossiers racine",
"components.Settings.RadarrModal.testFirstQualityProfiles": "Testez votre connexion pour charger des profils qualité",
"components.Settings.RadarrModal.loadingrootfolders": "Chargement des dossiers racine…",
"components.Settings.RadarrModal.loadingprofiles": "Chargement des profils qualité…",
"components.TvDetails.showtype": "Type de série",
"components.TvDetails.network": "Réseau",
"components.TvDetails.anime": "Anime",
"components.Settings.toastSettingsSuccess": "Paramètres enregistrés.",
"components.Settings.toastSettingsFailure": "Une erreur s'est produite lors de l'enregistrement des paramètres.",
"components.Settings.toastApiKeySuccess": "Nouvelle clé API générée !",
"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.animequalityprofile": "Profil qualité pour anime",
"components.MovieDetails.studio": "Studio"
} }

@ -0,0 +1,320 @@
{
"components.Discover.recentrequests": "Richieste recenti",
"components.Discover.recentlyAdded": "Aggiunti di recente",
"components.Discover.populartv": "Serie popolari",
"components.Discover.popularmovies": "Film popolari",
"components.Discover.nopending": "Nessuna richiesta in sospeso",
"components.Discover.discovertv": "Serie popolari",
"components.Discover.discovermovies": "Film popolari",
"components.UserEdit.email": "E-mail",
"components.Settings.Notifications.validationFromRequired": "È necessario fornire un indirizzo mittente di posta elettronica",
"components.Settings.Notifications.emailsettingssaved": "Impostazioni di notifica tramite posta elettronica salvate!",
"components.Settings.Notifications.emailsettingsfailed": "Impossibile salvare le impostazioni di notifica tramite posta elettronica.",
"components.Settings.Notifications.emailsender": "Indirizzo mittente di posta elettronica",
"components.Settings.SonarrModal.testing": "Test in corso...",
"components.Settings.RadarrModal.testing": "Test in corso...",
"components.Settings.address": "Indirizzo",
"components.Settings.SonarrModal.test": "Test",
"components.Settings.SonarrModal.ssl": "SSL",
"components.Settings.SonarrModal.saving": "Salvataggio...",
"components.Settings.SonarrModal.port": "Porta",
"components.Settings.SonarrModal.hostname": "Hostname",
"components.Settings.SettingsAbout.version": "Versione",
"components.Settings.RadarrModal.test": "Test",
"components.Settings.RadarrModal.ssl": "SSL",
"components.Settings.RadarrModal.saving": "Salvataggio…",
"components.Settings.RadarrModal.port": "Porta",
"components.Settings.RadarrModal.hostname": "Hostname",
"components.Settings.Notifications.saving": "Salvataggio…",
"components.RequestModal.requesting": "Richiesta in corso…",
"components.MovieDetails.pending": "In sospeso",
"components.Settings.Notifications.agentenabled": "Agente abilitato",
"components.Search.searchresults": "Risultati di ricerca",
"components.RequestModal.status": "Stato",
"components.RequestModal.selectseason": "Seleziona stagioni",
"components.RequestModal.seasonnumber": "Stagione {number}",
"components.RequestModal.season": "Stagione",
"components.RequestModal.requestadmin": "La tua richiesta verrà approvata immediatamente.",
"components.RequestModal.requestSuccess": "<strong>{title}</strong> richiesto.",
"components.RequestModal.requestCancel": "Richiesta per <strong>{title}</strong> cancellata",
"components.RequestModal.request": "Richiedi",
"components.RequestModal.numberofepisodes": "Nº di episodi",
"components.RequestModal.notrequested": "Non richiesto",
"components.RequestModal.extras": "Extra",
"components.RequestModal.close": "Chiudi",
"components.RequestModal.cancelling": "Cancellazione…",
"components.RequestModal.cancel": "Cancella la richiesta",
"components.RequestList.status": "Stato",
"components.RequestList.requests": "Richieste",
"components.RequestList.requestedAt": "Richiesto",
"components.RequestList.previous": "Precedente",
"components.RequestList.next": "Successivo",
"components.RequestList.modifiedBy": "Ultima modifica da",
"components.RequestList.mediaInfo": "Media",
"components.RequestList.RequestItem.seasons": "Stagioni",
"components.RequestList.RequestItem.requestedby": "Richiesto da {username}",
"components.RequestList.RequestItem.notavailable": "n.a.",
"components.RequestCard.seasons": "Stagioni",
"components.RequestCard.requestedby": "Richiesto da {username}",
"components.RequestCard.all": "Tutte",
"components.RequestBlock.seasons": "Stagioni",
"components.PlexLoginButton.loginwithplex": "Accedi con Plex",
"components.PlexLoginButton.loggingin": "Accesso in corso…",
"components.PlexLoginButton.loading": "Caricamento…",
"components.PersonDetails.nobiography": "Biografia non disponibile.",
"components.PersonDetails.ascharacter": "come {character}",
"components.PersonDetails.appearsin": "Compare in",
"components.MovieDetails.userrating": "Voto pubblico",
"components.MovieDetails.unavailable": "Non disponibile",
"components.MovieDetails.studio": "Studio",
"components.MovieDetails.status": "Stato",
"components.MovieDetails.similarsubtext": "Altri film simili a {title}",
"components.MovieDetails.similar": "Titoli simili",
"components.MovieDetails.runtime": "{minutes} minuti",
"components.MovieDetails.revenue": "Incassi",
"components.MovieDetails.request": "Richiedi",
"components.MovieDetails.releasedate": "Data di uscita",
"components.MovieDetails.recommendationssubtext": "Se ti è piaciuto {title}, potrebbe interessarti…",
"components.MovieDetails.recommendations": "Consigliati",
"components.MovieDetails.overviewunavailable": "Trama non disponibile",
"components.MovieDetails.overview": "Trama",
"components.MovieDetails.originallanguage": "Lingua originale",
"components.MovieDetails.manageModalTitle": "Gestisci film",
"components.MovieDetails.manageModalRequests": "Richieste",
"components.MovieDetails.manageModalNoRequests": "Nessuna richiesta",
"components.MovieDetails.manageModalClearMediaWarning": "Questo rimuoverà tutti i dati, incluse le richieste per questo elemento in modo irreversibile. Se questo elemento esiste nella tua libreria di Plex, i dati verranno ricreati alla prossima sincronizzazione.",
"components.MovieDetails.manageModalClearMedia": "Cancella tutti i dati",
"components.MovieDetails.cancelrequest": "Annulla la richiesta",
"components.MovieDetails.decline": "Rifiuta",
"components.MovieDetails.cast": "Cast",
"components.MovieDetails.budget": "Budget",
"components.MovieDetails.available": "Disponibile",
"components.MovieDetails.approve": "Approva",
"components.MovieDetails.MovieCast.fullcast": "Cast completo",
"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.UserDropdown.signout": "Esci",
"components.Layout.Sidebar.users": "Utenti",
"components.Layout.Sidebar.settings": "Impostazioni",
"components.Layout.Sidebar.requests": "Richieste",
"components.Layout.SearchInput.searchPlaceholder": "Cerca film e serie",
"components.Layout.LanguagePicker.changelanguage": "Cambia la lingua",
"components.Discover.upcomingmovies": "Film in uscita",
"components.Discover.upcoming": "Film in uscita",
"components.Discover.trending": "Di tendenza",
"components.UserEdit.avatar": "Avatar",
"components.UserEdit.edituser": "Modifica l'utente",
"components.UserEdit.settings": "Gestisci le impostazioni",
"components.UserEdit.saving": "Salvataggio…",
"components.UserEdit.save": "Salva",
"components.UserEdit.usersaved": "Utente salvato",
"components.UserEdit.usersDescription": "Concede l'autorizzazione per gestire gli utenti di Overseerr. Gli utenti con questa autorizzazione non possono modificare gli utenti con privilegi di amministratore o concederla.",
"components.UserEdit.users": "Gestisci gli utenti",
"components.UserEdit.username": "Nome utente",
"components.UserList.deleteconfirm": "Eliminare l'utente? Tutti i dati di richiesta esistenti da questo utente verranno rimossi.",
"components.UserList.delete": "Elimina",
"components.UserList.created": "Creato",
"components.UserList.admin": "Amministratore",
"components.UserList.role": "Ruolo",
"components.UserList.plexuser": "Utente Plex",
"components.UserList.lastupdated": "Ultimo aggiornamento",
"components.UserList.edit": "Modifica",
"components.UserList.deleteuser": "Elimina l'utente",
"components.UserList.userlist": "Elenco utenti",
"components.UserList.userdeleteerror": "Qualcosa è andato storto eliminando l'utente",
"components.UserList.userdeleted": "Utente eliminato",
"components.UserList.user": "Utente",
"components.UserList.totalrequests": "Totale richieste",
"i18n.declined": "Rifiutato",
"i18n.decline": "Rifiuta",
"i18n.cancel": "Annulla",
"i18n.available": "Disponibile",
"i18n.approved": "Approvato",
"i18n.approve": "Approva",
"components.UserList.usertype": "Tipo di utente",
"components.UserList.username": "Nome utente",
"i18n.unavailable": "Non disponibile",
"i18n.tvshows": "Serie",
"i18n.processing": "Elaborazione…",
"i18n.pending": "In sospeso",
"i18n.partiallyavailable": "Parzialmente disponibile",
"i18n.movies": "Film",
"i18n.deleting": "Eliminazione…",
"i18n.delete": "Elimina",
"pages.oops": "Ops",
"components.Settings.RadarrModal.rootfolder": "Cartella radice",
"components.Settings.RadarrModal.selectRootFolder": "Seleziona una cartella radice",
"components.Settings.RadarrModal.selectQualityProfile": "Seleziona un profilo qualità",
"components.Settings.RadarrModal.selectMinimumAvailability": "Seleziona la disponibilità minima",
"components.Settings.RadarrModal.save": "Salva i cambiamenti",
"components.Settings.RadarrModal.qualityprofile": "Profilo qualità",
"components.Settings.RadarrModal.minimumAvailability": "Disponibilità minima",
"components.Settings.RadarrModal.editradarr": "Modifica server Radarr",
"components.Settings.RadarrModal.defaultserver": "Server predefinito",
"components.Settings.RadarrModal.apiKey": "Chiave API",
"components.Settings.RadarrModal.add": "Aggiungi un server",
"components.Settings.Notifications.save": "Salva i cambiamenti",
"components.Settings.Notifications.discordsettingsfailed": "Impossibile salvare le impostazioni di notifica Discord.",
"components.RequestModal.requesttitle": "Richiedi {title}",
"components.RequestModal.requestfrom": "Al momento è in sospeso una richiesta da {username}",
"components.RequestModal.cancelrequest": "Questo rimuoverà la richiesta. Continuare?",
"components.RequestModal.pendingrequest": "Richiesta in sospeso per {title}",
"components.MovieDetails.viewrequest": "Visualizza la richiesta",
"components.Layout.Sidebar.dashboard": "Esplora",
"components.TvDetails.manageModalTitle": "Gestisci serie",
"components.TvDetails.manageModalRequests": "Richieste",
"components.TvDetails.manageModalNoRequests": "Nessuna richiesta",
"components.TvDetails.manageModalClearMedia": "Cancella tutti i dati multimediali",
"components.TvDetails.declinerequests": "Rifiuta {requestCount} {requestCount, plural, one {Request} other {Requests}}",
"components.TvDetails.decline": "Rifiuta",
"components.TvDetails.cast": "Cast",
"components.TvDetails.cancelrequest": "Annulla la richiesta",
"components.TvDetails.available": "Disponibile",
"components.TvDetails.approverequests": "Approva {requestCount} {requestCount, plural, one {Request} other {Requests}}",
"components.TvDetails.approve": "Approva",
"components.TvDetails.anime": "Anime",
"components.TvDetails.TvCast.fullseriescast": "Cast completo della serie",
"components.TitleCard.tvshow": "Serie",
"components.Slider.noresults": "Nessun risultato",
"components.Setup.welcome": "Benvenuti in Overseerr",
"components.TitleCard.movie": "Film",
"components.Setup.loginwithplex": "Accedi con Plex",
"components.Setup.configureplex": "Configurare Plex",
"components.Settings.validationPortRequired": "È necessario fornire una porta",
"components.Settings.validationHostnameRequired": "È necessario fornire un nome host/IP",
"components.Settings.toastSettingsSuccess": "Impostazioni salvate.",
"components.Settings.syncing": "Sincronizzazione…",
"components.Settings.startscan": "Avvia la scansione",
"components.Settings.ssl": "SSL",
"components.Settings.saving": "Salvataggio…",
"components.Settings.save": "Salva i cambiamenti",
"components.Settings.runnow": "Esegui ora",
"components.Settings.radarrsettings": "Impostazioni Radarr",
"components.Settings.plexsettings": "Impostazioni Plex",
"components.Settings.notrunning": "Non in esecuzione",
"components.Settings.notificationsettingsDescription": "Qui puoi scegliere quali tipi di notifiche inviare e attraverso quali tipi di servizi.",
"components.Settings.notificationsettings": "Impostazioni di notifica",
"components.Settings.nodefaultdescription": "Almeno un server deve essere contrassegnato come predefinito prima che qualsiasi richiesta lo apportare ai servizi.",
"components.Settings.nodefault": "Nessun server predefinito selezionato!",
"components.Settings.no4kimplemented": "(I server 4K predefiniti non sono attualmente implementati)",
"components.Settings.nextexecution": "Esecuzione successiva",
"components.Settings.menuServices": "Servizi",
"components.Settings.menuPlexSettings": "Plex",
"components.Settings.menuNotifications": "Notifiche",
"components.Settings.menuLogs": "Registri",
"components.Settings.menuGeneralSettings": "Impostazioni generali",
"components.Settings.menuAbout": "Informazioni",
"components.Settings.manualscan": "Scansione manuale della biblioteca",
"components.Settings.librariesRemaining": "Biblioteche rimanenti: {count}",
"components.Settings.hostname": "Nome host/IP",
"components.Settings.generalsettingsDescription": "Queste sono impostazioni relative alla configurazione generale di Overseerr.",
"components.Settings.generalsettings": "Impostazioni generali",
"components.Settings.edit": "Modifica",
"components.Settings.deleteserverconfirm": "Sei sicuro/a di voler eliminare questo server?",
"components.Settings.delete": "Elimina",
"components.Settings.default4k": "4K predefinito",
"components.Settings.default": "Predefinito",
"components.Settings.currentlibrary": "Biblioteca corrente: {name}",
"components.Settings.copied": "Chiave API copiata negli appunti",
"components.Settings.cancelscan": "Annulla l'analisi",
"components.Settings.applicationurl": "URL applicazione",
"components.Settings.apikey": "Chiave API",
"components.Settings.addsonarr": "Aggiungi un server Sonarr",
"components.Settings.addradarr": "Aggiungi un server radarr",
"components.Settings.activeProfile": "Profilo attivo",
"components.Settings.SonarrModal.validationRootFolderRequired": "È necessario selezionare una cartella radice",
"components.Settings.SonarrModal.validationProfileRequired": "È necessario selezionare un profilo",
"components.Settings.SonarrModal.validationPortRequired": "È necessario fornire una porta",
"components.Settings.SonarrModal.validationNameRequired": "È necessario fornire un nome di server",
"components.Settings.SonarrModal.validationHostnameRequired": "È necessario fornire un nome host/IP",
"components.Settings.SonarrModal.validationApiKeyRequired": "È necessario fornire una chiave API",
"components.Settings.SonarrModal.toastRadarrTestSuccess": "Stabilita la connessione Sonarr!",
"components.Settings.SonarrModal.toastRadarrTestFailure": "Impossibile connettersi a Sonarr Server",
"components.Settings.SonarrModal.testFirstRootFolders": "Testa la connessione per caricare le cartelle radice",
"components.Settings.SonarrModal.testFirstQualityProfiles": "Testa la connessione per caricare profili di qualità",
"components.Settings.SonarrModal.servernamePlaceholder": "Un server Sonarr",
"components.Settings.SonarrModal.servername": "Nome server",
"components.Settings.SonarrModal.server4k": "Server 4K",
"components.Settings.SonarrModal.selectRootFolder": "Seleziona una cartella radice",
"components.Settings.SonarrModal.selectQualityProfile": "Seleziona un profilo qualità",
"components.Settings.SonarrModal.seasonfolders": "Cartelle stagione",
"components.Settings.SonarrModal.save": "Salva i cambiamenti",
"components.Settings.SonarrModal.rootfolder": "Cartella radice",
"components.Settings.SonarrModal.qualityprofile": "Profilo qualità",
"components.Settings.SonarrModal.loadingrootfolders": "Caricamento delle cartelle radice in…",
"components.Settings.SonarrModal.loadingprofiles": "Caricamento profili qualità…",
"components.Settings.SonarrModal.editsonarr": "Modifica server Sonarr",
"components.Settings.SonarrModal.defaultserver": "Server predefinito",
"components.Settings.SonarrModal.createsonarr": "Crea nuovo server Sonarr",
"components.Settings.SonarrModal.baseUrlPlaceholder": "Esempio: /sonarr",
"components.Settings.SonarrModal.baseUrl": "URL di base",
"components.Settings.SonarrModal.apiKeyPlaceholder": "La tua chiave API Sonarr",
"components.Settings.SonarrModal.apiKey": "Chiave API",
"components.Settings.SonarrModal.animerootfolder": "Cartella radice anime",
"components.Settings.SonarrModal.animequalityprofile": "Profilo qualità anime",
"components.Settings.SonarrModal.add": "Aggiungi un server",
"components.Settings.SettingsAbout.totalrequests": "Totale richieste",
"components.Settings.SettingsAbout.totalmedia": "Media totali",
"components.Settings.SettingsAbout.overseerrinformation": "Informazioni su Overseerr",
"components.Settings.SettingsAbout.githubdiscussions": "Discussioni su GitHub",
"components.Settings.SettingsAbout.gettingsupport": "Ottieni aiuto",
"components.Settings.SettingsAbout.clickheretojoindiscord": "Clicca qui per unirti al nostro server Discord.",
"components.Settings.RadarrModal.validationRootFolderRequired": "È necessario selezionare una cartella radice",
"components.Settings.RadarrModal.validationProfileRequired": "È necessario selezionare un profilo",
"components.Settings.RadarrModal.validationPortRequired": "È necessario fornire una porta",
"components.Settings.RadarrModal.validationNameRequired": "È necessario fornire un nome di server",
"components.Settings.RadarrModal.validationMinimumAvailabilityRequired": "È necessario selezionare la disponibilità minima",
"components.Settings.RadarrModal.validationHostnameRequired": "È necessario fornire un nome host/IP",
"components.Settings.RadarrModal.validationApiKeyRequired": "È necessario fornire una chiave API",
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Stabilita la connessione 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.testFirstQualityProfiles": "Testa la connessione per caricare profili qualità",
"components.Settings.RadarrModal.servernamePlaceholder": "Un server Radarr",
"components.Settings.RadarrModal.servername": "Nome server",
"components.Settings.RadarrModal.server4k": "Server 4K",
"components.Settings.RadarrModal.loadingrootfolders": "Caricamento delle cartelle radice in…",
"components.Settings.RadarrModal.loadingprofiles": "Caricamento profili di qualità…",
"components.Settings.RadarrModal.createradarr": "Crea un nuovo server Radarr",
"components.Settings.RadarrModal.baseUrlPlaceholder": "Esempio: /radarr",
"components.Settings.RadarrModal.baseUrl": "URL di base",
"components.Settings.RadarrModal.apiKeyPlaceholder": "La tua chiave API Radarr",
"components.Settings.Notifications.webhookUrlPlaceholder": "Impostazioni server -> integrazioni -> Webhook",
"components.Settings.Notifications.webhookUrl": "URL webhook",
"components.Settings.Notifications.validationWebhookUrlRequired": "È necessario fornire un URL webhook",
"components.Settings.Notifications.validationSmtpPortRequired": "È necessario fornire una porta SMTP",
"components.Settings.Notifications.validationSmtpHostRequired": "È necessario fornire un host SMTP",
"components.Settings.Notifications.smtpPort": "Porta SMTP",
"components.Settings.Notifications.smtpHost": "Host SMTP",
"components.Settings.Notifications.enableSsl": "Abilita SSL",
"components.Settings.Notifications.discordsettingssaved": "Impostazioni di notifica Discord salvate!",
"components.Settings.Notifications.authUser": "Utente autenticazione",
"components.Settings.Notifications.authPass": "Password autenticazione",
"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.UserEdit.userfail": "Qualcosa è andato storto salvando l'utente.",
"components.UserEdit.requestDescription": "Concede l'autorizzazione per richiedere film e serie.",
"components.UserEdit.request": "Richiesta",
"components.UserEdit.permissions": "Autorizzazioni",
"components.UserEdit.managerequestsDescription": "Concede l'autorizzazione per gestire le richieste Overseerr. Ciò include l'approvazione e la negazione delle richieste.",
"components.UserEdit.managerequests": "Gestisci le richieste",
"components.UserEdit.autoapproveDescription": "Concede l'approvazione automatica per tutte le richieste effettuate da questo utente.",
"components.UserEdit.autoapprove": "Approvazione automatica",
"components.UserEdit.adminDescription": "Accesso completo all'amministratore. Ignora tutti i controlli delle autorizzazioni.",
"components.UserEdit.admin": "Amministratore",
"components.TvDetails.userrating": "Voto pubblico",
"components.TvDetails.unavailable": "Non disponibile",
"components.TvDetails.status": "Stato",
"components.TvDetails.similarsubtext": "Altre serie simili a {title}",
"components.TvDetails.similar": "Serie simile",
"components.TvDetails.showtype": "Tipo di serie",
"components.TvDetails.requestmore": "Richiedi di più",
"components.TvDetails.request": "Richiesta",
"components.TvDetails.recommendationssubtext": "Se ti è piaciuto {title}, potresti anche piacerti…",
"components.TvDetails.recommendations": "Consigli",
"components.TvDetails.pending": "In sospeso",
"components.TvDetails.overviewunavailable": "Trama non disponibile",
"components.TvDetails.overview": "Trama",
"components.TvDetails.originallanguage": "Lingua originale",
"components.TvDetails.network": "Rete"
}

@ -0,0 +1,64 @@
{
"components.RequestList.requestedAt": "Solicitado",
"components.RequestList.next": "Próxima",
"components.RequestList.modifiedBy": "Última Modificação Feita",
"components.RequestList.mediaInfo": "Detalhes",
"components.RequestList.RequestItem.requestedby": "Solicitado por {username}",
"components.RequestCard.seasons": "Temporadas",
"components.RequestCard.requestedby": "Solicitado por {username}",
"components.RequestBlock.seasons": "Temporadas",
"components.PlexLoginButton.loginwithplex": "Entrar com",
"components.PlexLoginButton.loggingin": "Fazendo login...",
"components.PlexLoginButton.loading": "Carregando...",
"components.PersonDetails.nobiography": "Biografia não disponível.",
"components.PersonDetails.ascharacter": "como {character}",
"components.PersonDetails.appearsin": "Aparece em",
"components.MovieDetails.viewrequest": "Ver solicitação",
"components.MovieDetails.userrating": "Avaliação do usuário",
"components.MovieDetails.unavailable": "Indisponível",
"components.MovieDetails.studio": "Estúdio",
"components.MovieDetails.status": "Detalhes",
"components.MovieDetails.similarsubtext": "Outros filmes semelhantes a {title}",
"components.MovieDetails.similar": "Títulos Semelhantes",
"components.MovieDetails.runtime": "{minutes} minutos",
"components.MovieDetails.revenue": "Receita",
"components.MovieDetails.request": "Solicitar",
"components.MovieDetails.releasedate": "Data de Lançamento",
"components.MovieDetails.recommendationssubtext": "Se você gostou {title}, você provavelmente irá gostar...",
"components.MovieDetails.recommendations": "Recomendações",
"components.MovieDetails.pending": "Pendente",
"components.MovieDetails.overviewunavailable": "Visão Geral Indisponível",
"components.MovieDetails.overview": "Visão Geral",
"components.MovieDetails.originallanguage": "Língua original",
"components.MovieDetails.manageModalTitle": "Gerenciar Filme",
"components.MovieDetails.manageModalRequests": "Solicitações",
"components.MovieDetails.manageModalNoRequests": "Nenhuma Solicitação",
"components.MovieDetails.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.MovieDetails.manageModalClearMedia": "Limpar Todos Dados de Mídia",
"components.MovieDetails.decline": "Rejeitar",
"components.MovieDetails.cast": "Elenco",
"components.MovieDetails.cancelrequest": "Cancelar Solicitação",
"components.MovieDetails.budget": "Orçamento",
"components.MovieDetails.available": "Disponível",
"components.MovieDetails.approve": "Aprovar",
"components.MovieDetails.MovieCast.fullcast": "Elenco Completo",
"components.Login.signinplex": "Faça login para continuar",
"components.Layout.alphawarning": "Esta é uma versão Alpha. Quase tudo é instável ou não funciona. Por favor reporte os problemas no GitHub do Overseerr!",
"components.Layout.UserDropdown.signout": "Sair",
"components.Layout.Sidebar.users": "Usuários",
"components.Layout.Sidebar.settings": "Configurações",
"components.Layout.Sidebar.requests": "Solicitações",
"components.Layout.Sidebar.dashboard": "Descobrir",
"components.Layout.SearchInput.searchPlaceholder": "Pesquisar Filmes & Séries",
"components.Layout.LanguagePicker.changelanguage": "Alterar Idioma",
"components.Discover.upcomingmovies": "Em Breve",
"components.Discover.upcoming": "Em Breve",
"components.Discover.trending": "Em Alta",
"components.Discover.recentrequests": "Solicitações Recentes",
"components.Discover.recentlyAdded": "Adicionado recentemente",
"components.Discover.populartv": "Séries Populares",
"components.Discover.popularmovies": "Filmes Populares",
"components.Discover.nopending": "Nenhuma Solicitação Pendente",
"components.Discover.discovertv": "Séries Populares",
"components.Discover.discovermovies": "Filmes Populares"
}

@ -15,7 +15,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'], opacity: ['disabled', 'hover'],
}, },
plugins: [ plugins: [
require('@tailwindcss/forms'), require('@tailwindcss/forms'),

Loading…
Cancel
Save