1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-17 21:26:13 -04:00

Compare commits

..

7 Commits

Author SHA1 Message Date
Mark McDowall
af0e55aef4 Bump version to 4.0.5 2024-05-29 16:23:16 -07:00
Weblate
39a439eb4c Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Bao Trinh <servarr@baodtrinh.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: mm519897405 <baiya@vip.qq.com>
Co-authored-by: thegamingcat13 <sandervanbeek2004@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-05-29 16:23:04 -07:00
Weblate
66940b283b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: mm519897405 <baiya@vip.qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-05-24 06:21:13 -07:00
Mark McDowall
2a662afaef Fixed: Time for episodes airing today being blank 2024-05-24 06:19:38 -07:00
Weblate
62a9c2519b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: mm519897405 <baiya@vip.qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-05-22 20:09:18 -07:00
Mark McDowall
ca372bee25 Fixed: Queue and Calendar not loading 2024-05-22 20:07:31 -07:00
Sonarr
0904a0737e Automated API Docs update
ignore-downstream
2024-05-21 17:09:20 -07:00
15 changed files with 159 additions and 91 deletions

View File

@@ -22,7 +22,7 @@ env:
FRAMEWORK: net6.0
RAW_BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
SONARR_MAJOR_VERSION: 4
VERSION: 4.0.4
VERSION: 4.0.5
jobs:
backend:

View File

@@ -24,7 +24,11 @@ function TimeleftCell(props) {
} = props;
if (status === 'delay') {
const date = getRelativeDate(estimatedCompletionTime, shortDateFormat, showRelativeDates);
const date = getRelativeDate({
date: estimatedCompletionTime,
shortDateFormat,
showRelativeDates
});
const time = formatTime(estimatedCompletionTime, timeFormat, { includeMinuteZero: true });
return (
@@ -40,7 +44,11 @@ function TimeleftCell(props) {
}
if (status === 'downloadClientUnavailable') {
const date = getRelativeDate(estimatedCompletionTime, shortDateFormat, showRelativeDates);
const date = getRelativeDate({
date: estimatedCompletionTime,
shortDateFormat,
showRelativeDates
});
const time = formatTime(estimatedCompletionTime, timeFormat, { includeMinuteZero: true });
return (

View File

@@ -28,7 +28,7 @@ class DayOfWeek extends Component {
if (view === calendarViews.WEEK) {
formatedDate = momentDate.format(calendarWeekColumnHeader);
} else if (view === calendarViews.FORECAST) {
formatedDate = getRelativeDate(date, shortDateFormat, showRelativeDates);
formatedDate = getRelativeDate({ date, shortDateFormat, showRelativeDates });
}
return (

View File

@@ -40,7 +40,7 @@ class RelativeDateCell extends PureComponent {
title={formatDateTime(date, longDateFormat, timeFormat, { includeSeconds, includeRelativeDay: !showRelativeDates })}
{...otherProps}
>
{getRelativeDate(date, shortDateFormat, showRelativeDates, { timeFormat, includeSeconds, includeTime, timeForToday: true })}
{getRelativeDate({ date, shortDateFormat, showRelativeDates, timeFormat, includeSeconds, includeTime, timeForToday: true })}
</Component>
);
}

View File

@@ -138,7 +138,10 @@ function getInfoRowProps(
}),
iconName: icons.CALENDAR,
label:
getRelativeDate(previousAiring, shortDateFormat, showRelativeDates, {
getRelativeDate({
date: previousAiring,
shortDateFormat,
showRelativeDates,
timeFormat,
timeForToday: true,
}) ?? '',
@@ -156,7 +159,10 @@ function getInfoRowProps(
}),
iconName: icons.ADD,
label:
getRelativeDate(added, shortDateFormat, showRelativeDates, {
getRelativeDate({
date: added,
shortDateFormat,
showRelativeDates,
timeFormat,
timeForToday: true,
}) ?? '',
@@ -232,15 +238,13 @@ function SeriesIndexOverviewInfo(props: SeriesIndexOverviewInfoProps) {
<SeriesIndexOverviewInfoRow
title={formatDateTime(nextAiring, longDateFormat, timeFormat)}
iconName={icons.SCHEDULED}
label={getRelativeDate(
nextAiring,
label={getRelativeDate({
date: nextAiring,
shortDateFormat,
showRelativeDates,
{
timeFormat,
timeForToday: true,
}
)}
timeFormat,
timeForToday: true,
})}
/>
)}

View File

@@ -217,7 +217,10 @@ function SeriesIndexPoster(props: SeriesIndexPosterProps) {
timeFormat
)}`}
>
{getRelativeDate(nextAiring, shortDateFormat, showRelativeDates, {
{getRelativeDate({
date: nextAiring,
shortDateFormat,
showRelativeDates,
timeFormat,
timeForToday: true,
})}

View File

@@ -80,7 +80,10 @@ function SeriesIndexPosterInfo(props: SeriesIndexPosterInfoProps) {
timeFormat
)}`}
>
{getRelativeDate(previousAiring, shortDateFormat, showRelativeDates, {
{getRelativeDate({
date: previousAiring,
shortDateFormat,
showRelativeDates,
timeFormat,
timeForToday: true,
})}
@@ -89,15 +92,13 @@ function SeriesIndexPosterInfo(props: SeriesIndexPosterInfoProps) {
}
if (sortKey === 'added' && added) {
const addedDate = getRelativeDate(
added,
const addedDate = getRelativeDate({
date: added,
shortDateFormat,
showRelativeDates,
{
timeFormat,
timeForToday: false,
}
);
timeFormat,
timeForToday: false,
});
return (
<div

View File

@@ -1,49 +0,0 @@
import moment from 'moment';
import formatTime from 'Utilities/Date/formatTime';
import isInNextWeek from 'Utilities/Date/isInNextWeek';
import isToday from 'Utilities/Date/isToday';
import isTomorrow from 'Utilities/Date/isTomorrow';
import isYesterday from 'Utilities/Date/isYesterday';
import translate from 'Utilities/String/translate';
import formatDateTime from './formatDateTime';
function getRelativeDate(date, shortDateFormat, showRelativeDates, { timeFormat, includeSeconds = false, timeForToday = false, includeTime = false } = {}) {
if (!date) {
return null;
}
const isTodayDate = isToday(date);
const time = formatTime(date, timeFormat, { includeMinuteZero: true, includeSeconds });
if (isTodayDate && timeForToday && timeFormat) {
return time;
}
if (!showRelativeDates) {
return moment(date).format(shortDateFormat);
}
if (isYesterday(date)) {
return includeTime ? translate('YesterdayAt', { time } ): translate('Yesterday');
}
if (isTodayDate) {
return includeTime ? translate('TodayAt', { time } ): translate('Today');
}
if (isTomorrow(date)) {
return includeTime ? translate('TomorrowAt', { time } ): translate('Tomorrow');
}
if (isInNextWeek(date)) {
const day = moment(date).format('dddd');
return includeTime ? translate('DayOfWeekAt', { day, time }) : day;
}
return includeTime ?
formatDateTime(date, shortDateFormat, timeFormat, { includeSeconds }) :
moment(date).format(shortDateFormat);
}
export default getRelativeDate;

View File

@@ -0,0 +1,82 @@
import moment from 'moment';
import formatTime from 'Utilities/Date/formatTime';
import isInNextWeek from 'Utilities/Date/isInNextWeek';
import isToday from 'Utilities/Date/isToday';
import isTomorrow from 'Utilities/Date/isTomorrow';
import isYesterday from 'Utilities/Date/isYesterday';
import translate from 'Utilities/String/translate';
import formatDateTime from './formatDateTime';
interface GetRelativeDateOptions {
date?: string;
shortDateFormat: string;
showRelativeDates: boolean;
timeFormat?: string;
includeSeconds?: boolean;
timeForToday?: boolean;
includeTime?: boolean;
}
function getRelativeDate({
date,
shortDateFormat,
showRelativeDates,
timeFormat,
includeSeconds = false,
timeForToday = false,
includeTime = false,
}: GetRelativeDateOptions) {
if (!date) {
return null;
}
if ((includeTime || timeForToday) && !timeFormat) {
throw new Error(
"getRelativeDate: 'timeFormat' is required when 'includeTime' or 'timeForToday' is true"
);
}
const isTodayDate = isToday(date);
const time = timeFormat
? formatTime(date, timeFormat, {
includeMinuteZero: true,
includeSeconds,
})
: '';
if (isTodayDate && timeForToday) {
return time;
}
if (!showRelativeDates) {
return moment(date).format(shortDateFormat);
}
if (isYesterday(date)) {
return includeTime
? translate('YesterdayAt', { time })
: translate('Yesterday');
}
if (isTodayDate) {
return includeTime ? translate('TodayAt', { time }) : translate('Today');
}
if (isTomorrow(date)) {
return includeTime
? translate('TomorrowAt', { time })
: translate('Tomorrow');
}
if (isInNextWeek(date)) {
const day = moment(date).format('dddd');
return includeTime ? translate('DayOfWeekAt', { day, time }) : day;
}
return includeTime
? formatDateTime(date, shortDateFormat, timeFormat, { includeSeconds })
: moment(date).format(shortDateFormat);
}
export default getRelativeDate;

View File

@@ -2074,5 +2074,9 @@
"IndexerSettingsMultiLanguageReleaseHelpText": "¿Qué idiomas están normalmente en un lanzamiento múltiple en este indexador?",
"DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent está reportando archivos faltantes",
"BlocklistFilterHasNoItems": "El filtro de lista de bloqueo seleccionado no contiene elementos",
"HasUnmonitoredSeason": "Tiene temporada sin monitorizar"
"HasUnmonitoredSeason": "Tiene temporada sin monitorizar",
"TomorrowAt": "Mañana a las {time}",
"YesterdayAt": "Ayer a las {time}",
"TodayAt": "Hoy a las {time}",
"DayOfWeekAt": "{day} a las {time}"
}

View File

@@ -205,5 +205,7 @@
"Category": "Categorie",
"BlocklistReleaseHelpText": "Voorkom dat deze release opnieuw wordt gedownload door {appName} door een RSS lijst of een automatische zoekopdracht",
"ChangeCategory": "Verander categorie",
"ChownGroup": "chown groep"
"ChownGroup": "chown groep",
"AutoTaggingSpecificationTag": "Tag",
"AddDelayProfileError": "Mislukt om vertragingsprofiel toe te voegen, probeer het later nog eens."
}

View File

@@ -169,7 +169,7 @@
"Calendar": "Calendário",
"Connect": "Conectar",
"CustomFormats": "Formatos personalizados",
"CutoffUnmet": "Corte não alcançado",
"CutoffUnmet": "Limite não alcançado",
"DownloadClients": "Clientes de download",
"Events": "Eventos",
"General": "Geral",
@@ -493,8 +493,8 @@
"CustomFormatsLoadError": "Não foi possível carregar Formatos Personalizados",
"CustomFormatsSettings": "Configurações de Formatos Personalizados",
"CustomFormatsSettingsSummary": "Configurações e Formatos Personalizados",
"DailyEpisodeFormat": "Formato do Episódio Diário",
"Cutoff": "Corte",
"DailyEpisodeFormat": "Formato do episódio diário",
"Cutoff": "Limite",
"Dash": "Traço",
"Dates": "Datas",
"Debug": "Depuração",
@@ -1448,11 +1448,11 @@
"MissingNoItems": "Nenhum item ausente",
"SearchAll": "Pesquisar Todos",
"UnmonitorSelected": "Não Monitorar os Selecionados",
"CutoffUnmetNoItems": "Nenhum item com corte não atingido",
"CutoffUnmetNoItems": "Nenhum item com limite não atingido",
"MonitorSelected": "Monitorar Selecionados",
"SearchForAllMissingEpisodesConfirmationCount": "Tem certeza de que deseja pesquisar todos os episódios ausentes de {totalRecords}?",
"SearchSelected": "Pesquisar Selecionado",
"CutoffUnmetLoadError": "Erro ao carregar itens de corte não atingidos",
"CutoffUnmetLoadError": "Erro ao carregar itens de limite não atingido",
"MassSearchCancelWarning": "Isso não pode ser cancelado depois de iniciado sem reiniciar {appName} ou desabilitar todos os seus indexadores.",
"SearchForAllMissingEpisodes": "Pesquisar por todos os episódios ausentes",
"SearchForCutoffUnmetEpisodes": "Pesquise todos os episódios que o corte não foi atingido",
@@ -2016,7 +2016,7 @@
"BlocklistReleaseHelpText": "Impede que esta versão seja baixada novamente por {appName} via RSS ou Pesquisa Automática",
"ChangeCategoryHint": "Altera o download para a \"Categoria pós-importação\" do cliente de download",
"ChangeCategoryMultipleHint": "Altera os downloads para a \"Categoria pós-importação' do cliente de download",
"DatabaseMigration": "Migração de Banco de Dados",
"DatabaseMigration": "Migração de banco de dados",
"DoNotBlocklistHint": "Remover sem colocar na lista de bloqueio",
"ChangeCategory": "Alterar categoria",
"DoNotBlocklist": "Não coloque na lista de bloqueio",
@@ -2073,5 +2073,10 @@
"AutoTaggingSpecificationTag": "Etiqueta",
"IndexerSettingsMultiLanguageRelease": "Multi Idiomas",
"DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent está relatando arquivos perdidos",
"BlocklistFilterHasNoItems": "O filtro selecionado para a lista de bloqueio não contém itens"
"BlocklistFilterHasNoItems": "O filtro selecionado para a lista de bloqueio não contém itens",
"DayOfWeekAt": "{day} às {time}",
"TodayAt": "Hoje às {time}",
"TomorrowAt": "Amanhã às {time}",
"HasUnmonitoredSeason": "Tem Temporada Não Monitorada",
"YesterdayAt": "Ontem às {time}"
}

View File

@@ -5,5 +5,7 @@
"ApiKeyValidationHealthCheckMessage": "Hãy cập nhật mã API để dài ít nhất {length} kí tự. Bạn có thể làm điều này trong cài đặt hoặc trong tập config",
"AppDataLocationHealthCheckMessage": "Việc cập nhật sẽ không xảy ra để tránh xóa AppData khi cập nhật",
"ApplyChanges": "Áp dụng thay đổi",
"AutomaticAdd": "Tự động thêm"
"AutomaticAdd": "Tự động thêm",
"CalendarOptions": "Tùy chọn lịch",
"UpdateMechanismHelpText": "Sử dụng trình cập nhật tích hợp của {appName} hoặc một tập lệnh"
}

View File

@@ -161,7 +161,7 @@
"CountIndexersSelected": "已选择 {count} 个索引器",
"CurrentlyInstalled": "已安装",
"CustomFormats": "自定义命名格式",
"CutoffUnmet": "未达截止条件",
"CutoffUnmet": "未达设定标准",
"Date": "日期",
"DeleteBackup": "删除备份",
"DeleteCustomFormat": "删除自定义命名格式",
@@ -293,7 +293,7 @@
"RootFolderMultipleMissingHealthCheckMessage": "多个根目录缺失:{rootFolderPaths}",
"SkipRedownloadHelpText": "阻止{appName}尝试下载此项目的替代版本",
"Tasks": "任务",
"Wanted": "已追踪",
"Wanted": "待获取",
"Yes": "确定",
"AbsoluteEpisodeNumbers": "准确的集数",
"RemoveCompleted": "移除已完成",
@@ -688,7 +688,7 @@
"ICalShowAsAllDayEventsHelpText": "事件将以全天事件的形式显示在日历中",
"ICalSeasonPremieresOnlyHelpText": "每季中只有第一集会出现在订阅中",
"IconForFinalesHelpText": "根据可用的集信息为完结的剧集或季显示图标",
"IconForCutoffUnmet": "未达截止条件的图标",
"IconForCutoffUnmet": "未达设定标准的图标",
"IconForCutoffUnmetHelpText": "终止监控条件未满足前为文件显示图标",
"IconForFinales": "剧集或季完结的图标",
"Images": "图像",
@@ -1459,8 +1459,8 @@
"TotalFileSize": "文件总大小",
"TotalRecords": "记录总数: {totalRecords}",
"Trace": "追踪",
"CutoffUnmetLoadError": "加载未达截止条件项目错误",
"CutoffUnmetNoItems": "没有未达截止条件的项目",
"CutoffUnmetLoadError": "加载未达设定标准项目时出错",
"CutoffUnmetNoItems": "没有未达设定标准的项目",
"DeleteSeriesFolderHelpText": "删除剧集文件夹及其所含文件",
"DeleteSeriesModalHeader": "删除 - {title}",
"DeletedSeriesDescription": "剧集已从 TheTVDB 移除",
@@ -1830,5 +1830,11 @@
"AutoTaggingSpecificationStatus": "状态",
"ClickToChangeIndexerFlags": "点击修改索引器标志",
"ConnectionSettingsUrlBaseHelpText": "向 {clientName} url 添加前缀,例如 {url}",
"BlocklistFilterHasNoItems": "所选的黑名单过滤器没有项目"
"BlocklistFilterHasNoItems": "所选的黑名单过滤器没有项目",
"CustomFormatsSpecificationReleaseGroup": "发布组",
"MetadataSettingsSeriesMetadata": "季元数据",
"CustomFormatsSpecificationResolution": "分辨率",
"CustomFormatsSpecificationSource": "来源",
"ClickToChangeReleaseType": "点击更改发布类型",
"CustomFormatsSettingsTriggerInfo": "当一个发布版本或文件至少匹配其中一个条件时,自定义格式将会被应用到这个版本或文件上。"
}

View File

@@ -10132,6 +10132,9 @@
"onHealthIssue": {
"type": "boolean"
},
"includeHealthWarnings": {
"type": "boolean"
},
"onHealthRestored": {
"type": "boolean"
},
@@ -10177,9 +10180,6 @@
"supportsOnManualInteractionRequired": {
"type": "boolean"
},
"includeHealthWarnings": {
"type": "boolean"
},
"testCommand": {
"type": "string",
"nullable": true