diff --git a/frontend/src/MovieFile/MediaInfo.js b/frontend/src/MovieFile/MediaInfo.js
index fa6f87f041..9aa4d1d7ff 100644
--- a/frontend/src/MovieFile/MediaInfo.js
+++ b/frontend/src/MovieFile/MediaInfo.js
@@ -1,6 +1,7 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
+import getLanguageName from 'Utilities/String/getLanguageName';
import * as mediaInfoTypes from './mediaInfoTypes';
function formatLanguages(languages) {
@@ -8,7 +9,7 @@ function formatLanguages(languages) {
return null;
}
- const splitLanguages = _.uniq(languages.split(' / '));
+ const splitLanguages = _.uniq(languages.split('/')).map((l) => getLanguageName(l));
if (splitLanguages.length > 3) {
return (
@@ -39,18 +40,15 @@ function MediaInfo(props) {
return (
{
- !!audioCodec &&
- audioCodec
+ audioCodec ? audioCodec : ''
}
{
- !!audioCodec && !!audioChannels &&
- ' - '
+ audioCodec && audioChannels ? ' - ' : ''
}
{
- !!audioChannels &&
- audioChannels.toFixed(1)
+ audioChannels ? audioChannels.toFixed(1) : ''
}
);
diff --git a/frontend/src/Settings/UI/UISettingsConnector.js b/frontend/src/Settings/UI/UISettingsConnector.js
index ea9194f8cd..0f891dd7d3 100644
--- a/frontend/src/Settings/UI/UISettingsConnector.js
+++ b/frontend/src/Settings/UI/UISettingsConnector.js
@@ -4,30 +4,34 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { clearPendingChanges } from 'Store/Actions/baseActions';
import { fetchUISettings, saveUISettings, setUISettingsValue } from 'Store/Actions/settingsActions';
+import createLanguagesSelector from 'Store/Selectors/createLanguagesSelector';
import createSettingsSectionSelector from 'Store/Selectors/createSettingsSectionSelector';
import UISettings from './UISettings';
const SECTION = 'ui';
+const FILTER_LANGUAGES = ['Any', 'Unknown', 'Original'];
-function createLanguagesSelector() {
+function createFilteredLanguagesSelector() {
return createSelector(
- (state) => state.settings.languages,
+ createLanguagesSelector(),
(languages) => {
- const items = languages.items;
- const filterItems = ['Any', 'Unknown'];
-
- if (!items) {
+ if (!languages || !languages.items) {
return [];
}
- const newItems = items.filter((lang) => !filterItems.includes(lang.name)).map((item) => {
- return {
- key: item.id,
- value: item.name
- };
- });
+ const newItems = languages.items
+ .filter((lang) => !FILTER_LANGUAGES.includes(lang.name))
+ .map((item) => {
+ return {
+ key: item.id,
+ value: item.name
+ };
+ });
- return newItems;
+ return {
+ ...languages,
+ items: newItems
+ };
}
);
}
@@ -36,12 +40,15 @@ function createMapStateToProps() {
return createSelector(
(state) => state.settings.advancedSettings,
createSettingsSectionSelector(SECTION),
- createLanguagesSelector(),
+ createFilteredLanguagesSelector(),
(advancedSettings, sectionSettings, languages) => {
return {
advancedSettings,
- languages,
- ...sectionSettings
+ languages: languages.items,
+ isLanguagesPopulated: languages.isPopulated,
+ ...sectionSettings,
+ isFetching: sectionSettings.isFetching || languages.isFetching,
+ error: sectionSettings.error || languages.error
};
}
);
diff --git a/frontend/src/Utilities/String/getLanguageName.js b/frontend/src/Utilities/String/getLanguageName.js
new file mode 100644
index 0000000000..db957e6438
--- /dev/null
+++ b/frontend/src/Utilities/String/getLanguageName.js
@@ -0,0 +1,27 @@
+import createAjaxRequest from 'Utilities/createAjaxRequest';
+
+function getTranslations() {
+ return createAjaxRequest({
+ global: false,
+ dataType: 'json',
+ url: '/localization/language'
+ }).request;
+}
+
+let languageNames = new Intl.DisplayNames(['en'], { type: 'language' });
+
+getTranslations().then((data) => {
+ const names = new Intl.DisplayNames([data.identifier], { type: 'language' });
+
+ if (names) {
+ languageNames = names;
+ }
+});
+
+export default function getLanguageName(code) {
+ if (!languageNames) {
+ return code;
+ }
+
+ return languageNames.of(code) ?? code;
+}
diff --git a/src/NzbDrone.Core/Localization/LocalizationService.cs b/src/NzbDrone.Core/Localization/LocalizationService.cs
index 38a2c0a69c..8633ea45cd 100644
--- a/src/NzbDrone.Core/Localization/LocalizationService.cs
+++ b/src/NzbDrone.Core/Localization/LocalizationService.cs
@@ -20,6 +20,7 @@ public interface ILocalizationService
Dictionary GetLocalizationDictionary();
string GetLocalizedString(string phrase);
string GetLocalizedString(string phrase, string language);
+ string GetLanguageIdentifier();
}
public class LocalizationService : ILocalizationService, IHandleAsync
@@ -45,14 +46,14 @@ public LocalizationService(IConfigService configService,
public Dictionary GetLocalizationDictionary()
{
- var language = GetSetLanguageFileName();
+ var language = GetLanguageFileName();
return GetLocalizationDictionary(language);
}
public string GetLocalizedString(string phrase)
{
- var language = GetSetLanguageFileName();
+ var language = GetLanguageFileName();
return GetLocalizedString(phrase, language);
}
@@ -66,7 +67,7 @@ public string GetLocalizedString(string phrase, string language)
if (language.IsNullOrWhiteSpace())
{
- language = GetSetLanguageFileName();
+ language = GetLanguageFileName();
}
if (language == null)
@@ -84,19 +85,24 @@ public string GetLocalizedString(string phrase, string language)
return phrase;
}
- private string GetSetLanguageFileName()
+ public string GetLanguageIdentifier()
{
var isoLanguage = IsoLanguages.Get((Language)_configService.UILanguage);
var language = isoLanguage.TwoLetterCode;
if (isoLanguage.CountryCode.IsNotNullOrWhiteSpace())
{
- language = string.Format("{0}_{1}", language, isoLanguage.CountryCode);
+ language = $"{language}-{isoLanguage.CountryCode.ToUpperInvariant()}";
}
return language;
}
+ private string GetLanguageFileName()
+ {
+ return GetLanguageIdentifier().Replace("-", "_").ToLowerInvariant();
+ }
+
private Dictionary GetLocalizationDictionary(string language)
{
if (string.IsNullOrEmpty(language))
diff --git a/src/NzbDrone.Core/Parser/IsoLanguage.cs b/src/NzbDrone.Core/Parser/IsoLanguage.cs
index 6f919c5726..c9d0f740ea 100644
--- a/src/NzbDrone.Core/Parser/IsoLanguage.cs
+++ b/src/NzbDrone.Core/Parser/IsoLanguage.cs
@@ -9,6 +9,7 @@ public class IsoLanguage
public string CountryCode { get; set; }
public string EnglishName { get; set; }
public Language Language { get; set; }
+ public string CountyCodeLower => CountryCode?.ToLower();
public IsoLanguage(string twoLetterCode, string countryCode, string threeLetterCode, string englishName, Language language)
{
diff --git a/src/Radarr.Api.V3/Localization/LocalizationController.cs b/src/Radarr.Api.V3/Localization/LocalizationController.cs
index b12f074b5e..9fb330f72e 100644
--- a/src/Radarr.Api.V3/Localization/LocalizationController.cs
+++ b/src/Radarr.Api.V3/Localization/LocalizationController.cs
@@ -25,5 +25,17 @@ public string GetLocalizationDictionary()
{
return JsonSerializer.Serialize(_localizationService.GetLocalizationDictionary().ToResource(), _serializerSettings);
}
+
+ [HttpGet("language")]
+ [Produces("application/json")]
+ public LocalizationLanguageResource GetLanguage()
+ {
+ var identifier = _localizationService.GetLanguageIdentifier();
+
+ return new LocalizationLanguageResource
+ {
+ Identifier = identifier
+ };
+ }
}
}
diff --git a/src/Radarr.Api.V3/Localization/LocalizationLanguageResource.cs b/src/Radarr.Api.V3/Localization/LocalizationLanguageResource.cs
new file mode 100644
index 0000000000..e331022f9a
--- /dev/null
+++ b/src/Radarr.Api.V3/Localization/LocalizationLanguageResource.cs
@@ -0,0 +1,7 @@
+namespace Radarr.Api.V3.Localization
+{
+ public class LocalizationLanguageResource
+ {
+ public string Identifier { get; set; }
+ }
+}