mirror of
https://github.com/fallenbagel/jellyseerr.git
synced 2025-12-31 19:59:31 -05:00
Merge remote-tracking branch 'overseerr/develop' into develop
This commit is contained in:
25
cypress/e2e/pull-to-refresh.cy.ts
Normal file
25
cypress/e2e/pull-to-refresh.cy.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
describe('Pull To Refresh', () => {
|
||||
beforeEach(() => {
|
||||
cy.login(Cypress.env('ADMIN_EMAIL'), Cypress.env('ADMIN_PASSWORD'));
|
||||
cy.viewport(390, 844);
|
||||
cy.visitMobile('/');
|
||||
});
|
||||
|
||||
it('reloads the current page', () => {
|
||||
cy.wait(500);
|
||||
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: '/api/v1/*',
|
||||
}).as('apiCall');
|
||||
|
||||
cy.get('.searchbar').swipe('bottom', [190, 400]);
|
||||
|
||||
cy.wait('@apiCall').then((interception) => {
|
||||
assert.isNotNull(
|
||||
interception.response.body,
|
||||
'API was called and received data'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
/// <reference types="cypress" />
|
||||
import 'cy-mobile-commands';
|
||||
|
||||
Cypress.Commands.add('login', (email, password) => {
|
||||
cy.session(
|
||||
|
||||
@@ -2731,6 +2731,12 @@ paths:
|
||||
nullable: true
|
||||
enum: [debug, info, warn, error]
|
||||
default: debug
|
||||
- in: query
|
||||
name: search
|
||||
schema:
|
||||
type: string
|
||||
nullable: true
|
||||
example: plex
|
||||
responses:
|
||||
'200':
|
||||
description: Server log returned
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"cookie-parser": "1.4.6",
|
||||
"copy-to-clipboard": "3.3.2",
|
||||
"country-flag-icons": "1.5.5",
|
||||
"cronstrue": "2.11.0",
|
||||
"csurf": "1.11.0",
|
||||
"date-fns": "2.29.1",
|
||||
"email-templates": "9.0.0",
|
||||
@@ -67,6 +68,7 @@
|
||||
"openpgp": "5.4.0",
|
||||
"plex-api": "5.3.2",
|
||||
"pug": "3.0.2",
|
||||
"pulltorefreshjs": "0.1.22",
|
||||
"react": "18.2.0",
|
||||
"react-ace": "10.1.0",
|
||||
"react-animate-height": "2.1.2",
|
||||
@@ -116,6 +118,7 @@
|
||||
"@types/node": "17.0.36",
|
||||
"@types/node-schedule": "2.1.0",
|
||||
"@types/nodemailer": "6.4.5",
|
||||
"@types/pulltorefreshjs": "0.1.5",
|
||||
"@types/react": "18.0.17",
|
||||
"@types/react-dom": "18.0.6",
|
||||
"@types/react-transition-group": "4.4.5",
|
||||
@@ -133,6 +136,7 @@
|
||||
"babel-plugin-react-intl-auto": "3.3.0",
|
||||
"commitizen": "4.2.5",
|
||||
"copyfiles": "2.4.1",
|
||||
"cy-mobile-commands": "0.3.0",
|
||||
"cypress": "10.6.0",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "8.22.0",
|
||||
|
||||
@@ -16,6 +16,7 @@ interface ScheduledJob {
|
||||
name: string;
|
||||
type: 'process' | 'command';
|
||||
interval: 'short' | 'long' | 'fixed';
|
||||
cronSchedule: string;
|
||||
running?: () => boolean;
|
||||
cancelFn?: () => void;
|
||||
}
|
||||
@@ -33,6 +34,7 @@ export const startJobs = (): void => {
|
||||
name: 'Plex Recently Added Scan',
|
||||
type: 'process',
|
||||
interval: 'short',
|
||||
cronSchedule: jobs['plex-recently-added-scan'].schedule,
|
||||
job: schedule.scheduleJob(
|
||||
jobs['plex-recently-added-scan'].schedule,
|
||||
() => {
|
||||
@@ -52,6 +54,7 @@ export const startJobs = (): void => {
|
||||
name: 'Plex Full Library Scan',
|
||||
type: 'process',
|
||||
interval: 'long',
|
||||
cronSchedule: jobs['plex-full-scan'].schedule,
|
||||
job: schedule.scheduleJob(jobs['plex-full-scan'].schedule, () => {
|
||||
logger.info('Starting scheduled job: Plex Full Library Scan', {
|
||||
label: 'Jobs',
|
||||
@@ -71,6 +74,7 @@ export const startJobs = (): void => {
|
||||
name: 'Jellyfin Recently Added Sync',
|
||||
type: 'process',
|
||||
interval: 'long',
|
||||
cronSchedule: jobs['jellyfin-recently-added-sync'].schedule,
|
||||
job: schedule.scheduleJob(
|
||||
jobs['jellyfin-recently-added-sync'].schedule,
|
||||
() => {
|
||||
@@ -90,6 +94,7 @@ export const startJobs = (): void => {
|
||||
name: 'Jellyfin Full Library Sync',
|
||||
type: 'process',
|
||||
interval: 'long',
|
||||
cronSchedule: jobs['jellyfin-full-sync'].schedule,
|
||||
job: schedule.scheduleJob(jobs['jellyfin-full-sync'].schedule, () => {
|
||||
logger.info('Starting scheduled job: Jellyfin Full Sync', {
|
||||
label: 'Jobs',
|
||||
@@ -107,6 +112,7 @@ export const startJobs = (): void => {
|
||||
name: 'Plex Watchlist Sync',
|
||||
type: 'process',
|
||||
interval: 'long',
|
||||
cronSchedule: jobs['plex-watchlist-sync'].schedule,
|
||||
job: schedule.scheduleJob(jobs['plex-watchlist-sync'].schedule, () => {
|
||||
logger.info('Starting scheduled job: Plex Watchlist Sync', {
|
||||
label: 'Jobs',
|
||||
@@ -121,6 +127,7 @@ export const startJobs = (): void => {
|
||||
name: 'Radarr Scan',
|
||||
type: 'process',
|
||||
interval: 'long',
|
||||
cronSchedule: jobs['radarr-scan'].schedule,
|
||||
job: schedule.scheduleJob(jobs['radarr-scan'].schedule, () => {
|
||||
logger.info('Starting scheduled job: Radarr Scan', { label: 'Jobs' });
|
||||
radarrScanner.run();
|
||||
@@ -135,6 +142,7 @@ export const startJobs = (): void => {
|
||||
name: 'Sonarr Scan',
|
||||
type: 'process',
|
||||
interval: 'long',
|
||||
cronSchedule: jobs['sonarr-scan'].schedule,
|
||||
job: schedule.scheduleJob(jobs['sonarr-scan'].schedule, () => {
|
||||
logger.info('Starting scheduled job: Sonarr Scan', { label: 'Jobs' });
|
||||
sonarrScanner.run();
|
||||
@@ -149,6 +157,7 @@ export const startJobs = (): void => {
|
||||
name: 'Download Sync',
|
||||
type: 'command',
|
||||
interval: 'fixed',
|
||||
cronSchedule: jobs['download-sync'].schedule,
|
||||
job: schedule.scheduleJob(jobs['download-sync'].schedule, () => {
|
||||
logger.debug('Starting scheduled job: Download Sync', {
|
||||
label: 'Jobs',
|
||||
@@ -163,6 +172,7 @@ export const startJobs = (): void => {
|
||||
name: 'Download Sync Reset',
|
||||
type: 'command',
|
||||
interval: 'long',
|
||||
cronSchedule: jobs['download-sync-reset'].schedule,
|
||||
job: schedule.scheduleJob(jobs['download-sync-reset'].schedule, () => {
|
||||
logger.info('Starting scheduled job: Download Sync Reset', {
|
||||
label: 'Jobs',
|
||||
|
||||
@@ -27,7 +27,7 @@ import { getAppVersion } from '@server/utils/appVersion';
|
||||
import { Router } from 'express';
|
||||
import rateLimit from 'express-rate-limit';
|
||||
import fs from 'fs';
|
||||
import { merge, omit, set, sortBy } from 'lodash';
|
||||
import { escapeRegExp, merge, omit, set, sortBy } from 'lodash';
|
||||
import { rescheduleJob } from 'node-schedule';
|
||||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
@@ -454,6 +454,8 @@ settingsRoutes.get(
|
||||
(req, res, next) => {
|
||||
const pageSize = req.query.take ? Number(req.query.take) : 25;
|
||||
const skip = req.query.skip ? Number(req.query.skip) : 0;
|
||||
const search = (req.query.search as string) ?? '';
|
||||
const searchRegexp = new RegExp(escapeRegExp(search), 'i');
|
||||
|
||||
let filter: string[] = [];
|
||||
switch (req.query.filter) {
|
||||
@@ -485,6 +487,22 @@ settingsRoutes.get(
|
||||
'data',
|
||||
];
|
||||
|
||||
const deepValueStrings = (obj: Record<string, unknown>): string[] => {
|
||||
const values = [];
|
||||
|
||||
for (const val of Object.values(obj)) {
|
||||
if (typeof val === 'string') {
|
||||
values.push(val);
|
||||
} else if (typeof val === 'number') {
|
||||
values.push(val.toString());
|
||||
} else if (val !== null && typeof val === 'object') {
|
||||
values.push(...deepValueStrings(val as Record<string, unknown>));
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
try {
|
||||
fs.readFileSync(logFile, 'utf-8')
|
||||
.split('\n')
|
||||
@@ -509,6 +527,19 @@ settingsRoutes.get(
|
||||
});
|
||||
}
|
||||
|
||||
if (req.query.search) {
|
||||
if (
|
||||
// label and data are sometimes undefined
|
||||
!searchRegexp.test(logMessage.label ?? '') &&
|
||||
!searchRegexp.test(logMessage.message) &&
|
||||
!deepValueStrings(logMessage.data ?? {}).some((val) =>
|
||||
searchRegexp.test(val)
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
logs.push(logMessage);
|
||||
});
|
||||
|
||||
@@ -543,6 +574,7 @@ settingsRoutes.get('/jobs', (_req, res) => {
|
||||
name: job.name,
|
||||
type: job.type,
|
||||
interval: job.interval,
|
||||
cronSchedule: job.cronSchedule,
|
||||
nextExecutionTime: job.job.nextInvocation(),
|
||||
running: job.running ? job.running() : false,
|
||||
}))
|
||||
@@ -563,6 +595,7 @@ settingsRoutes.post<{ jobId: string }>('/jobs/:jobId/run', (req, res, next) => {
|
||||
name: scheduledJob.name,
|
||||
type: scheduledJob.type,
|
||||
interval: scheduledJob.interval,
|
||||
cronSchedule: scheduledJob.cronSchedule,
|
||||
nextExecutionTime: scheduledJob.job.nextInvocation(),
|
||||
running: scheduledJob.running ? scheduledJob.running() : false,
|
||||
});
|
||||
@@ -588,6 +621,7 @@ settingsRoutes.post<{ jobId: string }>(
|
||||
name: scheduledJob.name,
|
||||
type: scheduledJob.type,
|
||||
interval: scheduledJob.interval,
|
||||
cronSchedule: scheduledJob.cronSchedule,
|
||||
nextExecutionTime: scheduledJob.job.nextInvocation(),
|
||||
running: scheduledJob.running ? scheduledJob.running() : false,
|
||||
});
|
||||
@@ -612,11 +646,14 @@ settingsRoutes.post<{ jobId: string }>(
|
||||
settings.jobs[scheduledJob.id].schedule = req.body.schedule;
|
||||
settings.save();
|
||||
|
||||
scheduledJob.cronSchedule = req.body.schedule;
|
||||
|
||||
return res.status(200).json({
|
||||
id: scheduledJob.id,
|
||||
name: scheduledJob.name,
|
||||
type: scheduledJob.type,
|
||||
interval: scheduledJob.interval,
|
||||
cronSchedule: scheduledJob.cronSchedule,
|
||||
nextExecutionTime: scheduledJob.job.nextInvocation(),
|
||||
running: scheduledJob.running ? scheduledJob.running() : false,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import SearchInput from '@app/components/Layout/SearchInput';
|
||||
import Sidebar from '@app/components/Layout/Sidebar';
|
||||
import UserDropdown from '@app/components/Layout/UserDropdown';
|
||||
import PullToRefresh from '@app/components/PullToRefresh';
|
||||
import type { AvailableLocale } from '@app/context/LanguageContext';
|
||||
import useLocale from '@app/hooks/useLocale';
|
||||
import useSettings from '@app/hooks/useSettings';
|
||||
@@ -58,6 +59,7 @@ const Layout = ({ children }: LayoutProps) => {
|
||||
<Sidebar open={isSidebarOpen} setClosed={() => setSidebarOpen(false)} />
|
||||
|
||||
<div className="relative mb-16 flex w-0 min-w-0 flex-1 flex-col lg:ml-64">
|
||||
<PullToRefresh />
|
||||
<div
|
||||
className={`searchbar fixed left-0 right-0 top-0 z-10 flex flex-shrink-0 bg-opacity-80 transition duration-300 ${
|
||||
isScrolled ? 'bg-gray-700' : 'bg-transparent'
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ServerIcon, ViewListIcon } from '@heroicons/react/outline';
|
||||
import { CheckCircleIcon, DocumentRemoveIcon } from '@heroicons/react/solid';
|
||||
import { IssueStatus } from '@server/constants/issue';
|
||||
import { MediaRequestStatus, MediaStatus } from '@server/constants/media';
|
||||
import { MediaServerType } from '@server/constants/server';
|
||||
import type { MediaWatchDataResponse } from '@server/interfaces/api/mediaInterfaces';
|
||||
import type { MovieDetails } from '@server/models/Movie';
|
||||
import type { TvDetails } from '@server/models/Tv';
|
||||
|
||||
36
src/components/PullToRefresh/index.tsx
Normal file
36
src/components/PullToRefresh/index.tsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import { RefreshIcon } from '@heroicons/react/outline';
|
||||
import Router from 'next/router';
|
||||
import PR from 'pulltorefreshjs';
|
||||
import { useEffect } from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
|
||||
const PullToRefresh: React.FC = () => {
|
||||
useEffect(() => {
|
||||
PR.init({
|
||||
mainElement: '#pull-to-refresh',
|
||||
onRefresh() {
|
||||
Router.reload();
|
||||
},
|
||||
iconArrow: ReactDOMServer.renderToString(
|
||||
<RefreshIcon className="z-50 m-auto h-9 w-9 rounded-full border-4 border-gray-800 bg-gray-800 text-indigo-500 ring-1 ring-gray-700" />
|
||||
),
|
||||
iconRefreshing: ReactDOMServer.renderToString(
|
||||
<RefreshIcon
|
||||
className="z-50 m-auto h-9 w-9 animate-spin rounded-full border-4 border-gray-800 bg-gray-800 text-indigo-500 ring-1 ring-gray-700"
|
||||
style={{ animationDirection: 'reverse' }}
|
||||
/>
|
||||
),
|
||||
instructionsPullToRefresh: ReactDOMServer.renderToString(<div />),
|
||||
instructionsReleaseToRefresh: ReactDOMServer.renderToString(<div />),
|
||||
instructionsRefreshing: ReactDOMServer.renderToString(<div />),
|
||||
distReload: 55,
|
||||
});
|
||||
return () => {
|
||||
PR.destroyAll();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <div id="pull-to-refresh"></div>;
|
||||
};
|
||||
|
||||
export default PullToRefresh;
|
||||
@@ -5,6 +5,7 @@ import LoadingSpinner from '@app/components/Common/LoadingSpinner';
|
||||
import Modal from '@app/components/Common/Modal';
|
||||
import PageTitle from '@app/components/Common/PageTitle';
|
||||
import Table from '@app/components/Common/Table';
|
||||
import useLocale from '@app/hooks/useLocale';
|
||||
import useSettings from '@app/hooks/useSettings';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import { formatBytes } from '@app/utils/numberHelpers';
|
||||
@@ -15,7 +16,8 @@ import { MediaServerType } from '@server/constants/server';
|
||||
import type { CacheItem } from '@server/interfaces/api/settingsInterfaces';
|
||||
import type { JobId } from '@server/lib/settings';
|
||||
import axios from 'axios';
|
||||
import { Fragment, useState } from 'react';
|
||||
import cronstrue from 'cronstrue/i18n';
|
||||
import { Fragment, useReducer, useState } from 'react';
|
||||
import type { MessageDescriptor } from 'react-intl';
|
||||
import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
@@ -59,7 +61,8 @@ const messages: { [messageName: string]: MessageDescriptor } = defineMessages({
|
||||
editJobSchedule: 'Modify Job',
|
||||
jobScheduleEditSaved: 'Job edited successfully!',
|
||||
jobScheduleEditFailed: 'Something went wrong while saving the job.',
|
||||
editJobSchedulePrompt: 'Frequency',
|
||||
editJobScheduleCurrent: 'Current Frequency',
|
||||
editJobSchedulePrompt: 'New Frequency',
|
||||
editJobScheduleSelectorHours:
|
||||
'Every {jobScheduleHours, plural, one {hour} other {{jobScheduleHours} hours}}',
|
||||
editJobScheduleSelectorMinutes:
|
||||
@@ -71,12 +74,56 @@ interface Job {
|
||||
name: string;
|
||||
type: 'process' | 'command';
|
||||
interval: 'short' | 'long' | 'fixed';
|
||||
cronSchedule: string;
|
||||
nextExecutionTime: string;
|
||||
running: boolean;
|
||||
}
|
||||
|
||||
type JobModalState = {
|
||||
isOpen?: boolean;
|
||||
job?: Job;
|
||||
scheduleHours: number;
|
||||
scheduleMinutes: number;
|
||||
};
|
||||
|
||||
type JobModalAction =
|
||||
| { type: 'set'; hours?: number; minutes?: number }
|
||||
| {
|
||||
type: 'close';
|
||||
}
|
||||
| { type: 'open'; job?: Job };
|
||||
|
||||
const jobModalReducer = (
|
||||
state: JobModalState,
|
||||
action: JobModalAction
|
||||
): JobModalState => {
|
||||
switch (action.type) {
|
||||
case 'close':
|
||||
return {
|
||||
...state,
|
||||
isOpen: false,
|
||||
};
|
||||
|
||||
case 'open':
|
||||
return {
|
||||
isOpen: true,
|
||||
job: action.job,
|
||||
scheduleHours: 1,
|
||||
scheduleMinutes: 5,
|
||||
};
|
||||
|
||||
case 'set':
|
||||
return {
|
||||
...state,
|
||||
scheduleHours: action.hours ?? state.scheduleHours,
|
||||
scheduleMinutes: action.minutes ?? state.scheduleMinutes,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const SettingsJobs = () => {
|
||||
const intl = useIntl();
|
||||
const { locale } = useLocale();
|
||||
const { addToast } = useToasts();
|
||||
const {
|
||||
data,
|
||||
@@ -92,15 +139,12 @@ const SettingsJobs = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const [jobEditModal, setJobEditModal] = useState<{
|
||||
isOpen: boolean;
|
||||
job?: Job;
|
||||
}>({
|
||||
const [jobModalState, dispatch] = useReducer(jobModalReducer, {
|
||||
isOpen: false,
|
||||
scheduleHours: 1,
|
||||
scheduleMinutes: 5,
|
||||
});
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
const [jobScheduleMinutes, setJobScheduleMinutes] = useState(5);
|
||||
const [jobScheduleHours, setJobScheduleHours] = useState(1);
|
||||
const settings = useSettings();
|
||||
|
||||
if (!data && !error) {
|
||||
@@ -151,10 +195,10 @@ const SettingsJobs = () => {
|
||||
const jobScheduleCron = ['0', '0', '*', '*', '*', '*'];
|
||||
|
||||
try {
|
||||
if (jobEditModal.job?.interval === 'short') {
|
||||
jobScheduleCron[1] = `*/${jobScheduleMinutes}`;
|
||||
} else if (jobEditModal.job?.interval === 'long') {
|
||||
jobScheduleCron[2] = `*/${jobScheduleHours}`;
|
||||
if (jobModalState.job?.interval === 'short') {
|
||||
jobScheduleCron[1] = `*/${jobModalState.scheduleMinutes}`;
|
||||
} else if (jobModalState.job?.interval === 'long') {
|
||||
jobScheduleCron[2] = `*/${jobModalState.scheduleHours}`;
|
||||
} else {
|
||||
// jobs with interval: fixed should not be editable
|
||||
throw new Error();
|
||||
@@ -162,16 +206,18 @@ const SettingsJobs = () => {
|
||||
|
||||
setIsSaving(true);
|
||||
await axios.post(
|
||||
`/api/v1/settings/jobs/${jobEditModal.job?.id}/schedule`,
|
||||
`/api/v1/settings/jobs/${jobModalState.job.id}/schedule`,
|
||||
{
|
||||
schedule: jobScheduleCron.join(' '),
|
||||
}
|
||||
);
|
||||
|
||||
addToast(intl.formatMessage(messages.jobScheduleEditSaved), {
|
||||
appearance: 'success',
|
||||
autoDismiss: true,
|
||||
});
|
||||
setJobEditModal({ isOpen: false });
|
||||
|
||||
dispatch({ type: 'close' });
|
||||
revalidate();
|
||||
} catch (e) {
|
||||
addToast(intl.formatMessage(messages.jobScheduleEditFailed), {
|
||||
@@ -199,7 +245,7 @@ const SettingsJobs = () => {
|
||||
leave="opacity-100 transition duration-300"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
show={jobEditModal.isOpen}
|
||||
show={jobModalState.isOpen}
|
||||
>
|
||||
<Modal
|
||||
title={intl.formatMessage(messages.editJobSchedule)}
|
||||
@@ -208,24 +254,43 @@ const SettingsJobs = () => {
|
||||
? intl.formatMessage(globalMessages.saving)
|
||||
: intl.formatMessage(globalMessages.save)
|
||||
}
|
||||
onCancel={() => setJobEditModal({ isOpen: false })}
|
||||
onCancel={() => dispatch({ type: 'close' })}
|
||||
okDisabled={isSaving}
|
||||
onOk={() => scheduleJob()}
|
||||
>
|
||||
<div className="section">
|
||||
<form>
|
||||
<div className="form-row pb-6">
|
||||
<form className="mb-6">
|
||||
<div className="form-row">
|
||||
<label className="text-label">
|
||||
{intl.formatMessage(messages.editJobScheduleCurrent)}
|
||||
</label>
|
||||
<div className="form-input-area mt-2 mb-1">
|
||||
<div>
|
||||
{jobModalState.job &&
|
||||
cronstrue.toString(jobModalState.job.cronSchedule, {
|
||||
locale,
|
||||
})}
|
||||
</div>
|
||||
<div className="text-sm text-gray-500">
|
||||
{jobModalState.job?.cronSchedule}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="jobSchedule" className="text-label">
|
||||
{intl.formatMessage(messages.editJobSchedulePrompt)}
|
||||
</label>
|
||||
<div className="form-input-area">
|
||||
{jobEditModal.job?.interval === 'short' ? (
|
||||
{jobModalState.job?.interval === 'short' ? (
|
||||
<select
|
||||
name="jobScheduleMinutes"
|
||||
className="inline"
|
||||
value={jobScheduleMinutes}
|
||||
value={jobModalState.scheduleMinutes}
|
||||
onChange={(e) =>
|
||||
setJobScheduleMinutes(Number(e.target.value))
|
||||
dispatch({
|
||||
type: 'set',
|
||||
minutes: Number(e.target.value),
|
||||
})
|
||||
}
|
||||
>
|
||||
{[5, 10, 15, 20, 30, 60].map((v) => (
|
||||
@@ -243,9 +308,12 @@ const SettingsJobs = () => {
|
||||
<select
|
||||
name="jobScheduleHours"
|
||||
className="inline"
|
||||
value={jobScheduleHours}
|
||||
value={jobModalState.scheduleHours}
|
||||
onChange={(e) =>
|
||||
setJobScheduleHours(Number(e.target.value))
|
||||
dispatch({
|
||||
type: 'set',
|
||||
hours: Number(e.target.value),
|
||||
})
|
||||
}
|
||||
>
|
||||
{[1, 2, 3, 4, 6, 8, 12, 24, 48, 72].map((v) => (
|
||||
@@ -324,9 +392,7 @@ const SettingsJobs = () => {
|
||||
<Button
|
||||
className="mr-2"
|
||||
buttonType="warning"
|
||||
onClick={() =>
|
||||
setJobEditModal({ isOpen: true, job: job })
|
||||
}
|
||||
onClick={() => dispatch({ type: 'open', job })}
|
||||
>
|
||||
<PencilIcon />
|
||||
<span>{intl.formatMessage(globalMessages.edit)}</span>
|
||||
|
||||
@@ -5,6 +5,7 @@ import Modal from '@app/components/Common/Modal';
|
||||
import PageTitle from '@app/components/Common/PageTitle';
|
||||
import Table from '@app/components/Common/Table';
|
||||
import Tooltip from '@app/components/Common/Tooltip';
|
||||
import useDebouncedState from '@app/hooks/useDebouncedState';
|
||||
import { useUpdateQueryParams } from '@app/hooks/useUpdateQueryParams';
|
||||
import globalMessages from '@app/i18n/globalMessages';
|
||||
import Error from '@app/pages/_error';
|
||||
@@ -17,6 +18,7 @@ import {
|
||||
FilterIcon,
|
||||
PauseIcon,
|
||||
PlayIcon,
|
||||
SearchIcon,
|
||||
} from '@heroicons/react/solid';
|
||||
import type {
|
||||
LogMessage,
|
||||
@@ -59,6 +61,8 @@ const SettingsLogs = () => {
|
||||
const { addToast } = useToasts();
|
||||
const [currentFilter, setCurrentFilter] = useState<Filter>('debug');
|
||||
const [currentPageSize, setCurrentPageSize] = useState(25);
|
||||
const [searchFilter, debouncedSearchFilter, setSearchFilter] =
|
||||
useDebouncedState('');
|
||||
const [refreshInterval, setRefreshInterval] = useState(5000);
|
||||
const [activeLog, setActiveLog] = useState<{
|
||||
isOpen: boolean;
|
||||
@@ -76,7 +80,9 @@ const SettingsLogs = () => {
|
||||
const { data, error } = useSWR<LogsResultsResponse>(
|
||||
`/api/v1/settings/logs?take=${currentPageSize}&skip=${
|
||||
pageIndex * currentPageSize
|
||||
}&filter=${currentFilter}`,
|
||||
}&filter=${currentFilter}${
|
||||
debouncedSearchFilter ? `&search=${debouncedSearchFilter}` : ''
|
||||
}`,
|
||||
{
|
||||
refreshInterval: refreshInterval,
|
||||
revalidateOnFocus: false,
|
||||
@@ -118,15 +124,13 @@ const SettingsLogs = () => {
|
||||
});
|
||||
};
|
||||
|
||||
if (!data && !error) {
|
||||
return <LoadingSpinner />;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
// check if there's no data and no errors in the table
|
||||
// so as to show a spinner inside the table and not refresh the whole component
|
||||
if (!data && error) {
|
||||
return <Error statusCode={500} />;
|
||||
}
|
||||
|
||||
const hasNextPage = data.pageInfo.pages > pageIndex + 1;
|
||||
const hasNextPage = data?.pageInfo.pages ?? 0 > pageIndex + 1;
|
||||
const hasPrevPage = pageIndex > 0;
|
||||
|
||||
return (
|
||||
@@ -245,10 +249,21 @@ const SettingsLogs = () => {
|
||||
appDataPath: appData ? appData.appDataPath : '/app/config',
|
||||
})}
|
||||
</p>
|
||||
<div className="mt-2 flex flex-grow flex-row sm:flex-grow-0 sm:justify-end">
|
||||
<div className="mt-2 flex flex-grow flex-col sm:flex-grow-0 sm:flex-row sm:justify-end">
|
||||
<div className="mb-2 flex flex-grow sm:mb-0 sm:mr-2 md:flex-grow-0">
|
||||
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-sm text-gray-100">
|
||||
<SearchIcon className="h-6 w-6" />
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
className="rounded-r-only"
|
||||
value={searchFilter}
|
||||
onChange={(e) => setSearchFilter(e.target.value as string)}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-2 flex flex-1 flex-row justify-between sm:mb-0 sm:flex-none">
|
||||
<Button
|
||||
className="mr-2 w-full flex-grow"
|
||||
className="mr-2 flex flex-grow"
|
||||
buttonType={refreshInterval ? 'default' : 'primary'}
|
||||
onClick={() => toggleLogs()}
|
||||
>
|
||||
@@ -259,8 +274,7 @@ const SettingsLogs = () => {
|
||||
)}
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
<div className="mb-2 flex flex-1 sm:mb-0 sm:flex-none">
|
||||
<div className="flex flex-grow">
|
||||
<span className="inline-flex cursor-default items-center rounded-l-md border border-r-0 border-gray-500 bg-gray-800 px-3 text-sm text-gray-100">
|
||||
<FilterIcon className="h-6 w-6" />
|
||||
</span>
|
||||
@@ -289,6 +303,7 @@ const SettingsLogs = () => {
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -300,7 +315,14 @@ const SettingsLogs = () => {
|
||||
</tr>
|
||||
</thead>
|
||||
<Table.TBody>
|
||||
{data.results.map((row: LogMessage, index: number) => {
|
||||
{!data ? (
|
||||
<tr>
|
||||
<Table.TD colSpan={5} noPadding>
|
||||
<LoadingSpinner />
|
||||
</Table.TD>
|
||||
</tr>
|
||||
) : (
|
||||
data.results.map((row: LogMessage, index: number) => {
|
||||
return (
|
||||
<tr key={`log-list-${index}`}>
|
||||
<Table.TD className="text-gray-300">
|
||||
@@ -338,8 +360,8 @@ const SettingsLogs = () => {
|
||||
content={intl.formatMessage(messages.viewdetails)}
|
||||
>
|
||||
<Button
|
||||
buttonType="primary"
|
||||
buttonSize="sm"
|
||||
buttonType="primary"
|
||||
onClick={() =>
|
||||
setActiveLog({ log: row, isOpen: true })
|
||||
}
|
||||
@@ -364,9 +386,10 @@ const SettingsLogs = () => {
|
||||
</Table.TD>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
})
|
||||
)}
|
||||
|
||||
{data.results.length === 0 && (
|
||||
{data?.results.length === 0 && (
|
||||
<tr className="relative h-24 p-2 text-white">
|
||||
<Table.TD colSpan={5} noPadding>
|
||||
<div className="flex w-screen flex-col items-center justify-center p-6 md:w-full">
|
||||
@@ -396,15 +419,15 @@ const SettingsLogs = () => {
|
||||
>
|
||||
<div className="hidden lg:flex lg:flex-1">
|
||||
<p className="text-sm">
|
||||
{data.results.length > 0 &&
|
||||
{(data?.results.length ?? 0) > 0 &&
|
||||
intl.formatMessage(globalMessages.showingresults, {
|
||||
from: pageIndex * currentPageSize + 1,
|
||||
to:
|
||||
data.results.length < currentPageSize
|
||||
data?.results.length ?? 0 < currentPageSize
|
||||
? pageIndex * currentPageSize +
|
||||
data.results.length
|
||||
(data?.results.length ?? 0)
|
||||
: (pageIndex + 1) * currentPageSize,
|
||||
total: data.pageInfo.results,
|
||||
total: data?.pageInfo.results ?? 0,
|
||||
strong: (msg: React.ReactNode) => (
|
||||
<span className="font-medium">{msg}</span>
|
||||
),
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
"components.Settings.SettingsUsers.userSettings": "Uživatelské nastavení",
|
||||
"components.Settings.SettingsUsers.defaultPermissions": "Výchozí oprávnění",
|
||||
"components.Settings.SettingsJobsCache.unknownJob": "Neznámá úloha",
|
||||
"components.Settings.SettingsJobsCache.sonarr-scan": "Sonarr Sken",
|
||||
"components.Settings.SettingsJobsCache.sonarr-scan": "Sonarr sken",
|
||||
"components.Settings.SettingsJobsCache.runnow": "Spustit nyní",
|
||||
"components.Settings.SettingsJobsCache.radarr-scan": "Radarr Sken",
|
||||
"components.Settings.SettingsJobsCache.radarr-scan": "Radarr sken",
|
||||
"components.Settings.SettingsJobsCache.jobstarted": "{jobname} zahájeno.",
|
||||
"components.Settings.SettingsJobsCache.jobname": "Název úlohy",
|
||||
"components.Settings.SettingsJobsCache.jobcancelled": "{jobname} zrušeno.",
|
||||
@@ -39,12 +39,12 @@
|
||||
"components.Settings.SettingsAbout.totalrequests": "Celkový počet žádostí",
|
||||
"components.Settings.SettingsAbout.totalmedia": "Celkový počet médií",
|
||||
"components.Settings.SettingsAbout.timezone": "Časové pásmo",
|
||||
"components.Settings.SettingsAbout.supportoverseerr": "Podpořte Jellyseerr",
|
||||
"components.Settings.SettingsAbout.overseerrinformation": "Jellyseerr Informace",
|
||||
"components.Settings.SettingsAbout.supportoverseerr": "Podpořte Overseerr",
|
||||
"components.Settings.SettingsAbout.overseerrinformation": "O Jellyseerr",
|
||||
"components.Settings.SettingsAbout.githubdiscussions": "Diskuze na GitHubu",
|
||||
"components.Settings.SettingsAbout.Releases.viewchangelog": "Zobrazit seznam změn",
|
||||
"components.Settings.SettingsAbout.Releases.versionChangelog": "Seznam změn",
|
||||
"components.Settings.SettingsAbout.Releases.currentversion": "Aktuální verze",
|
||||
"components.Settings.SettingsAbout.Releases.versionChangelog": "{version} Seznam změn",
|
||||
"components.Settings.SettingsAbout.Releases.currentversion": "Aktuální",
|
||||
"components.Settings.RadarrModal.syncEnabled": "Povolit skenování",
|
||||
"components.Settings.RadarrModal.ssl": "Použít SSL",
|
||||
"components.Settings.RadarrModal.servername": "Název serveru",
|
||||
@@ -85,7 +85,7 @@
|
||||
"components.Settings.Notifications.NotificationsLunaSea.webhookUrl": "Webhook URL",
|
||||
"components.Settings.Notifications.NotificationsLunaSea.profileName": "Jméno profilu",
|
||||
"components.Settings.Notifications.NotificationsLunaSea.agentenabled": "Povolit agenta",
|
||||
"components.Search.searchresults": "Výsledek vyhledávání",
|
||||
"components.Search.searchresults": "Výsledky vyhledávání",
|
||||
"components.ResetPassword.passwordreset": "Obnovení hesla",
|
||||
"components.ResetPassword.email": "E-mailová adresa",
|
||||
"components.ResetPassword.confirmpassword": "Potvrďte heslo",
|
||||
@@ -105,7 +105,7 @@
|
||||
"components.RequestModal.AdvancedRequester.destinationserver": "Cílový server",
|
||||
"components.RequestModal.AdvancedRequester.default": "{name} (výchozí)",
|
||||
"components.RequestList.sortModified": "Naposledy změněno",
|
||||
"components.RequestList.sortAdded": "Datum žádosti",
|
||||
"components.RequestList.sortAdded": "Nejnovější",
|
||||
"components.RequestList.RequestItem.editrequest": "Upravit žádost",
|
||||
"components.RequestList.RequestItem.deleterequest": "Odstranit žádost",
|
||||
"components.RequestList.RequestItem.cancelRequest": "Zrušit žádost",
|
||||
@@ -128,8 +128,8 @@
|
||||
"components.PermissionEdit.users": "Spravovat uživatele",
|
||||
"components.PermissionEdit.settings": "Spravovat nastavení",
|
||||
"components.PermissionEdit.requestTv": "Žádat seriály",
|
||||
"components.PermissionEdit.requestMovies": "Žádat filmy",
|
||||
"components.PermissionEdit.request4k": "Žádosti ve 4K",
|
||||
"components.PermissionEdit.requestMovies": "Vyžádat filmy",
|
||||
"components.PermissionEdit.request4k": "Vyžádat ve 4K",
|
||||
"components.PermissionEdit.managerequests": "Spravovat žádosti",
|
||||
"components.PermissionEdit.autoapproveSeries": "Automaticky schvalovat seriály",
|
||||
"components.PermissionEdit.autoapproveMovies": "Automaticky schvalovat filmy",
|
||||
@@ -234,7 +234,7 @@
|
||||
"components.NotificationTypeSelector.usermediaapprovedDescription": "Získat upozornění na schválení vašich žádostí o média.",
|
||||
"components.NotificationTypeSelector.usermediaAutoApprovedDescription": "Získat upozornění, když ostatní uživatelé zadají nové požadavky na média, která jsou automaticky schválena.",
|
||||
"components.NotificationTypeSelector.mediarequestedDescription": "Odeslat oznámení, když uživatelé zažádají o média vyžadující schválení.",
|
||||
"components.MovieDetails.streamingproviders": "Aktuálně streamovatelné zde",
|
||||
"components.MovieDetails.streamingproviders": "Aktuálně streamovatelné na",
|
||||
"pages.serviceunavailable": "Služba není k dispozici",
|
||||
"pages.returnHome": "Vrátit se domů",
|
||||
"pages.pagenotfound": "Stránka nebyla nalezena",
|
||||
@@ -469,7 +469,7 @@
|
||||
"components.IssueDetails.IssueComment.edit": "Upravit komentář",
|
||||
"components.IssueDetails.allseasons": "Všechny série",
|
||||
"components.IssueDetails.closeissue": "Uzavřít problém",
|
||||
"components.ManageSlideOver.downloadstatus": "Stav stahování",
|
||||
"components.ManageSlideOver.downloadstatus": "Stahování",
|
||||
"components.NotificationTypeSelector.issueresolved": "Problém vyřešen",
|
||||
"components.RequestList.RequestItem.modifieduserdate": "{date} od {user}",
|
||||
"components.RequestList.showallrequests": "Zobrazit všechny žádosti",
|
||||
@@ -710,7 +710,7 @@
|
||||
"components.Settings.SonarrModal.toastSonarrTestSuccess": "Připojení Sonarr úspěšně navázáno!",
|
||||
"components.Settings.SonarrModal.validationBaseUrlLeadingSlash": "Základní adresa URL musí mít na začátku lomítko",
|
||||
"components.Settings.cacheImages": "Povolení ukládání obrázků do mezipaměti",
|
||||
"components.Settings.cacheImagesTip": "Optimalizovat a ukládat všechny obrázky lokálně (spotřebovává značné množství místa na disku)",
|
||||
"components.Settings.cacheImagesTip": "Ukládat do mezipaměti a poskytovat optimalizované obrazy (vyžaduje značné množství místa na disku)",
|
||||
"components.Settings.manualscanDescription": "Obvykle se provádí pouze jednou za 24 hodin. Jellyseerr bude kontrolovat nedávno přidané položky vašeho serveru Plex agresivněji. Pokud Plex konfigurujete poprvé, doporučujeme provést jednorázovou úplnou ruční kontrolu knihovny!",
|
||||
"components.Settings.originallanguageTip": "Filtrování obsahu podle původního jazyka",
|
||||
"components.Settings.urlBase": "Základní adresa URL",
|
||||
@@ -894,11 +894,11 @@
|
||||
"components.Settings.Notifications.NotificationsPushover.userToken": "Klíč uživatele nebo skupiny",
|
||||
"components.RequestCard.failedretry": "Při opakovaném pokusu o zadání požadavku se něco pokazilo.",
|
||||
"components.Settings.Notifications.NotificationsLunaSea.profileNameTip": "Vyžaduje se pouze v případě, že nepoužíváte profil <code>default</code>",
|
||||
"components.RequestCard.mediaerror": "Související titul pro tuto žádost již není k dispozici.",
|
||||
"components.Settings.trustProxyTip": "Povolit Jellyseerr správně registrovat IP adresy klientů za proxy serverem (aby se změny projevily, musí být Jellyseerr znovu načten)",
|
||||
"components.RequestList.RequestItem.mediaerror": "Související titul pro tuto žádost již není k dispozici.",
|
||||
"components.RequestCard.mediaerror": "{mediaType} Nenalezeno",
|
||||
"components.Settings.trustProxyTip": "Povolit Jellyseerr správně registrovat IP adresy klientů za proxy serverem",
|
||||
"components.RequestList.RequestItem.mediaerror": "{mediaType} Nenalezeno",
|
||||
"components.RequestModal.QuotaDisplay.allowedRequests": "Můžete požádat o <strong>{limit}</strong> {type} každé <strong>{days}</strong> dny.",
|
||||
"components.RequestModal.SearchByNameModal.notvdbiddescription": "Váš požadavek jsme nemohli automaticky porovnat. Vyberte prosím správnou shodu ze seznamu níže.",
|
||||
"components.RequestModal.SearchByNameModal.notvdbiddescription": "Tuto sérii jsme nemohli automaticky spárovat. Níže prosím vyberte správnou shodu.",
|
||||
"components.Settings.RadarrModal.validationBaseUrlLeadingSlash": "Základ URL musí mít na začátku lomítko",
|
||||
"components.Settings.SettingsJobsCache.plex-recently-added-scan": "Plex Nedávno přidané skenování",
|
||||
"components.Settings.SettingsLogs.logsDescription": "Tyto protokoly můžete také zobrazit přímo prostřednictvím <code>stdout</code> nebo v <code>{appDataPath}/logs/overseerr.log</code>.",
|
||||
@@ -1036,5 +1036,91 @@
|
||||
"components.RequestButton.decline4krequests": "Odmítnout {requestCount, plural, one {4K žádost} other {{requestCount} 4K žádosti}}",
|
||||
"components.RequestButton.declinerequests": "Odmítnout {requestCount, plural, one {Žádost} other {{requestCount} Žádosti}}",
|
||||
"components.RequestModal.requestmovies": "Požádat {count} {count, plural, one {film} other {filmy}}",
|
||||
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "{jobScheduleMinutes, plural, one {Každou minutu} few {Každé {jobScheduleMinutes} minuty} other {Každých {jobScheduleMinutes} minut}}"
|
||||
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "{jobScheduleMinutes, plural, one {Každou minutu} few {Každé {jobScheduleMinutes} minuty} other {Každých {jobScheduleMinutes} minut}}",
|
||||
"components.MovieDetails.digitalrelease": "Digitální vydání",
|
||||
"components.Discover.DiscoverWatchlist.discoverwatchlist": "Váš Plex Watchlist",
|
||||
"components.MovieDetails.physicalrelease": "Fyzické vydání",
|
||||
"components.MovieDetails.managemovie": "Spravovat film",
|
||||
"components.AirDateBadge.airsrelative": "Vysíla se {relativeTime}",
|
||||
"components.Layout.UserDropdown.MiniQuotaDisplay.movierequests": "Žádosti o filmy",
|
||||
"components.MovieDetails.rtaudiencescore": "Skóre publika Rotten Tomatoes",
|
||||
"components.MovieDetails.rtcriticsscore": "Rotten Tomatoes Tomatometer",
|
||||
"components.Layout.UserDropdown.MiniQuotaDisplay.seriesrequests": "Žádosti o seriály",
|
||||
"components.AirDateBadge.airedrelative": "Odvysílano {relativeTime}",
|
||||
"components.Layout.UserDropdown.requests": "Žádosti",
|
||||
"components.MovieDetails.reportissue": "Nahlásit problém",
|
||||
"components.StatusChecker.restartRequired": "Je vyžadován restart serveru",
|
||||
"components.PermissionEdit.viewrecent": "Zobrazit naposledy přidané",
|
||||
"components.StatusChecker.appUpdated": "{applicationTitle} Aktualizováno",
|
||||
"components.StatusChecker.appUpdatedDescription": "Chcete-li aplikaci znovu načíst, klikněte na tlačítko níže.",
|
||||
"components.StatusChecker.restartRequiredDescription": "Chcete-li použít aktualizovaná nastavení, restartujte server.",
|
||||
"components.RequestCard.tmdbid": "TMDB ID",
|
||||
"components.RequestList.RequestItem.tmdbid": "TMDB ID",
|
||||
"components.TitleCard.tmdbid": "TMDB ID",
|
||||
"components.TitleCard.tvdbid": "TheTVDB ID",
|
||||
"components.RequestCard.tvdbid": "TheTVDB ID",
|
||||
"components.RequestList.RequestItem.tvdbid": "TheTVDB ID",
|
||||
"components.PermissionEdit.autorequestMovies": "Automatické vyžádání filmů",
|
||||
"components.PermissionEdit.autorequestMoviesDescription": "Udělte oprávnění k automatickému odesílání žádostí o filmy v jiném rozlišení než 4K prostřednictvím Plex Watchlistu.",
|
||||
"components.PermissionEdit.viewrecentDescription": "Udělte oprávnění k zobrazení seznamu nedávno přidaných médií.",
|
||||
"components.Settings.restartrequiredTooltip": "Aby se změny tohoto nastavení projevily, musí být Overserr restartován",
|
||||
"components.StatusChecker.reloadApp": "Znovu načíst {applicationTitle}",
|
||||
"components.TitleCard.cleardata": "Vyčistit data",
|
||||
"components.TitleCard.mediaerror": "{mediaType} Nenalezeno",
|
||||
"components.PermissionEdit.autorequestDescription": "Udělte oprávnění k automatickému odesílání žádostí o média jiná než 4K prostřednictvím seznamu Plex Watchlist.",
|
||||
"components.PermissionEdit.autorequest": "Automatická žádost",
|
||||
"components.PermissionEdit.autorequestSeries": "Automaticky vyžádat seriál",
|
||||
"components.PermissionEdit.viewwatchlists": "Zobrazit Plex Watchilisty",
|
||||
"components.Settings.advancedTooltip": "Nesprávná konfigurace tohoto nastavení může vést k narušení funkčnosti",
|
||||
"components.Settings.deleteServer": "Smazat server {serverType}",
|
||||
"components.Settings.experimentalTooltip": "Povolení tohoto nastavení může vést k neočekávanému chování aplikace",
|
||||
"components.Settings.SettingsLogs.viewdetails": "Zobrazit podrobnosti",
|
||||
"components.PermissionEdit.autorequestSeriesDescription": "Udělte oprávnění k automatickému odesílání žádostí o seriály jiné než 4K prostřednictvím Plex Watchlist.",
|
||||
"components.RequestBlock.approve": "Schválit žádost",
|
||||
"components.RequestBlock.decline": "Odmítnout požadavek",
|
||||
"components.RequestBlock.lastmodifiedby": "Naposledy změněno od",
|
||||
"components.RequestBlock.requestdate": "Datum požadavku",
|
||||
"components.RequestBlock.requestedby": "Vyžádáno od",
|
||||
"components.RequestCard.approverequest": "Schválit žádost",
|
||||
"components.RequestCard.cancelrequest": "Zrušit žádost",
|
||||
"components.RequestCard.declinerequest": "Odmítnout požadavek",
|
||||
"components.Settings.SettingsJobsCache.plex-watchlist-sync": "Plex Watchlist synchronizace",
|
||||
"components.StatusBadge.managemedia": "Spravovat {mediaType}",
|
||||
"components.StatusBadge.openinarr": "Otevřít v {arr}",
|
||||
"components.StatusBadge.playonplex": "Přehrávání cez Plex",
|
||||
"components.TvDetails.manageseries": "Spravovat sérii",
|
||||
"components.RequestBlock.delete": "Smazat požadavek",
|
||||
"components.RequestBlock.edit": "Upravit požadavek",
|
||||
"components.RequestCard.editrequest": "Upravit požadavek",
|
||||
"components.RequestModal.SearchByNameModal.nomatches": "Pro tuto sérii jsme nenašli shodu.",
|
||||
"components.RequestModal.requestcollection4ktitle": "Vyžádejte si kolekci ve 4K",
|
||||
"components.RequestModal.requestcollectiontitle": "Vyžádat kolekci",
|
||||
"components.RequestModal.requestmovie4ktitle": "Vyžádejte si film ve 4K",
|
||||
"components.RequestModal.requestmovietitle": "Vyžádat si film",
|
||||
"components.RequestModal.requestseries4ktitle": "Žádost o sérii ve 4K",
|
||||
"components.RequestModal.requestseriestitle": "Vyžádat sérii",
|
||||
"components.TvDetails.episodeCount": "{episodeCount, plural, one {# Epizoda} other {# Epizody}}",
|
||||
"components.NotificationTypeSelector.mediaautorequested": "Žádost byla odeslána automaticky",
|
||||
"components.NotificationTypeSelector.mediaautorequestedDescription": "Získejte upozornění, když jsou automaticky odeslány nové požadavky na média pro položky na vašem Plex Watchlistu.",
|
||||
"components.PermissionEdit.viewwatchlistsDescription": "Udělte oprávnění k zobrazení Plex Watchlistu ostatních uživatelů.",
|
||||
"components.TvDetails.Season.somethingwentwrong": "Při načítání údajů o sezóně se něco pokazilo.",
|
||||
"i18n.restartRequired": "Je vyžadován restart",
|
||||
"components.Discover.plexwatchlist": "Váš Plex Watchlist",
|
||||
"components.MovieDetails.theatricalrelease": "Dostupné v kinách",
|
||||
"components.Discover.DiscoverWatchlist.watchlist": "Plex Watchlist",
|
||||
"components.TvDetails.reportissue": "Nahlásit problém",
|
||||
"components.MovieDetails.tmdbuserscore": "Uživatelské skóre TMDB",
|
||||
"components.TvDetails.seasonstitle": "Sezóny",
|
||||
"components.TvDetails.seasonnumber": "Sezóna {seasonNumber}",
|
||||
"components.TvDetails.rtcriticsscore": "Rotten Tomatoes Tomatometer",
|
||||
"components.TvDetails.rtaudiencescore": "Rotten Tomatoes Audience Skóre",
|
||||
"components.TvDetails.tmdbuserscore": "Uživatelské skóre TMDB",
|
||||
"components.TvDetails.status4k": "4K {status}",
|
||||
"components.Discover.emptywatchlist": "Média přidaná do vašeho <PlexWatchlistSupportLink>Plex Watchlistu</PlexWatchlistSupportLink> se zobrazí zde.",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncmoviestip": "Automaticky vyžádat filmy na vašem <PlexWatchlistSupportLink>Plex Watchlistu</PlexWatchlistSupportLink>",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncseriestip": "Automaticky vyžádejte sérii na vašem <PlexWatchlistSupportLink>Plex Watchlistu</PlexWatchlistSupportLink>",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncseries": "Automaticky vyžádat sérii",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncmovies": "Automaticky vyžádat filmy",
|
||||
"components.UserProfile.plexwatchlist": "Plex Watchlist",
|
||||
"components.UserProfile.emptywatchlist": "Zde se zobrazí média přidaná do vašeho <PlexWatchlistSupportLink>Plex Watchlistu</PlexWatchlistSupportLink>."
|
||||
}
|
||||
|
||||
@@ -642,7 +642,8 @@
|
||||
"components.Settings.SettingsJobsCache.download-sync": "Download Sync",
|
||||
"components.Settings.SettingsJobsCache.download-sync-reset": "Download Sync Reset",
|
||||
"components.Settings.SettingsJobsCache.editJobSchedule": "Modify Job",
|
||||
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "Frequency",
|
||||
"components.Settings.SettingsJobsCache.editJobScheduleCurrent": "Current Frequency",
|
||||
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "New Frequency",
|
||||
"components.Settings.SettingsJobsCache.editJobScheduleSelectorHours": "Every {jobScheduleHours, plural, one {hour} other {{jobScheduleHours} hours}}",
|
||||
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "Every {jobScheduleMinutes, plural, one {minute} other {{jobScheduleMinutes} minutes}}",
|
||||
"components.Settings.SettingsJobsCache.flushcache": "Flush Cache",
|
||||
|
||||
55
src/i18n/locale/hr.json
Normal file
55
src/i18n/locale/hr.json
Normal file
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"components.CollectionDetails.numberofmovies": "{count} Filmovi",
|
||||
"components.CollectionDetails.overview": "Pregled",
|
||||
"components.CollectionDetails.requestcollection4k": "Zahtjev za serijalom u 4K",
|
||||
"components.CollectionDetails.requestcollection": "Zahtjev za serijalom",
|
||||
"components.Discover.DiscoverMovieGenre.genreMovies": "{genre} Filmovi",
|
||||
"components.Discover.DiscoverMovieLanguage.languageMovies": "{language} Filmovi",
|
||||
"components.Discover.DiscoverNetwork.networkSeries": "{network} Serije",
|
||||
"components.Discover.DiscoverStudio.studioMovies": "{studio} Filmovi",
|
||||
"components.Discover.discover": "Otkrivanje",
|
||||
"components.Discover.discovermovies": "Popularni Filmovi",
|
||||
"components.Discover.discovertv": "Popularne Serije",
|
||||
"components.Discover.DiscoverTvGenre.genreSeries": "{genre} Serije",
|
||||
"components.Discover.DiscoverTvLanguage.languageSeries": "{language} Serije",
|
||||
"components.Discover.DiscoverWatchlist.discoverwatchlist": "Vaš Plex popis za gledanje",
|
||||
"components.Discover.MovieGenreList.moviegenres": "Filmski Žanrovi",
|
||||
"components.Discover.StudioSlider.studios": "Studio",
|
||||
"components.Discover.TvGenreList.seriesgenres": "Serijski Žanrovi",
|
||||
"components.Discover.TvGenreSlider.tvgenres": "Serijski Žanrovi",
|
||||
"components.Discover.plexwatchlist": "Vaš Plex popis za gledanje",
|
||||
"components.Discover.popularmovies": "Popularni Filmovi",
|
||||
"components.Discover.recentlyAdded": "Nedavno Dodano",
|
||||
"components.Discover.recentrequests": "Nedavni Zahtjevi",
|
||||
"components.Discover.trending": "Popularno",
|
||||
"components.IssueDetails.IssueComment.edit": "Uredi Komentar",
|
||||
"components.IssueDetails.IssueDescription.deleteissue": "Izbriši problem",
|
||||
"components.IssueDetails.IssueDescription.description": "Opis",
|
||||
"components.IssueDetails.IssueDescription.edit": "Uredi opis",
|
||||
"components.IssueDetails.allepisodes": "Sve Epizode",
|
||||
"components.IssueDetails.closeissue": "Zatvori Problem",
|
||||
"components.IssueDetails.closeissueandcomment": "Zatvori s komentarom",
|
||||
"components.IssueDetails.commentplaceholder": "Dodaj komentar…",
|
||||
"components.IssueDetails.comments": "Komentari",
|
||||
"components.IssueDetails.deleteissue": "Izbriši problem",
|
||||
"components.AirDateBadge.airedrelative": "Emitirano {relativeTime}",
|
||||
"components.AirDateBadge.airsrelative": "Emitiranje {relativeTime}",
|
||||
"components.AppDataWarning.dockerVolumeMissingDescription": "Navedeni <code>{appDataPath}</code> mapirani volumen nije ispravno podešen. Svi podaci će biti izbrisani kada se spremnik (container) zaustavi ili ponovno pokrene.",
|
||||
"components.Discover.DiscoverWatchlist.watchlist": "Plex popis za gledanje",
|
||||
"components.Discover.emptywatchlist": "Filmovi dodani na Vaš <PlexWatchlistSupportLink> popis za gledanje </PlexWatchlistSupportLink> pojaviti će se ovdje.",
|
||||
"components.Discover.MovieGenreSlider.moviegenres": "Filmski Žanrovi",
|
||||
"components.Discover.NetworkSlider.networks": "Striming servisi",
|
||||
"components.Discover.populartv": "Popularne Serije",
|
||||
"components.Discover.upcomingtv": "Nadolazeće Serije",
|
||||
"components.Discover.upcoming": "Nadolazeći Filmovi",
|
||||
"components.Discover.upcomingmovies": "Nadolazeći Filmovi",
|
||||
"components.DownloadBlock.estimatedtime": "Procijenjeno {time}",
|
||||
"components.IssueDetails.IssueComment.areyousuredelete": "Jeste li sigurni da želite izbrisati ovaj komentar?",
|
||||
"components.IssueDetails.IssueComment.delete": "Izbriši Komentar",
|
||||
"components.IssueDetails.IssueComment.postedby": "Objavljeno u {relativeTime} od korisnika {username}",
|
||||
"components.IssueDetails.IssueComment.validationComment": "Morate unijeti poruku",
|
||||
"components.IssueDetails.IssueComment.postedbyedited": "Objavljeno u {relativeTime} od korisnika {username} (Uređeno)",
|
||||
"components.IssueDetails.allseasons": "Sve Sezone",
|
||||
"components.IssueDetails.episode": "Epizode {episodeNumber}",
|
||||
"components.IssueDetails.deleteissueconfirm": "Jeste li sigurni da želite izbrisati ovaj problem?"
|
||||
}
|
||||
@@ -337,7 +337,7 @@
|
||||
"i18n.experimental": "Experimenteel",
|
||||
"components.Settings.hideAvailable": "Beschikbare media verbergen",
|
||||
"components.RequestModal.requesterror": "Er ging iets mis bij het aanvragen.",
|
||||
"components.RequestModal.SearchByNameModal.notvdbiddescription": "We konden je verzoek niet automatisch matchen. Selecteer de juiste match uit de onderstaande lijst.",
|
||||
"components.RequestModal.SearchByNameModal.notvdbiddescription": "We kunnen deze serie niet automatisch matchen. Selecteer hieronder de juiste match.",
|
||||
"components.Login.signinwithplex": "Plex-account gebruiken",
|
||||
"components.Login.signinheader": "Log in om verder te gaan",
|
||||
"components.Login.signingin": "Bezig met inloggen…",
|
||||
@@ -632,7 +632,7 @@
|
||||
"components.Settings.SettingsJobsCache.jobsandcache": "Taken en cache",
|
||||
"components.Settings.SettingsAbout.about": "Over",
|
||||
"components.ResetPassword.passwordreset": "Wachtwoord opnieuw instellen",
|
||||
"components.Settings.cacheImagesTip": "Alle afbeeldingen optimaliseren en lokaal opslaan (gebruikt een aanzienlijke hoeveelheid schijfruimte)",
|
||||
"components.Settings.cacheImagesTip": "Cache en serveer geoptimaliseerde afbeeldingen (een aanzienlijke hoeveelheid schijfruimte is nodig)",
|
||||
"components.Settings.cacheImages": "Afbeeldingscaching inschakelen",
|
||||
"components.Settings.SettingsLogs.logDetails": "Loggegevens",
|
||||
"components.Settings.SettingsLogs.extraData": "Aanvullende gegevens",
|
||||
@@ -713,9 +713,9 @@
|
||||
"components.RequestModal.AdvancedRequester.selecttags": "Labels selecteren",
|
||||
"components.RequestModal.AdvancedRequester.notagoptions": "Geen labels.",
|
||||
"components.Settings.RadarrModal.loadingTags": "Labels laden…",
|
||||
"components.RequestList.RequestItem.mediaerror": "De gekoppelde titel voor dit verzoek is niet meer beschikbaar.",
|
||||
"components.RequestList.RequestItem.mediaerror": "{mediaType} Niet Gevonden",
|
||||
"components.RequestList.RequestItem.deleterequest": "Verzoek verwijderen",
|
||||
"components.RequestCard.mediaerror": "De gekoppelde titel voor dit verzoek is niet meer beschikbaar.",
|
||||
"components.RequestCard.mediaerror": "{mediaType} Niet Gevonden",
|
||||
"components.RequestCard.deleterequest": "Verzoek verwijderen",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.validationPgpPublicKey": "Je moet een geldige openbare PGP-sleutel opgeven",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingssaved": "Instellingen Telegrammeldingen succesvol opgeslagen!",
|
||||
|
||||
@@ -1034,5 +1034,44 @@
|
||||
"i18n.next": "Tjetra",
|
||||
"i18n.experimental": "Eksperimentale",
|
||||
"i18n.noresults": "S'ka rezultate.",
|
||||
"i18n.notrequested": "Nuk është Kerkuar"
|
||||
"i18n.notrequested": "Nuk është Kerkuar",
|
||||
"components.Settings.SettingsAbout.appDataPath": "Direktoria e të dhënave",
|
||||
"components.MovieDetails.digitalrelease": "Publikimi Dixhital",
|
||||
"components.MovieDetails.physicalrelease": "Lëshimi Fizik",
|
||||
"components.MovieDetails.theatricalrelease": "Publikimi Teatror",
|
||||
"components.PermissionEdit.viewrecent": "Shiko Shtuar së fundi",
|
||||
"components.PermissionEdit.viewrecentDescription": "Jep leje për të parë listën e mediave të shtuara kohët e fundit.",
|
||||
"components.Discover.DiscoverWatchlist.discoverwatchlist": "Lista juaj e shikimit në Plex",
|
||||
"components.PermissionEdit.autorequestMoviesDescription": "Jepni lejen për të paraqitur automatikisht kërkesat për mediat jo-4K nëpërmjet Plex Watchlist.",
|
||||
"components.PermissionEdit.autorequestSeries": "Kërkesa Automatike Serialesh",
|
||||
"components.PermissionEdit.autorequestSeriesDescription": "Jep leje për të paraqitur automatikisht kërkesat për seri jo-4K nëpërmjet Plex Watchlist.",
|
||||
"components.Discover.DiscoverWatchlist.watchlist": "Lista e Shikimit Plex",
|
||||
"components.Discover.plexwatchlist": "Lista juaj e shikimit në Plex",
|
||||
"components.MovieDetails.reportissue": "Raportoni një problem",
|
||||
"components.NotificationTypeSelector.mediaautorequested": "Kërkesa u dorëzua automatikisht",
|
||||
"components.PermissionEdit.autorequest": "Auto-Kërkesë",
|
||||
"components.PermissionEdit.autorequestDescription": "Jepni lejen për të paraqitur automatikisht kërkesat për mediat jo-4K nëpërmjet Plex Watchlist.",
|
||||
"components.PermissionEdit.autorequestMovies": "Kërkesë automatike për filma",
|
||||
"components.PermissionEdit.viewwatchlists": "Shiko listat e shikimit të Plex",
|
||||
"components.PermissionEdit.viewwatchlistsDescription": "Jep leje për të parë listat e Plex Watchlist të përdoruesve të tjerë.",
|
||||
"components.MovieDetails.managemovie": "Menaxho filmin",
|
||||
"components.AirDateBadge.airedrelative": "Transmetuar {relativeTime}",
|
||||
"components.Layout.UserDropdown.MiniQuotaDisplay.movierequests": "Kërkesat e Filmave",
|
||||
"components.Layout.UserDropdown.MiniQuotaDisplay.seriesrequests": "Kërkesat e Serialeve",
|
||||
"components.Layout.UserDropdown.requests": "Kërkesat",
|
||||
"components.MovieDetails.rtaudiencescore": "Rezultati i audiencës së Rotten Tomatoes",
|
||||
"components.MovieDetails.rtcriticsscore": "Tomatometeri i Rotten Tomatoes",
|
||||
"components.NotificationTypeSelector.mediaautorequestedDescription": "Njoftohuni kur kërkesat e reja të medias dorëzohen automatikisht për artikujt në Listën tuaj të Plex Watchlist.",
|
||||
"components.RequestBlock.languageprofile": "Profili i gjuhës",
|
||||
"components.AirDateBadge.airsrelative": "Duke u Transmetuar {relativeTime}",
|
||||
"components.Discover.emptywatchlist": "Këtu do të shfaqet media e shtuar në listën tuaj <PlexWatchlistSupportLink>Plex</PlexWatchlistSupportLink>.",
|
||||
"components.RequestBlock.decline": "Refuzo kërkesën",
|
||||
"components.RequestBlock.delete": "Fshije Kërkesën",
|
||||
"components.RequestBlock.edit": "Ndrysho kërkesën",
|
||||
"components.MovieDetails.tmdbuserscore": "Nota e përdoruesve TMDB",
|
||||
"components.RequestBlock.approve": "Mirato Kërkesën",
|
||||
"components.RequestBlock.lastmodifiedby": "Ndryshuar së fundi nga",
|
||||
"components.RequestBlock.requestdate": "Data e Kërkesës",
|
||||
"components.RequestBlock.requestedby": "Kërkuar nga",
|
||||
"components.RequestCard.approverequest": "Mirato Kërkesën"
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"components.UserList.creating": "創建中…",
|
||||
"components.UserList.createlocaluser": "建立本地使用者",
|
||||
"components.UserList.autogeneratepassword": "自動生成密碼",
|
||||
"i18n.tvshows": "電視節目",
|
||||
"i18n.tvshows": "影集",
|
||||
"pages.oops": "哎呀",
|
||||
"components.TvDetails.firstAirDate": "原始播出日期",
|
||||
"i18n.delete": "刪除",
|
||||
@@ -133,15 +133,15 @@
|
||||
"components.Layout.Sidebar.users": "使用者",
|
||||
"components.Layout.Sidebar.settings": "設定",
|
||||
"components.Layout.Sidebar.requests": "請求",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "搜尋電影、電視節目、人物…",
|
||||
"components.Layout.SearchInput.searchPlaceholder": "搜尋電影、影集、人物…",
|
||||
"components.Discover.upcomingmovies": "即將上映的電影",
|
||||
"components.Discover.upcoming": "即將上映的電影",
|
||||
"components.Discover.trending": "趨勢",
|
||||
"components.Discover.recentlyAdded": "最近新增",
|
||||
"components.Discover.recentrequests": "最新請求",
|
||||
"components.Discover.populartv": "熱門電視節目",
|
||||
"components.Discover.populartv": "熱門影集",
|
||||
"components.Discover.popularmovies": "熱門電影",
|
||||
"components.Discover.discovertv": "熱門電視節目",
|
||||
"components.Discover.discovertv": "熱門影集",
|
||||
"components.Discover.discovermovies": "熱門電影",
|
||||
"components.CollectionDetails.requestcollection": "提出電影系列請求",
|
||||
"components.CollectionDetails.overview": "概要",
|
||||
@@ -262,7 +262,7 @@
|
||||
"components.TvDetails.overviewunavailable": "沒有概要。",
|
||||
"components.MovieDetails.overviewunavailable": "沒有概要。",
|
||||
"components.TvDetails.watchtrailer": "觀看預告片",
|
||||
"components.TvDetails.showtype": "節目類型",
|
||||
"components.TvDetails.showtype": "影集類型",
|
||||
"components.TvDetails.similar": "類似",
|
||||
"components.RequestModal.requestfrom": "{username} 的請求待處理。",
|
||||
"components.Settings.toastApiKeySuccess": "生成新應用程式密鑰成功!",
|
||||
@@ -306,7 +306,7 @@
|
||||
"components.Settings.RadarrModal.add": "新增伺服器",
|
||||
"components.RequestModal.requestcancelled": "<strong>{title}</strong> 的請求已被取消。",
|
||||
"components.RequestModal.AdvancedRequester.qualityprofile": "品質設定",
|
||||
"components.RequestModal.AdvancedRequester.animenote": "※這是個動漫節目。",
|
||||
"components.RequestModal.AdvancedRequester.animenote": "※這是個動漫影集。",
|
||||
"components.RequestModal.AdvancedRequester.advancedoptions": "進階選項",
|
||||
"components.RequestModal.AdvancedRequester.default": "{name}(預設)",
|
||||
"components.RequestModal.AdvancedRequester.destinationserver": "目標伺服器",
|
||||
@@ -321,7 +321,7 @@
|
||||
"components.Settings.SonarrModal.toastSonarrTestFailure": "Sonarr 伺服器連線失敗。",
|
||||
"components.Settings.serverpreset": "伺服器",
|
||||
"components.RequestModal.autoapproval": "自動批准",
|
||||
"components.PermissionEdit.autoapproveSeries": "電視節目自動批准",
|
||||
"components.PermissionEdit.autoapproveSeries": "影集自動批准",
|
||||
"components.PermissionEdit.autoapproveMovies": "電影自動批准",
|
||||
"components.PermissionEdit.autoapprove": "自動批准",
|
||||
"components.PermissionEdit.admin": "管理員",
|
||||
@@ -330,7 +330,7 @@
|
||||
"components.Settings.serverpresetRefreshing": "載入中…",
|
||||
"components.Settings.SonarrModal.syncEnabled": "啟用掃描",
|
||||
"components.UserList.userssaved": "使用者權限儲存成功!",
|
||||
"components.Settings.hideAvailable": "隱藏可觀看的電影和電視節目",
|
||||
"components.Settings.hideAvailable": "隱藏可觀看的電影和影集",
|
||||
"components.Settings.SonarrModal.externalUrl": "外部網址",
|
||||
"components.Settings.RadarrModal.externalUrl": "外部網址",
|
||||
"components.Settings.csrfProtection": "防止跨站請求偽造(CSRF)攻擊",
|
||||
@@ -353,7 +353,7 @@
|
||||
"components.PlexLoginButton.signinwithplex": "登入",
|
||||
"components.PlexLoginButton.signingin": "登入中…",
|
||||
"components.PermissionEdit.users": "管理使用者",
|
||||
"components.PermissionEdit.request4kTv": "提出 4K 電視節目請求",
|
||||
"components.PermissionEdit.request4kTv": "提出 4K 影集請求",
|
||||
"components.PermissionEdit.request4kMovies": "提出 4K 電影請求",
|
||||
"components.PermissionEdit.request4k": "提出 4K 請求",
|
||||
"components.PermissionEdit.request": "提出請求",
|
||||
@@ -432,7 +432,7 @@
|
||||
"components.NotificationTypeSelector.mediadeclinedDescription": "當請求拒被絕時發送通知。",
|
||||
"components.PermissionEdit.request4kDescription": "授予提出 4K 媒體請求的權限。",
|
||||
"components.PermissionEdit.request4kMoviesDescription": "授予提出 4K 電影請求的權限。",
|
||||
"components.PermissionEdit.request4kTvDescription": "授予提出 4K 電視節目請求的權限。",
|
||||
"components.PermissionEdit.request4kTvDescription": "授予提出 4K 影集請求的權限。",
|
||||
"components.PermissionEdit.requestDescription": "授予提出非 4K 媒體請求的權限。",
|
||||
"components.PermissionEdit.viewrequestsDescription": "授予查看其他使用者提出的媒體請求的權限。",
|
||||
"components.Settings.SonarrModal.validationLanguageProfileRequired": "請設定語言",
|
||||
@@ -443,7 +443,7 @@
|
||||
"components.Settings.SonarrModal.animelanguageprofile": "動漫語言設定",
|
||||
"components.RequestModal.AdvancedRequester.languageprofile": "語言設定",
|
||||
"components.PermissionEdit.usersDescription": "授予管理使用者的權限。有此權限的使用者不能編輯管理員或授予管理員權限。",
|
||||
"components.PermissionEdit.autoapproveSeriesDescription": "自動批准非 4K 電視節目請求。",
|
||||
"components.PermissionEdit.autoapproveSeriesDescription": "自動批准非 4K 影集請求。",
|
||||
"components.PermissionEdit.autoapproveMoviesDescription": "自動批准非 4K 電影請求。",
|
||||
"components.PermissionEdit.autoapproveDescription": "自動批准所有非 4K 媒體請求。",
|
||||
"components.PermissionEdit.advancedrequestDescription": "授予使用進階媒體請求選項的權限。",
|
||||
@@ -456,8 +456,8 @@
|
||||
"components.UserList.sortCreated": "加入日期",
|
||||
"components.UserList.sortDisplayName": "顯示名稱",
|
||||
"components.UserList.sortRequests": "請求數",
|
||||
"components.PermissionEdit.autoapprove4kSeriesDescription": "自動批准 4K 電視節目請求。",
|
||||
"components.PermissionEdit.autoapprove4kSeries": "4K 電視節目自動批准",
|
||||
"components.PermissionEdit.autoapprove4kSeriesDescription": "自動批准 4K 影集請求。",
|
||||
"components.PermissionEdit.autoapprove4kSeries": "4K 影集自動批准",
|
||||
"components.PermissionEdit.autoapprove4kMoviesDescription": "自動批准 4K 電影請求。",
|
||||
"components.PermissionEdit.autoapprove4kMovies": "4K 電影自動批准",
|
||||
"components.PermissionEdit.autoapprove4kDescription": "自動批准所有 4K 媒體請求。",
|
||||
@@ -502,7 +502,7 @@
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.validationDiscordId": "請輸入有效的使用者 ID",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.discordIdTip": "您的<FindDiscordIdLink>使用者 ID 號碼</FindDiscordIdLink>",
|
||||
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailure": "重設密碼時出了點問題。",
|
||||
"components.RequestModal.SearchByNameModal.notvdbiddescription": "無法自動配對此電視節目的數據。 請在以下選擇正確的媒體項。",
|
||||
"components.RequestModal.SearchByNameModal.notvdbiddescription": "無法自動配對此影集的數據。 請在以下選擇正確的媒體項。",
|
||||
"components.CollectionDetails.requestcollection4k": "提出 4K 電影系列請求",
|
||||
"components.Settings.trustProxyTip": "使用代理伺服器時,允許 Jellyseerr 註冊客戶端的正確 IP 位址",
|
||||
"components.Settings.csrfProtectionTip": "設定外部訪問權限為只讀(需要 HTTPS)",
|
||||
@@ -513,7 +513,7 @@
|
||||
"components.Settings.region": "「探索」地區",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.originallanguage": "「探索」語言",
|
||||
"components.Settings.originallanguage": "「探索」語言",
|
||||
"components.Discover.upcomingtv": "即將上映的電視節目",
|
||||
"components.Discover.upcomingtv": "即將上映的影集",
|
||||
"components.Settings.webhook": "Webhook",
|
||||
"components.Settings.email": "電子郵件",
|
||||
"components.Settings.generalsettingsDescription": "Jellyseerr 的全域和預設設定。",
|
||||
@@ -540,8 +540,8 @@
|
||||
"components.Settings.SettingsJobsCache.download-sync": "下載狀態同步",
|
||||
"components.Settings.SettingsJobsCache.unknownJob": "未知作業",
|
||||
"components.TvDetails.seasons": "{seasonCount} 季",
|
||||
"components.Discover.DiscoverTvGenre.genreSeries": "{genre}電視節目",
|
||||
"components.Discover.DiscoverNetwork.networkSeries": "{network} 電視節目",
|
||||
"components.Discover.DiscoverTvGenre.genreSeries": "{genre}影集",
|
||||
"components.Discover.DiscoverNetwork.networkSeries": "{network} 影集",
|
||||
"components.Discover.DiscoverStudio.studioMovies": "{studio} 電影",
|
||||
"components.Discover.DiscoverMovieGenre.genreMovies": "{genre}電影",
|
||||
"i18n.loading": "載入中…",
|
||||
@@ -565,7 +565,7 @@
|
||||
"components.Settings.SettingsJobsCache.radarr-scan": "Radarr 掃描",
|
||||
"components.Settings.SettingsJobsCache.plex-recently-added-scan": "Plex 最近新增掃描",
|
||||
"components.Settings.SettingsJobsCache.plex-full-scan": "Plex 媒體庫掃描",
|
||||
"components.Discover.DiscoverTvLanguage.languageSeries": "{language}電視節目",
|
||||
"components.Discover.DiscoverTvLanguage.languageSeries": "{language}影集",
|
||||
"components.Discover.DiscoverMovieLanguage.languageMovies": "{language}電影",
|
||||
"components.UserProfile.ProfileHeader.userid": "使用者 ID:{userid}",
|
||||
"components.UserProfile.ProfileHeader.joindate": "加入日期:{joindate}",
|
||||
@@ -587,11 +587,11 @@
|
||||
"components.TvDetails.episodeRuntime": "劇集片長",
|
||||
"components.TvDetails.episodeRuntimeMinutes": "{runtime} 分鐘",
|
||||
"components.RequestModal.AdvancedRequester.folder": "{path}({space})",
|
||||
"components.Discover.TvGenreSlider.tvgenres": "電視節目類型",
|
||||
"components.Discover.TvGenreSlider.tvgenres": "影集類型",
|
||||
"components.Discover.MovieGenreSlider.moviegenres": "電影類型",
|
||||
"components.Discover.MovieGenreList.moviegenres": "電影類型",
|
||||
"components.Discover.TvGenreList.seriesgenres": "電視節目類型",
|
||||
"components.Settings.partialRequestsEnabled": "允許不完整的電視節目請求",
|
||||
"components.Discover.TvGenreList.seriesgenres": "影集類型",
|
||||
"components.Settings.partialRequestsEnabled": "允許不完整的影集請求",
|
||||
"components.RequestModal.alreadyrequested": "已經有請求",
|
||||
"components.Settings.SettingsLogs.time": "時間戳",
|
||||
"components.Settings.SettingsLogs.resumeLogs": "恢復",
|
||||
@@ -636,16 +636,16 @@
|
||||
"components.PersonDetails.lifespan": "{birthdate}-{deathdate}",
|
||||
"components.PersonDetails.alsoknownas": "別名:{names}",
|
||||
"i18n.delimitedlist": "{a}、{b}",
|
||||
"components.Settings.SettingsUsers.tvRequestLimitLabel": "電視節目請求全域限制",
|
||||
"components.Settings.SettingsUsers.tvRequestLimitLabel": "影集請求全域限制",
|
||||
"components.Settings.SettingsUsers.movieRequestLimitLabel": "電影請求全域限制",
|
||||
"components.RequestModal.QuotaDisplay.seasonlimit": "季數",
|
||||
"components.RequestModal.QuotaDisplay.season": "電視節目季數",
|
||||
"components.RequestModal.QuotaDisplay.season": "影集季數",
|
||||
"components.RequestModal.QuotaDisplay.requestsremaining": "{remaining, plural, =0 {電影請求剩餘數不足} other {剩餘 <strong>#</strong> 個{type}請求}}",
|
||||
"components.RequestModal.QuotaDisplay.notenoughseasonrequests": "請求剩餘數不足",
|
||||
"components.RequestModal.QuotaDisplay.movielimit": "電影",
|
||||
"components.RequestModal.QuotaDisplay.allowedRequestsUser": "此使用者每 <strong>{days}</strong> 天能提出 <strong>{limit}</strong> 個{type}請求。",
|
||||
"components.RequestModal.QuotaDisplay.allowedRequests": "您每 <strong>{days}</strong> 天能提出 <strong>{limit}</strong> 個{type}請求。",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.seriesrequestlimit": "電視節目請求限制",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.seriesrequestlimit": "影集請求限制",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.movierequestlimit": "電影請求限制",
|
||||
"components.UserProfile.movierequests": "電影請求",
|
||||
"components.UserProfile.limit": "{limit} 之 {remaining}",
|
||||
@@ -656,9 +656,9 @@
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.enableOverride": "覆寫全域限制",
|
||||
"components.UserProfile.unlimited": "無限",
|
||||
"components.UserProfile.totalrequests": "請求總數",
|
||||
"components.UserProfile.seriesrequest": "電視節目請求",
|
||||
"components.UserProfile.seriesrequest": "影集請求",
|
||||
"i18n.view": "檢視",
|
||||
"i18n.tvshow": "電視節目",
|
||||
"i18n.tvshow": "影集",
|
||||
"i18n.testing": "測試中…",
|
||||
"i18n.test": "測試",
|
||||
"i18n.status": "狀態",
|
||||
@@ -677,8 +677,8 @@
|
||||
"i18n.back": "返回",
|
||||
"i18n.all": "所有",
|
||||
"i18n.areyousure": "確定嗎?",
|
||||
"components.RequestModal.QuotaDisplay.requiredquotaUser": "此使用者的電視節目請求數量必須至少剩餘 <strong>{seasons}</strong> 個季數才能提出此節目請求。",
|
||||
"components.RequestModal.QuotaDisplay.requiredquota": "您的電視節目請求數量必須至少剩餘 <strong>{seasons}</strong> 個季數才能提出此節目請求。",
|
||||
"components.RequestModal.QuotaDisplay.requiredquotaUser": "此使用者的影集請求數量必須至少剩餘 <strong>{seasons}</strong> 個季數才能提出此影集請求。",
|
||||
"components.RequestModal.QuotaDisplay.requiredquota": "您的影集請求數量必須至少剩餘 <strong>{seasons}</strong> 個季數才能提出此影集請求。",
|
||||
"components.TvDetails.originaltitle": "原始標題",
|
||||
"components.MovieDetails.originaltitle": "原始標題",
|
||||
"components.RequestModal.QuotaDisplay.quotaLinkUser": "訪問此使用者的<ProfileLink>個人資料頁面</ProfileLink>以查看使用者的請求限制 。",
|
||||
@@ -734,7 +734,7 @@
|
||||
"components.Settings.noDefaultNon4kServer": "如果您只有一個 {serverType} 伺服器,請勿把它設定為 4K 伺服器。",
|
||||
"components.Settings.noDefaultServer": "您必須至少指定一個預設 {serverType} 伺服器,才能處理{mediaType}請求。",
|
||||
"components.Settings.serviceSettingsDescription": "關於 {serverType} 伺服器的設定。{serverType} 伺服器數沒有最大值限制,但您只能指定兩個預設伺服器(一個非 4K、一個 4K)。",
|
||||
"components.Settings.mediaTypeSeries": "電視節目",
|
||||
"components.Settings.mediaTypeSeries": "影集",
|
||||
"components.Settings.mediaTypeMovie": "電影",
|
||||
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSet": "此使用者的帳戶目前沒有設密碼。若在以下設定密碼,此使用者就能使用「本地登入」。",
|
||||
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSetOwnAccount": "您的帳戶目前沒有設密碼。若在以下設定密碼,您就能使用「本地登入」。",
|
||||
@@ -792,10 +792,10 @@
|
||||
"components.Settings.Notifications.NotificationsWebhook.toastWebhookTestSuccess": "Webhook 測試通知已發送!",
|
||||
"components.Settings.SettingsUsers.newPlexLoginTip": "讓還沒匯入的 Plex 使用者登入",
|
||||
"components.Settings.SettingsUsers.newPlexLogin": "允許新的 Plex 登入",
|
||||
"components.PermissionEdit.requestTv": "提出電視節目請求",
|
||||
"components.PermissionEdit.requestTv": "提出影集請求",
|
||||
"components.PermissionEdit.requestMovies": "提出電影請求",
|
||||
"components.PermissionEdit.requestMoviesDescription": "授予提出非 4K 電影請求的權限。",
|
||||
"components.PermissionEdit.requestTvDescription": "授予提出非 4K 電視節目請求的權限。",
|
||||
"components.PermissionEdit.requestTvDescription": "授予提出非 4K 影集請求的權限。",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "預設設定({language})",
|
||||
"components.Settings.locale": "顯示語言",
|
||||
"components.DownloadBlock.estimatedtime": "預計:{time}",
|
||||
@@ -879,16 +879,16 @@
|
||||
"components.ManageSlideOver.manageModalNoRequests": "沒有請求。",
|
||||
"components.ManageSlideOver.openarr": "開啟 {arr} 伺服器",
|
||||
"components.ManageSlideOver.openarr4k": "開啟 4K {arr} 伺服器",
|
||||
"components.ManageSlideOver.movie": "部電影",
|
||||
"components.ManageSlideOver.movie": "電影",
|
||||
"components.ManageSlideOver.markavailable": "標記為可觀看",
|
||||
"components.IssueModal.issueAudio": "音訊",
|
||||
"components.ManageSlideOver.downloadstatus": "下載狀態",
|
||||
"components.IssueModal.CreateIssueModal.allepisodes": "所有集數",
|
||||
"components.ManageSlideOver.manageModalClearMediaWarning": "※這將會刪除包括使用者請求在內所有有關這{mediaType}的資料。如果這{mediaType}存在於您的 Plex 伺服器,資料將會在媒體庫掃描時重新建立。",
|
||||
"components.ManageSlideOver.manageModalClearMediaWarning": "※這將會刪除包括使用者請求在內所有有關此{mediaType}的資料。如果這{mediaType}存在於您的 Plex 伺服器,資料將會在媒體庫掃描時重新建立。",
|
||||
"components.ManageSlideOver.mark4kavailable": "標記 4K 版為可觀看",
|
||||
"components.IssueModal.issueSubtitles": "字幕",
|
||||
"components.IssueModal.issueOther": "其他",
|
||||
"components.ManageSlideOver.tvshow": "個電視節目",
|
||||
"components.ManageSlideOver.tvshow": "影集",
|
||||
"components.ManageSlideOver.manageModalTitle": "管理{mediaType}",
|
||||
"components.IssueModal.issueVideo": "影片",
|
||||
"components.IssueList.IssueItem.issuetype": "類型",
|
||||
@@ -1053,19 +1053,19 @@
|
||||
"components.RequestList.RequestItem.tvdbid": "TheTVDB ID",
|
||||
"components.Discover.plexwatchlist": "您的 Plex Watchlist",
|
||||
"components.PermissionEdit.autorequestMovies": "自動提出電影請求",
|
||||
"components.PermissionEdit.autorequestSeries": "自動提出電視節目請求",
|
||||
"components.PermissionEdit.autorequestSeries": "自動提出影集請求",
|
||||
"components.Settings.SettingsJobsCache.plex-watchlist-sync": "Plex Watchlist 同步",
|
||||
"components.PermissionEdit.autorequest": "自動提出請求",
|
||||
"components.Discover.DiscoverWatchlist.discoverwatchlist": "您的 Plex Watchlist",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncmovies": "自動提出電影請求",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncseries": "自動提出電視節目請求",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncseries": "自動提出影集請求",
|
||||
"components.NotificationTypeSelector.mediaautorequested": "請求自動提出",
|
||||
"components.PermissionEdit.autorequestMoviesDescription": "授予從 Plex Watchlist 中自動提出非 4K 電影請求的權限。",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncmoviestip": "從您的 <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink> 中自動提出電影請求",
|
||||
"components.NotificationTypeSelector.mediaautorequestedDescription": "當您的 Plex Watchlist 中的媒體自動提出請求時取得通知。",
|
||||
"components.PermissionEdit.autorequestDescription": "授予從 Plex Watchlist 中自動提出非 4K 媒體請求的權限。",
|
||||
"components.PermissionEdit.autorequestSeriesDescription": "授予從 Plex Watchlist 中自動提出非 4K 電視節目請求的權限。",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncseriestip": "從您的 <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink> 中自動提出電視節目請求",
|
||||
"components.PermissionEdit.autorequestSeriesDescription": "授予從 Plex Watchlist 中自動提出非 4K 影集請求的權限。",
|
||||
"components.UserProfile.UserSettings.UserGeneralSettings.plexwatchlistsyncseriestip": "從您的 <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink> 中自動提出影集請求",
|
||||
"components.Settings.SettingsLogs.viewdetails": "查看詳細信息",
|
||||
"components.TvDetails.reportissue": "報告問題",
|
||||
"components.MovieDetails.managemovie": "管理電影",
|
||||
@@ -1074,10 +1074,10 @@
|
||||
"components.MovieDetails.reportissue": "報告問題",
|
||||
"components.PermissionEdit.viewwatchlists": "查看 Plex Watchlists",
|
||||
"components.PermissionEdit.viewwatchlistsDescription": "授予查看其他使用者的 Plex Watchlists 的權限。",
|
||||
"components.TvDetails.manageseries": "管理電視節目",
|
||||
"components.TvDetails.manageseries": "管理影集",
|
||||
"components.Settings.restartrequiredTooltip": "Jellyseerr 必須重新啟動才能應用設定的變更",
|
||||
"components.Layout.UserDropdown.MiniQuotaDisplay.movierequests": "電影請求",
|
||||
"components.Layout.UserDropdown.MiniQuotaDisplay.seriesrequests": "電視節目請求",
|
||||
"components.Layout.UserDropdown.MiniQuotaDisplay.seriesrequests": "影集請求",
|
||||
"components.Layout.UserDropdown.requests": "請求",
|
||||
"components.TvDetails.seasonstitle": "季數",
|
||||
"components.RequestBlock.decline": "拒絕請求",
|
||||
@@ -1109,10 +1109,10 @@
|
||||
"components.RequestModal.requestmovietitle": "提出電影請求",
|
||||
"components.RequestModal.requestmovie4ktitle": "提出 4K 電影請求",
|
||||
"components.RequestModal.requestcollection4ktitle": "提出 4K 電影系列請求",
|
||||
"components.RequestModal.requestseriestitle": "提出電視節目請求",
|
||||
"components.RequestModal.requestseries4ktitle": "提出 4K 電視節目請求",
|
||||
"components.RequestModal.requestseriestitle": "提出影集請求",
|
||||
"components.RequestModal.requestseries4ktitle": "提出 4K 影集請求",
|
||||
"components.RequestModal.requestcollectiontitle": "提出電影系列請求",
|
||||
"components.RequestModal.SearchByNameModal.nomatches": "找不到此電視節目的數據。",
|
||||
"components.RequestModal.SearchByNameModal.nomatches": "找不到此影集的數據。",
|
||||
"components.UserProfile.emptywatchlist": "您的 <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink> 中的媒體會顯示在這裡。",
|
||||
"components.Discover.emptywatchlist": "您的 <PlexWatchlistSupportLink>Plex Watchlist</PlexWatchlistSupportLink> 中的媒體會顯示在這裡。",
|
||||
"components.Settings.advancedTooltip": "錯誤的設定可能會破壞應用程式功能",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
body {
|
||||
@apply bg-gray-900;
|
||||
overscroll-behavior-y: contain;
|
||||
}
|
||||
|
||||
code {
|
||||
@@ -453,3 +454,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ptr--ptr {
|
||||
box-shadow: initial !important;
|
||||
position: absolute !important;
|
||||
z-index: 30 !important;
|
||||
}
|
||||
|
||||
.ptr--refresh {
|
||||
overflow: visible !important;
|
||||
z-index: 30 !important;
|
||||
}
|
||||
|
||||
.ptr--pull {
|
||||
z-index: 30 !important;
|
||||
}
|
||||
|
||||
.ptr--ptr .ptr--box {
|
||||
margin-bottom: -13px !important;
|
||||
}
|
||||
|
||||
20
yarn.lock
20
yarn.lock
@@ -3095,6 +3095,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
|
||||
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
|
||||
|
||||
"@types/pulltorefreshjs@0.1.5":
|
||||
version "0.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/pulltorefreshjs/-/pulltorefreshjs-0.1.5.tgz#f15c9dbc91b8fdd8135093d81ece9e9d4d2324d7"
|
||||
integrity sha512-/VRTgBettvBg1KI8mGnA9oeWs359tTXQ7qsxLuXnksL88jvK6ZNMStG5T9x9vUO9O7jLsgREB0cElz/BWFfdew==
|
||||
|
||||
"@types/qs@*":
|
||||
version "6.9.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
|
||||
@@ -4949,6 +4954,11 @@ cron-parser@^3.5.0:
|
||||
is-nan "^1.3.2"
|
||||
luxon "^1.26.0"
|
||||
|
||||
cronstrue@2.11.0:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/cronstrue/-/cronstrue-2.11.0.tgz#18ff1b95a836b9b4e06854f796db2dc8fa98ce41"
|
||||
integrity sha512-iIBCSis5yqtFYWtJAmNOiwDveFWWIn+8uV5UYuPHYu/Aeu5CSSJepSbaHMyfc+pPFgnsCcGzfPQEo7LSGmWbTg==
|
||||
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
@@ -5028,6 +5038,11 @@ csurf@1.11.0:
|
||||
csrf "3.1.0"
|
||||
http-errors "~1.7.3"
|
||||
|
||||
cy-mobile-commands@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/cy-mobile-commands/-/cy-mobile-commands-0.3.0.tgz#2bf242093149154d846b755977da197b4730429e"
|
||||
integrity sha512-Bj5P2ylw88hPqolLu68xWB6euVH5uNt8zyh+Ju8sBukGv39mWZxpjp6LtnUX/LK/YMthwvILYHhvr9SG1TP+4w==
|
||||
|
||||
cypress@10.6.0:
|
||||
version "10.6.0"
|
||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.6.0.tgz#13f46867febf2c3715874ed5dce9c2e946b175fe"
|
||||
@@ -10302,6 +10317,11 @@ pug@3.0.2, pug@^3.0.2:
|
||||
pug-runtime "^3.0.1"
|
||||
pug-strip-comments "^2.0.0"
|
||||
|
||||
pulltorefreshjs@0.1.22:
|
||||
version "0.1.22"
|
||||
resolved "https://registry.yarnpkg.com/pulltorefreshjs/-/pulltorefreshjs-0.1.22.tgz#ddb5e3feee0b2a49fd46e1b18e84fffef2c47ac0"
|
||||
integrity sha512-haxNVEHnS4NCQA7NeG7TSV69z4uqy/N7nfPRuc4dPWe8H6ygUrMjdNeohE+6v0lVVX/ukSjbLYwPUGUYtFKfvQ==
|
||||
|
||||
pump@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
|
||||
|
||||
Reference in New Issue
Block a user