From 7f42b4e8b6be40f6dcf96a058793a836e49bc1ee Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Mon, 4 Mar 2024 13:46:12 -0500 Subject: [PATCH 1/2] Remove dlna configuration pages --- .../drawer/sections/DevicesDrawerSection.tsx | 26 +- src/apps/dashboard/routes/_asyncRoutes.ts | 1 + src/apps/dashboard/routes/_legacyRoutes.ts | 18 - src/apps/dashboard/routes/_redirects.ts | 4 +- src/apps/dashboard/routes/dlna.tsx | 33 + src/controllers/dashboard/dlna/profile.html | 584 ------------ src/controllers/dashboard/dlna/profile.js | 830 ------------------ src/controllers/dashboard/dlna/profiles.html | 32 - src/controllers/dashboard/dlna/profiles.js | 93 -- src/controllers/dashboard/dlna/settings.html | 69 -- src/controllers/dashboard/dlna/settings.js | 60 -- src/strings/en-us.json | 120 +-- 12 files changed, 39 insertions(+), 1831 deletions(-) create mode 100644 src/apps/dashboard/routes/dlna.tsx delete mode 100644 src/controllers/dashboard/dlna/profile.html delete mode 100644 src/controllers/dashboard/dlna/profile.js delete mode 100644 src/controllers/dashboard/dlna/profiles.html delete mode 100644 src/controllers/dashboard/dlna/profiles.js delete mode 100644 src/controllers/dashboard/dlna/settings.html delete mode 100644 src/controllers/dashboard/dlna/settings.js diff --git a/src/apps/dashboard/components/drawer/sections/DevicesDrawerSection.tsx b/src/apps/dashboard/components/drawer/sections/DevicesDrawerSection.tsx index 6cc7ab79fc..6d788f6b40 100644 --- a/src/apps/dashboard/components/drawer/sections/DevicesDrawerSection.tsx +++ b/src/apps/dashboard/components/drawer/sections/DevicesDrawerSection.tsx @@ -1,26 +1,15 @@ -import { Devices, Analytics, Input, ExpandLess, ExpandMore } from '@mui/icons-material'; -import Collapse from '@mui/material/Collapse'; +import { Devices, Analytics, Input } from '@mui/icons-material'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import ListSubheader from '@mui/material/ListSubheader'; import React from 'react'; -import { useLocation } from 'react-router-dom'; import ListItemLink from 'components/ListItemLink'; import globalize from 'scripts/globalize'; -const DLNA_PATHS = [ - '/dashboard/dlna', - '/dashboard/dlna/profiles' -]; - const DevicesDrawerSection = () => { - const location = useLocation(); - - const isDlnaSectionOpen = DLNA_PATHS.includes(location.pathname); - return ( { - + - {isDlnaSectionOpen ? : } - - - - - - - - - - ); }; diff --git a/src/apps/dashboard/routes/_asyncRoutes.ts b/src/apps/dashboard/routes/_asyncRoutes.ts index 9abd6b75e3..0e33b2a0d4 100644 --- a/src/apps/dashboard/routes/_asyncRoutes.ts +++ b/src/apps/dashboard/routes/_asyncRoutes.ts @@ -2,6 +2,7 @@ import { AsyncRouteType, type AsyncRoute } from 'components/router/AsyncRoute'; export const ASYNC_ADMIN_ROUTES: AsyncRoute[] = [ { path: 'activity', type: AsyncRouteType.Dashboard }, + { path: 'dlna', type: AsyncRouteType.Dashboard }, { path: 'notifications', type: AsyncRouteType.Dashboard }, { path: 'users', type: AsyncRouteType.Dashboard }, { path: 'users/access', type: AsyncRouteType.Dashboard }, diff --git a/src/apps/dashboard/routes/_legacyRoutes.ts b/src/apps/dashboard/routes/_legacyRoutes.ts index efdd543a42..6adf825dc3 100644 --- a/src/apps/dashboard/routes/_legacyRoutes.ts +++ b/src/apps/dashboard/routes/_legacyRoutes.ts @@ -31,24 +31,6 @@ export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [ controller: 'dashboard/devices/device', view: 'dashboard/devices/device.html' } - }, { - path: 'dlna/profiles/edit', - pageProps: { - controller: 'dashboard/dlna/profile', - view: 'dashboard/dlna/profile.html' - } - }, { - path: 'dlna/profiles', - pageProps: { - controller: 'dashboard/dlna/profiles', - view: 'dashboard/dlna/profiles.html' - } - }, { - path: 'dlna', - pageProps: { - controller: 'dashboard/dlna/settings', - view: 'dashboard/dlna/settings.html' - } }, { path: 'plugins/add', pageProps: { diff --git a/src/apps/dashboard/routes/_redirects.ts b/src/apps/dashboard/routes/_redirects.ts index 94211c79c2..b7fdf07218 100644 --- a/src/apps/dashboard/routes/_redirects.ts +++ b/src/apps/dashboard/routes/_redirects.ts @@ -8,8 +8,8 @@ export const REDIRECTS: Redirect[] = [ { from: 'dashboardgeneral.html', to: '/dashboard/settings' }, { from: 'device.html', to: '/dashboard/devices/edit' }, { from: 'devices.html', to: '/dashboard/devices' }, - { from: 'dlnaprofile.html', to: '/dashboard/dlna/profiles/edit' }, - { from: 'dlnaprofiles.html', to: '/dashboard/dlna/profiles' }, + { from: 'dlnaprofile.html', to: '/dashboard/dlna' }, + { from: 'dlnaprofiles.html', to: '/dashboard/dlna' }, { from: 'dlnasettings.html', to: '/dashboard/dlna' }, { from: 'edititemmetadata.html', to: '/metadata' }, { from: 'encodingsettings.html', to: '/dashboard/playback/transcoding' }, diff --git a/src/apps/dashboard/routes/dlna.tsx b/src/apps/dashboard/routes/dlna.tsx new file mode 100644 index 0000000000..fec7d2fdb0 --- /dev/null +++ b/src/apps/dashboard/routes/dlna.tsx @@ -0,0 +1,33 @@ +import Alert from '@mui/material/Alert/Alert'; +import Box from '@mui/material/Box/Box'; +import Button from '@mui/material/Button/Button'; +import React from 'react'; +import { Link } from 'react-router-dom'; + +import Page from 'components/Page'; +import globalize from 'scripts/globalize'; + +const DlnaPage = () => ( + +
+

DLNA

+ + + {globalize.translate('DlnaMovedMessage')} + + + +
+
+); + +export default DlnaPage; diff --git a/src/controllers/dashboard/dlna/profile.html b/src/controllers/dashboard/dlna/profile.html deleted file mode 100644 index 237874e156..0000000000 --- a/src/controllers/dashboard/dlna/profile.html +++ /dev/null @@ -1,584 +0,0 @@ -
-
-
-
-
-
-

${HeaderProfileInformation}

-
-
- -
-
-
- -
-
- -
${LabelUserLibraryHelp}
-
-
-

${LabelSupportedMediaTypes}

-
- - - -
-
-
-
- -
${LabelMaxStreamingBitrateHelp}
-
-
- -
${LabelMusicStreamingTranscodingBitrateHelp}
-
-
- - -
${OptionIgnoreTranscodeByteRangeRequestsHelp}
-
-
-
-

${HeaderIdentificationCriteriaHelp}

-
- -
${LabelIdentificationFieldHelp}
-
-
- -
${LabelIdentificationFieldHelp}
-
-
- -
${LabelIdentificationFieldHelp}
-
-
- -
${LabelIdentificationFieldHelp}
-
-
- -
${LabelIdentificationFieldHelp}
-
-
- -
${LabelIdentificationFieldHelp}
-
-
- -
${LabelIdentificationFieldHelp}
-
-
- -
${LabelIdentificationFieldHelp}
-
-
- -
${LabelIdentificationFieldHelp}
-
-
-

${HeaderHttpHeaders}

- -
-
-
-
-
-
-
-
- -
${OptionPlainStorageFoldersHelp}
-
-
- -
${OptionPlainVideoItemsHelp}
-
-
-
-
-
-
- -
${LabelEmbedAlbumArtDidlHelp}
-
-
- -
${LabelEnableSingleImageInDidlLimitHelp}
-
-
- -
${LabelAlbumArtHelp}
-
-
- -
${LabelAlbumArtMaxResHelp}
-
-
- -
${LabelAlbumArtMaxResHelp}
-
-
- -
${LabelIconMaxResHelp}
-
-
- -
${LabelIconMaxResHelp}
-
-
-
-
-
-

${HeaderProfileServerSettingsHelp}

-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
${LabelProtocolInfoHelp}
-
-
- -
${LabelXDlnaCapHelp}
-
-
- -
${LabelXDlnaDocHelp}
-
-
- -
${LabelSonyAggregationFlagsHelp}
-
-
-
-
-
-

${HeaderSubtitleProfilesHelp}

- -
-
-
-
-
-
-
-

${HeaderXmlDocumentAttributes}

- -
-
-
${XmlDocumentAttributeListHelp}
-
-
-
-
-
-

${HeaderDirectPlayProfileHelp}

- -
-
-
-
-

${HeaderTranscodingProfileHelp}

- -
-
-
-
-

${HeaderContainerProfileHelp}

- -
-
-
-
-

${HeaderCodecProfileHelp}

- -
-
-
-
-

${HeaderResponseProfileHelp}

- -
-
-
-
-
- - -
-
-
-
-
-
-
-

${HeaderDirectPlayProfile}

-
-
-
- -
-
- -
${LabelProfileContainersHelp}
-
-
-
- -
${LabelProfileCodecsHelp}
-
-
-
-
- -
${LabelProfileCodecsHelp}
-
-
-

- - -

-
-
-
-
-
-
-

${HeaderTranscodingProfile}

-
-
-
- - - - -
-
- - -

- - -

-
-
-
-
-
-
-

${HeaderContainerProfile}

-
-
-

${HeaderContainerProfileHelp}

-
-
- -
-
- -
${LabelProfileContainersHelp}
-
-
- -

- - -

-
-
-
-
-
-
-

${HeaderCodecProfile}

-
-
-

${HeaderCodecProfileHelp}

-
- -
-
- -
${LabelProfileCodecsHelp}
-
-

- - -

-
-
-
-
-
-
-

${HeaderResponseProfile}

-
-
-
- -
-
- -
${LabelProfileContainersHelp}
-
-
-
- -
${LabelProfileCodecsHelp}
-
-
-
-
- -
${LabelProfileCodecsHelp}
-
-
-

- - -

-
-
-
-
-
-
-

${HeaderIdentificationHeader}

-
-
-
- -
-
- -
-
- -
-

- - -

-
-
-
-
-
-
-

${HeaderXmlDocumentAttribute}

-
-
-
- -
-
- -
-

- - -

-
-
-
-
-
-
-

${HeaderSubtitleProfile}

-
-
-
- -
${LabelSubtitleFormatHelp}
-
-
- -
-
- -
-

- - -

-
-
-
-
diff --git a/src/controllers/dashboard/dlna/profile.js b/src/controllers/dashboard/dlna/profile.js deleted file mode 100644 index 0f92a3200c..0000000000 --- a/src/controllers/dashboard/dlna/profile.js +++ /dev/null @@ -1,830 +0,0 @@ -import escapeHtml from 'escape-html'; -import 'jquery'; -import loading from '../../../components/loading/loading'; -import globalize from '../../../scripts/globalize'; -import '../../../elements/emby-select/emby-select'; -import '../../../elements/emby-button/emby-button'; -import '../../../elements/emby-input/emby-input'; -import '../../../elements/emby-checkbox/emby-checkbox'; -import '../../../components/listview/listview.scss'; -import Dashboard from '../../../utils/dashboard'; -import toast from '../../../components/toast/toast'; -import { getParameterByName } from '../../../utils/url.ts'; - -function loadProfile(page) { - loading.show(); - const promise1 = getProfile(); - const promise2 = ApiClient.getUsers(); - Promise.all([promise1, promise2]).then(function (responses) { - currentProfile = responses[0]; - renderProfile(page, currentProfile, responses[1]); - loading.hide(); - }); -} - -function getProfile() { - const id = getParameterByName('id'); - const url = id ? 'Dlna/Profiles/' + id : 'Dlna/Profiles/Default'; - return ApiClient.getJSON(ApiClient.getUrl(url)); -} - -function renderProfile(page, profile, users) { - $('#txtName', page).val(profile.Name); - $('.chkMediaType', page).each(function () { - this.checked = (profile.SupportedMediaTypes || '').split(',').indexOf(this.getAttribute('data-value')) != -1; - }); - $('#chkEnableAlbumArtInDidl', page).prop('checked', profile.EnableAlbumArtInDidl); - $('#chkEnableSingleImageLimit', page).prop('checked', profile.EnableSingleAlbumArtLimit); - renderXmlDocumentAttributes(page, profile.XmlRootAttributes || []); - const idInfo = profile.Identification || {}; - renderIdentificationHeaders(page, idInfo.Headers || []); - renderSubtitleProfiles(page, profile.SubtitleProfiles || []); - $('#txtInfoFriendlyName', page).val(profile.FriendlyName || ''); - $('#txtInfoModelName', page).val(profile.ModelName || ''); - $('#txtInfoModelNumber', page).val(profile.ModelNumber || ''); - $('#txtInfoModelDescription', page).val(profile.ModelDescription || ''); - $('#txtInfoModelUrl', page).val(profile.ModelUrl || ''); - $('#txtInfoManufacturer', page).val(profile.Manufacturer || ''); - $('#txtInfoManufacturerUrl', page).val(profile.ManufacturerUrl || ''); - $('#txtInfoSerialNumber', page).val(profile.SerialNumber || ''); - $('#txtIdFriendlyName', page).val(idInfo.FriendlyName || ''); - $('#txtIdModelName', page).val(idInfo.ModelName || ''); - $('#txtIdModelNumber', page).val(idInfo.ModelNumber || ''); - $('#txtIdModelDescription', page).val(idInfo.ModelDescription || ''); - $('#txtIdModelUrl', page).val(idInfo.ModelUrl || ''); - $('#txtIdManufacturer', page).val(idInfo.Manufacturer || ''); - $('#txtIdManufacturerUrl', page).val(idInfo.ManufacturerUrl || ''); - $('#txtIdSerialNumber', page).val(idInfo.SerialNumber || ''); - $('#txtIdDeviceDescription', page).val(idInfo.DeviceDescription || ''); - $('#txtAlbumArtPn', page).val(profile.AlbumArtPn || ''); - $('#txtAlbumArtMaxWidth', page).val(profile.MaxAlbumArtWidth || ''); - $('#txtAlbumArtMaxHeight', page).val(profile.MaxAlbumArtHeight || ''); - $('#txtIconMaxWidth', page).val(profile.MaxIconWidth || ''); - $('#txtIconMaxHeight', page).val(profile.MaxIconHeight || ''); - $('#chkIgnoreTranscodeByteRangeRequests', page).prop('checked', profile.IgnoreTranscodeByteRangeRequests); - $('#txtMaxAllowedBitrate', page).val(profile.MaxStreamingBitrate || ''); - $('#txtMusicStreamingTranscodingBitrate', page).val(profile.MusicStreamingTranscodingBitrate || ''); - $('#chkRequiresPlainFolders', page).prop('checked', profile.RequiresPlainFolders); - $('#chkRequiresPlainVideoItems', page).prop('checked', profile.RequiresPlainVideoItems); - $('#txtProtocolInfo', page).val(profile.ProtocolInfo || ''); - $('#txtXDlnaCap', page).val(profile.XDlnaCap || ''); - $('#txtXDlnaDoc', page).val(profile.XDlnaDoc || ''); - $('#txtSonyAggregationFlags', page).val(profile.SonyAggregationFlags || ''); - profile.DirectPlayProfiles = profile.DirectPlayProfiles || []; - profile.TranscodingProfiles = profile.TranscodingProfiles || []; - profile.ContainerProfiles = profile.ContainerProfiles || []; - profile.CodecProfiles = profile.CodecProfiles || []; - profile.ResponseProfiles = profile.ResponseProfiles || []; - const usersHtml = '' + users.map(function (u) { - return ''; - }).join(''); - $('#selectUser', page).html(usersHtml).val(profile.UserId || ''); - renderSubProfiles(page, profile); -} - -function renderIdentificationHeaders(page, headers) { - let index = 0; - const html = '
' + headers.map(function (h) { - let li = '
'; - li += ''; - li += '
'; - li += '

' + escapeHtml(h.Name + ': ' + (h.Value || '')) + '

'; - li += '
' + escapeHtml(h.Match || '') + '
'; - li += '
'; - li += ''; - li += '
'; - index++; - return li; - }).join('') + '
'; - const elem = $('.httpHeaderIdentificationList', page).html(html).trigger('create'); - $('.btnDeleteIdentificationHeader', elem).on('click', function () { - const itemIndex = parseInt(this.getAttribute('data-index'), 10); - currentProfile.Identification.Headers.splice(itemIndex, 1); - renderIdentificationHeaders(page, currentProfile.Identification.Headers); - }); -} - -function openPopup(elem) { - elem.classList.remove('hide'); -} - -function closePopup(elem) { - elem.classList.add('hide'); -} - -function editIdentificationHeader(page, header) { - isSubProfileNew = header == null; - header = header || {}; - currentSubProfile = header; - const popup = $('#identificationHeaderPopup', page); - $('#txtIdentificationHeaderName', popup).val(header.Name || ''); - $('#txtIdentificationHeaderValue', popup).val(header.Value || ''); - $('#selectMatchType', popup).val(header.Match || 'Equals'); - openPopup(popup[0]); -} - -function saveIdentificationHeader(page) { - currentSubProfile.Name = $('#txtIdentificationHeaderName', page).val(); - currentSubProfile.Value = $('#txtIdentificationHeaderValue', page).val(); - currentSubProfile.Match = $('#selectMatchType', page).val(); - - if (isSubProfileNew) { - currentProfile.Identification = currentProfile.Identification || {}; - currentProfile.Identification.Headers = currentProfile.Identification.Headers || []; - currentProfile.Identification.Headers.push(currentSubProfile); - } - - renderIdentificationHeaders(page, currentProfile.Identification.Headers); - currentSubProfile = null; - closePopup($('#identificationHeaderPopup', page)[0]); -} - -function renderXmlDocumentAttributes(page, attribute) { - const html = '
' + attribute.map(function (h) { - let li = '
'; - li += ''; - li += '
'; - li += '

' + escapeHtml(h.Name + ' = ' + (h.Value || '')) + '

'; - li += '
'; - li += ''; - li += '
'; - return li; - }).join('') + '
'; - const elem = $('.xmlDocumentAttributeList', page).html(html).trigger('create'); - $('.btnDeleteXmlAttribute', elem).on('click', function () { - const itemIndex = parseInt(this.getAttribute('data-index'), 10); - currentProfile.XmlRootAttributes.splice(itemIndex, 1); - renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes); - }); -} - -function editXmlDocumentAttribute(page, attribute) { - isSubProfileNew = attribute == null; - attribute = attribute || {}; - currentSubProfile = attribute; - const popup = $('#xmlAttributePopup', page); - $('#txtXmlAttributeName', popup).val(attribute.Name || ''); - $('#txtXmlAttributeValue', popup).val(attribute.Value || ''); - openPopup(popup[0]); -} - -function saveXmlDocumentAttribute(page) { - currentSubProfile.Name = $('#txtXmlAttributeName', page).val(); - currentSubProfile.Value = $('#txtXmlAttributeValue', page).val(); - - if (isSubProfileNew) { - currentProfile.XmlRootAttributes.push(currentSubProfile); - } - - renderXmlDocumentAttributes(page, currentProfile.XmlRootAttributes); - currentSubProfile = null; - closePopup($('#xmlAttributePopup', page)[0]); -} - -function renderSubtitleProfiles(page, profiles) { - let index = 0; - const html = '
' + profiles.map(function (h) { - let li = '
'; - li += ''; - li += '
'; - li += '

' + escapeHtml(h.Format || '') + '

'; - li += '
'; - li += ''; - li += '
'; - index++; - return li; - }).join('') + '
'; - const elem = $('.subtitleProfileList', page).html(html).trigger('create'); - $('.btnDeleteProfile', elem).on('click', function () { - const itemIndex = parseInt(this.getAttribute('data-index'), 10); - currentProfile.SubtitleProfiles.splice(itemIndex, 1); - renderSubtitleProfiles(page, currentProfile.SubtitleProfiles); - }); - $('.lnkEditSubProfile', elem).on('click', function () { - const itemIndex = parseInt(this.getAttribute('data-index'), 10); - editSubtitleProfile(page, currentProfile.SubtitleProfiles[itemIndex]); - }); -} - -function editSubtitleProfile(page, profile) { - isSubProfileNew = profile == null; - profile = profile || {}; - currentSubProfile = profile; - const popup = $('#subtitleProfilePopup', page); - $('#txtSubtitleProfileFormat', popup).val(profile.Format || ''); - $('#selectSubtitleProfileMethod', popup).val(profile.Method || ''); - $('#selectSubtitleProfileDidlMode', popup).val(profile.DidlMode || ''); - openPopup(popup[0]); -} - -function saveSubtitleProfile(page) { - currentSubProfile.Format = $('#txtSubtitleProfileFormat', page).val(); - currentSubProfile.Method = $('#selectSubtitleProfileMethod', page).val(); - currentSubProfile.DidlMode = $('#selectSubtitleProfileDidlMode', page).val(); - - if (isSubProfileNew) { - currentProfile.SubtitleProfiles.push(currentSubProfile); - } - - renderSubtitleProfiles(page, currentProfile.SubtitleProfiles); - currentSubProfile = null; - closePopup($('#subtitleProfilePopup', page)[0]); -} - -function renderSubProfiles(page, profile) { - renderDirectPlayProfiles(page, profile.DirectPlayProfiles); - renderTranscodingProfiles(page, profile.TranscodingProfiles); - renderContainerProfiles(page, profile.ContainerProfiles); - renderCodecProfiles(page, profile.CodecProfiles); - renderResponseProfiles(page, profile.ResponseProfiles); -} - -function saveDirectPlayProfile(page) { - currentSubProfile.Type = $('#selectDirectPlayProfileType', page).val(); - currentSubProfile.Container = $('#txtDirectPlayContainer', page).val(); - currentSubProfile.AudioCodec = $('#txtDirectPlayAudioCodec', page).val(); - currentSubProfile.VideoCodec = $('#txtDirectPlayVideoCodec', page).val(); - - if (isSubProfileNew) { - currentProfile.DirectPlayProfiles.push(currentSubProfile); - } - - renderSubProfiles(page, currentProfile); - currentSubProfile = null; - closePopup($('#popupEditDirectPlayProfile', page)[0]); -} - -function renderDirectPlayProfiles(page, profiles) { - let html = ''; - html += ''; - const elem = $('.directPlayProfiles', page).html(html).trigger('create'); - $('.btnDeleteProfile', elem).on('click', function () { - const index = this.getAttribute('data-profileindex'); - deleteDirectPlayProfile(page, index); - }); - $('.lnkEditSubProfile', elem).on('click', function () { - const index = parseInt(this.getAttribute('data-profileindex'), 10); - editDirectPlayProfile(page, currentProfile.DirectPlayProfiles[index]); - }); -} - -function deleteDirectPlayProfile(page, index) { - currentProfile.DirectPlayProfiles.splice(index, 1); - renderDirectPlayProfiles(page, currentProfile.DirectPlayProfiles); -} - -function editDirectPlayProfile(page, directPlayProfile) { - isSubProfileNew = directPlayProfile == null; - directPlayProfile = directPlayProfile || {}; - currentSubProfile = directPlayProfile; - const popup = $('#popupEditDirectPlayProfile', page); - $('#selectDirectPlayProfileType', popup).val(directPlayProfile.Type || 'Video').trigger('change'); - $('#txtDirectPlayContainer', popup).val(directPlayProfile.Container || ''); - $('#txtDirectPlayAudioCodec', popup).val(directPlayProfile.AudioCodec || ''); - $('#txtDirectPlayVideoCodec', popup).val(directPlayProfile.VideoCodec || ''); - openPopup(popup[0]); -} - -function renderTranscodingProfiles(page, profiles) { - let html = ''; - html += ''; - const elem = $('.transcodingProfiles', page).html(html).trigger('create'); - $('.btnDeleteProfile', elem).on('click', function () { - const index = this.getAttribute('data-profileindex'); - deleteTranscodingProfile(page, index); - }); - $('.lnkEditSubProfile', elem).on('click', function () { - const index = parseInt(this.getAttribute('data-profileindex'), 10); - editTranscodingProfile(page, currentProfile.TranscodingProfiles[index]); - }); -} - -function editTranscodingProfile(page, transcodingProfile) { - isSubProfileNew = transcodingProfile == null; - transcodingProfile = transcodingProfile || {}; - currentSubProfile = transcodingProfile; - const popup = $('#transcodingProfilePopup', page); - $('#selectTranscodingProfileType', popup).val(transcodingProfile.Type || 'Video').trigger('change'); - $('#txtTranscodingContainer', popup).val(transcodingProfile.Container || ''); - $('#txtTranscodingAudioCodec', popup).val(transcodingProfile.AudioCodec || ''); - $('#txtTranscodingVideoCodec', popup).val(transcodingProfile.VideoCodec || ''); - $('#selectTranscodingProtocol', popup).val(transcodingProfile.Protocol || 'Http'); - $('#chkEnableMpegtsM2TsMode', popup).prop('checked', transcodingProfile.EnableMpegtsM2TsMode || false); - $('#chkEstimateContentLength', popup).prop('checked', transcodingProfile.EstimateContentLength || false); - $('#chkReportByteRangeRequests', popup).prop('checked', transcodingProfile.TranscodeSeekInfo == 'Bytes'); - $('.radioTabButton:first', popup).trigger('click'); - openPopup(popup[0]); -} - -function deleteTranscodingProfile(page, index) { - currentProfile.TranscodingProfiles.splice(index, 1); - renderTranscodingProfiles(page, currentProfile.TranscodingProfiles); -} - -function saveTranscodingProfile(page) { - currentSubProfile.Type = $('#selectTranscodingProfileType', page).val(); - currentSubProfile.Container = $('#txtTranscodingContainer', page).val(); - currentSubProfile.AudioCodec = $('#txtTranscodingAudioCodec', page).val(); - currentSubProfile.VideoCodec = $('#txtTranscodingVideoCodec', page).val(); - currentSubProfile.Protocol = $('#selectTranscodingProtocol', page).val(); - currentSubProfile.Context = 'Streaming'; - currentSubProfile.EnableMpegtsM2TsMode = $('#chkEnableMpegtsM2TsMode', page).is(':checked'); - currentSubProfile.EstimateContentLength = $('#chkEstimateContentLength', page).is(':checked'); - currentSubProfile.TranscodeSeekInfo = $('#chkReportByteRangeRequests', page).is(':checked') ? 'Bytes' : 'Auto'; - - if (isSubProfileNew) { - currentProfile.TranscodingProfiles.push(currentSubProfile); - } - - renderSubProfiles(page, currentProfile); - currentSubProfile = null; - closePopup($('#transcodingProfilePopup', page)[0]); -} - -function renderContainerProfiles(page, profiles) { - let html = ''; - html += ''; - const elem = $('.containerProfiles', page).html(html).trigger('create'); - $('.btnDeleteProfile', elem).on('click', function () { - const index = this.getAttribute('data-profileindex'); - deleteContainerProfile(page, index); - }); - $('.lnkEditSubProfile', elem).on('click', function () { - const index = parseInt(this.getAttribute('data-profileindex'), 10); - editContainerProfile(page, currentProfile.ContainerProfiles[index]); - }); -} - -function deleteContainerProfile(page, index) { - currentProfile.ContainerProfiles.splice(index, 1); - renderContainerProfiles(page, currentProfile.ContainerProfiles); -} - -function editContainerProfile(page, containerProfile) { - isSubProfileNew = containerProfile == null; - containerProfile = containerProfile || {}; - currentSubProfile = containerProfile; - const popup = $('#containerProfilePopup', page); - $('#selectContainerProfileType', popup).val(containerProfile.Type || 'Video').trigger('change'); - $('#txtContainerProfileContainer', popup).val(containerProfile.Container || ''); - $('.radioTabButton:first', popup).trigger('click'); - openPopup(popup[0]); -} - -function saveContainerProfile(page) { - currentSubProfile.Type = $('#selectContainerProfileType', page).val(); - currentSubProfile.Container = $('#txtContainerProfileContainer', page).val(); - - if (isSubProfileNew) { - currentProfile.ContainerProfiles.push(currentSubProfile); - } - - renderSubProfiles(page, currentProfile); - currentSubProfile = null; - closePopup($('#containerProfilePopup', page)[0]); -} - -function renderCodecProfiles(page, profiles) { - let html = ''; - html += ''; - const elem = $('.codecProfiles', page).html(html).trigger('create'); - $('.btnDeleteProfile', elem).on('click', function () { - const index = this.getAttribute('data-profileindex'); - deleteCodecProfile(page, index); - }); - $('.lnkEditSubProfile', elem).on('click', function () { - const index = parseInt(this.getAttribute('data-profileindex'), 10); - editCodecProfile(page, currentProfile.CodecProfiles[index]); - }); -} - -function deleteCodecProfile(page, index) { - currentProfile.CodecProfiles.splice(index, 1); - renderCodecProfiles(page, currentProfile.CodecProfiles); -} - -function editCodecProfile(page, codecProfile) { - isSubProfileNew = codecProfile == null; - codecProfile = codecProfile || {}; - currentSubProfile = codecProfile; - const popup = $('#codecProfilePopup', page); - $('#selectCodecProfileType', popup).val(codecProfile.Type || 'Video').trigger('change'); - $('#txtCodecProfileCodec', popup).val(codecProfile.Codec || ''); - $('.radioTabButton:first', popup).trigger('click'); - openPopup(popup[0]); -} - -function saveCodecProfile(page) { - currentSubProfile.Type = $('#selectCodecProfileType', page).val(); - currentSubProfile.Codec = $('#txtCodecProfileCodec', page).val(); - - if (isSubProfileNew) { - currentProfile.CodecProfiles.push(currentSubProfile); - } - - renderSubProfiles(page, currentProfile); - currentSubProfile = null; - closePopup($('#codecProfilePopup', page)[0]); -} - -function renderResponseProfiles(page, profiles) { - let html = ''; - html += ''; - const elem = $('.mediaProfiles', page).html(html).trigger('create'); - $('.btnDeleteProfile', elem).on('click', function () { - const index = this.getAttribute('data-profileindex'); - deleteResponseProfile(page, index); - }); - $('.lnkEditSubProfile', elem).on('click', function () { - const index = parseInt(this.getAttribute('data-profileindex'), 10); - editResponseProfile(page, currentProfile.ResponseProfiles[index]); - }); -} - -function deleteResponseProfile(page, index) { - currentProfile.ResponseProfiles.splice(index, 1); - renderResponseProfiles(page, currentProfile.ResponseProfiles); -} - -function editResponseProfile(page, responseProfile) { - isSubProfileNew = responseProfile == null; - responseProfile = responseProfile || {}; - currentSubProfile = responseProfile; - const popup = $('#responseProfilePopup', page); - $('#selectResponseProfileType', popup).val(responseProfile.Type || 'Video').trigger('change'); - $('#txtResponseProfileContainer', popup).val(responseProfile.Container || ''); - $('#txtResponseProfileAudioCodec', popup).val(responseProfile.AudioCodec || ''); - $('#txtResponseProfileVideoCodec', popup).val(responseProfile.VideoCodec || ''); - $('.radioTabButton:first', popup).trigger('click'); - openPopup(popup[0]); -} - -function saveResponseProfile(page) { - currentSubProfile.Type = $('#selectResponseProfileType', page).val(); - currentSubProfile.Container = $('#txtResponseProfileContainer', page).val(); - currentSubProfile.AudioCodec = $('#txtResponseProfileAudioCodec', page).val(); - currentSubProfile.VideoCodec = $('#txtResponseProfileVideoCodec', page).val(); - - if (isSubProfileNew) { - currentProfile.ResponseProfiles.push(currentSubProfile); - } - - renderSubProfiles(page, currentProfile); - currentSubProfile = null; - closePopup($('#responseProfilePopup', page)[0]); -} - -function saveProfile(page, profile) { - updateProfile(page, profile); - const id = getParameterByName('id'); - - if (id) { - ApiClient.ajax({ - type: 'POST', - url: ApiClient.getUrl('Dlna/Profiles/' + id), - data: JSON.stringify(profile), - contentType: 'application/json' - }).then(function () { - toast(globalize.translate('SettingsSaved')); - }, Dashboard.processErrorResponse); - } else { - ApiClient.ajax({ - type: 'POST', - url: ApiClient.getUrl('Dlna/Profiles'), - data: JSON.stringify(profile), - contentType: 'application/json' - }).then(function () { - Dashboard.navigate('dashboard/dlna/profiles'); - }, Dashboard.processErrorResponse); - } - - loading.hide(); -} - -function updateProfile(page, profile) { - profile.Name = $('#txtName', page).val(); - profile.EnableAlbumArtInDidl = $('#chkEnableAlbumArtInDidl', page).is(':checked'); - profile.EnableSingleAlbumArtLimit = $('#chkEnableSingleImageLimit', page).is(':checked'); - profile.SupportedMediaTypes = $('.chkMediaType:checked', page).get().map(function (c) { - return c.getAttribute('data-value'); - }).join(','); - profile.Identification = profile.Identification || {}; - profile.FriendlyName = $('#txtInfoFriendlyName', page).val(); - profile.ModelName = $('#txtInfoModelName', page).val(); - profile.ModelNumber = $('#txtInfoModelNumber', page).val(); - profile.ModelDescription = $('#txtInfoModelDescription', page).val(); - profile.ModelUrl = $('#txtInfoModelUrl', page).val(); - profile.Manufacturer = $('#txtInfoManufacturer', page).val(); - profile.ManufacturerUrl = $('#txtInfoManufacturerUrl', page).val(); - profile.SerialNumber = $('#txtInfoSerialNumber', page).val(); - profile.Identification.FriendlyName = $('#txtIdFriendlyName', page).val(); - profile.Identification.ModelName = $('#txtIdModelName', page).val(); - profile.Identification.ModelNumber = $('#txtIdModelNumber', page).val(); - profile.Identification.ModelDescription = $('#txtIdModelDescription', page).val(); - profile.Identification.ModelUrl = $('#txtIdModelUrl', page).val(); - profile.Identification.Manufacturer = $('#txtIdManufacturer', page).val(); - profile.Identification.ManufacturerUrl = $('#txtIdManufacturerUrl', page).val(); - profile.Identification.SerialNumber = $('#txtIdSerialNumber', page).val(); - profile.Identification.DeviceDescription = $('#txtIdDeviceDescription', page).val(); - profile.AlbumArtPn = $('#txtAlbumArtPn', page).val(); - profile.MaxAlbumArtWidth = $('#txtAlbumArtMaxWidth', page).val(); - profile.MaxAlbumArtHeight = $('#txtAlbumArtMaxHeight', page).val(); - profile.MaxIconWidth = $('#txtIconMaxWidth', page).val(); - profile.MaxIconHeight = $('#txtIconMaxHeight', page).val(); - profile.RequiresPlainFolders = $('#chkRequiresPlainFolders', page).is(':checked'); - profile.RequiresPlainVideoItems = $('#chkRequiresPlainVideoItems', page).is(':checked'); - profile.IgnoreTranscodeByteRangeRequests = $('#chkIgnoreTranscodeByteRangeRequests', page).is(':checked'); - profile.MaxStreamingBitrate = $('#txtMaxAllowedBitrate', page).val(); - profile.MusicStreamingTranscodingBitrate = $('#txtMusicStreamingTranscodingBitrate', page).val(); - profile.ProtocolInfo = $('#txtProtocolInfo', page).val(); - profile.XDlnaCap = $('#txtXDlnaCap', page).val(); - profile.XDlnaDoc = $('#txtXDlnaDoc', page).val(); - profile.SonyAggregationFlags = $('#txtSonyAggregationFlags', page).val(); - profile.UserId = $('#selectUser', page).val(); -} - -let currentProfile; -let currentSubProfile; -let isSubProfileNew; -const allText = globalize.translate('All'); - -$(document).on('pageinit', '#dlnaProfilePage', function () { - const page = this; - $('.radioTabButton', page).on('click', function () { - $(this).siblings().removeClass('ui-btn-active'); - $(this).addClass('ui-btn-active'); - const value = this.tagName == 'A' ? this.getAttribute('data-value') : this.value; - const elem = $('.' + value, page); - elem.siblings('.tabContent').hide(); - elem.show(); - }); - $('#selectDirectPlayProfileType', page).on('change', function () { - if (this.value == 'Video') { - $('#fldDirectPlayVideoCodec', page).show(); - } else { - $('#fldDirectPlayVideoCodec', page).hide(); - } - - if (this.value == 'Photo') { - $('#fldDirectPlayAudioCodec', page).hide(); - } else { - $('#fldDirectPlayAudioCodec', page).show(); - } - }); - $('#selectTranscodingProfileType', page).on('change', function () { - if (this.value == 'Video') { - $('#fldTranscodingVideoCodec', page).show(); - $('#fldTranscodingProtocol', page).show(); - $('#fldEnableMpegtsM2TsMode', page).show(); - } else { - $('#fldTranscodingVideoCodec', page).hide(); - $('#fldTranscodingProtocol', page).hide(); - $('#fldEnableMpegtsM2TsMode', page).hide(); - } - - if (this.value == 'Photo') { - $('#fldTranscodingAudioCodec', page).hide(); - $('#fldEstimateContentLength', page).hide(); - $('#fldReportByteRangeRequests', page).hide(); - } else { - $('#fldTranscodingAudioCodec', page).show(); - $('#fldEstimateContentLength', page).show(); - $('#fldReportByteRangeRequests', page).show(); - } - }); - $('#selectResponseProfileType', page).on('change', function () { - if (this.value == 'Video') { - $('#fldResponseProfileVideoCodec', page).show(); - } else { - $('#fldResponseProfileVideoCodec', page).hide(); - } - - if (this.value == 'Photo') { - $('#fldResponseProfileAudioCodec', page).hide(); - } else { - $('#fldResponseProfileAudioCodec', page).show(); - } - }); - $('.btnAddDirectPlayProfile', page).on('click', function () { - editDirectPlayProfile(page); - }); - $('.btnAddTranscodingProfile', page).on('click', function () { - editTranscodingProfile(page); - }); - $('.btnAddContainerProfile', page).on('click', function () { - editContainerProfile(page); - }); - $('.btnAddCodecProfile', page).on('click', function () { - editCodecProfile(page); - }); - $('.btnAddResponseProfile', page).on('click', function () { - editResponseProfile(page); - }); - $('.btnAddIdentificationHttpHeader', page).on('click', function () { - editIdentificationHeader(page); - }); - $('.btnAddXmlDocumentAttribute', page).on('click', function () { - editXmlDocumentAttribute(page); - }); - $('.btnAddSubtitleProfile', page).on('click', function () { - editSubtitleProfile(page); - }); - $('.dlnaProfileForm').off('submit', DlnaProfilePage.onSubmit).on('submit', DlnaProfilePage.onSubmit); - $('.editDirectPlayProfileForm').off('submit', DlnaProfilePage.onDirectPlayFormSubmit).on('submit', DlnaProfilePage.onDirectPlayFormSubmit); - $('.transcodingProfileForm').off('submit', DlnaProfilePage.onTranscodingProfileFormSubmit).on('submit', DlnaProfilePage.onTranscodingProfileFormSubmit); - $('.containerProfileForm').off('submit', DlnaProfilePage.onContainerProfileFormSubmit).on('submit', DlnaProfilePage.onContainerProfileFormSubmit); - $('.codecProfileForm').off('submit', DlnaProfilePage.onCodecProfileFormSubmit).on('submit', DlnaProfilePage.onCodecProfileFormSubmit); - $('.editResponseProfileForm').off('submit', DlnaProfilePage.onResponseProfileFormSubmit).on('submit', DlnaProfilePage.onResponseProfileFormSubmit); - $('.identificationHeaderForm').off('submit', DlnaProfilePage.onIdentificationHeaderFormSubmit).on('submit', DlnaProfilePage.onIdentificationHeaderFormSubmit); - $('.xmlAttributeForm').off('submit', DlnaProfilePage.onXmlAttributeFormSubmit).on('submit', DlnaProfilePage.onXmlAttributeFormSubmit); - $('.subtitleProfileForm').off('submit', DlnaProfilePage.onSubtitleProfileFormSubmit).on('submit', DlnaProfilePage.onSubtitleProfileFormSubmit); -}).on('pageshow', '#dlnaProfilePage', function () { - const page = this; - $('#radioInfo', page).trigger('click'); - loadProfile(page); -}); -window.DlnaProfilePage = { - onSubmit: function () { - loading.show(); - saveProfile($(this).parents('.page'), currentProfile); - return false; - }, - onDirectPlayFormSubmit: function () { - saveDirectPlayProfile($(this).parents('.page')); - return false; - }, - onTranscodingProfileFormSubmit: function () { - saveTranscodingProfile($(this).parents('.page')); - return false; - }, - onContainerProfileFormSubmit: function () { - saveContainerProfile($(this).parents('.page')); - return false; - }, - onCodecProfileFormSubmit: function () { - saveCodecProfile($(this).parents('.page')); - return false; - }, - onResponseProfileFormSubmit: function () { - saveResponseProfile($(this).parents('.page')); - return false; - }, - onIdentificationHeaderFormSubmit: function () { - saveIdentificationHeader($(this).parents('.page')); - return false; - }, - onXmlAttributeFormSubmit: function () { - saveXmlDocumentAttribute($(this).parents('.page')); - return false; - }, - onSubtitleProfileFormSubmit: function () { - saveSubtitleProfile($(this).parents('.page')); - return false; - } -}; - diff --git a/src/controllers/dashboard/dlna/profiles.html b/src/controllers/dashboard/dlna/profiles.html deleted file mode 100644 index f1696632c9..0000000000 --- a/src/controllers/dashboard/dlna/profiles.html +++ /dev/null @@ -1,32 +0,0 @@ -
- -
-
- -
- -
-
-

${HeaderCustomDlnaProfiles}

- - - -
- -

${CustomDlnaProfilesHelp}

-
-
- - -
-
-

${HeaderSystemDlnaProfiles}

-
- -

${SystemDlnaProfilesHelp}

-
-
-
-
-
-
diff --git a/src/controllers/dashboard/dlna/profiles.js b/src/controllers/dashboard/dlna/profiles.js deleted file mode 100644 index f69a0c6bf0..0000000000 --- a/src/controllers/dashboard/dlna/profiles.js +++ /dev/null @@ -1,93 +0,0 @@ -import escapeHtml from 'escape-html'; -import 'jquery'; -import globalize from '../../../scripts/globalize'; -import loading from '../../../components/loading/loading'; -import libraryMenu from '../../../scripts/libraryMenu'; -import '../../../components/listview/listview.scss'; -import '../../../elements/emby-button/emby-button'; -import confirm from '../../../components/confirm/confirm'; - -function loadProfiles(page) { - loading.show(); - ApiClient.getJSON(ApiClient.getUrl('Dlna/ProfileInfos')).then(function (result) { - renderUserProfiles(page, result); - renderSystemProfiles(page, result); - loading.hide(); - }); -} - -function renderUserProfiles(page, profiles) { - renderProfiles(page, page.querySelector('.customProfiles'), profiles.filter(function (p) { - return p.Type == 'User'; - })); -} - -function renderSystemProfiles(page, profiles) { - renderProfiles(page, page.querySelector('.systemProfiles'), profiles.filter(function (p) { - return p.Type == 'System'; - })); -} - -function renderProfiles(page, element, profiles) { - let html = ''; - - if (profiles.length) { - html += '
'; - } - - for (let i = 0, length = profiles.length; i < length; i++) { - const profile = profiles[i]; - html += '
'; - html += ''; - html += ''; - - if (profile.Type == 'User') { - html += ''; - } - - html += '
'; - } - - if (profiles.length) { - html += '
'; - } - - element.innerHTML = html; - $('.btnDeleteProfile', element).on('click', function () { - const id = this.getAttribute('data-profileid'); - deleteProfile(page, id); - }); -} - -function deleteProfile(page, id) { - confirm(globalize.translate('MessageConfirmProfileDeletion'), globalize.translate('HeaderConfirmProfileDeletion')).then(function () { - loading.show(); - ApiClient.ajax({ - type: 'DELETE', - url: ApiClient.getUrl('Dlna/Profiles/' + id) - }).then(function () { - loading.hide(); - loadProfiles(page); - }); - }); -} - -function getTabs() { - return [{ - href: '#/dashboard/dlna', - name: globalize.translate('Settings') - }, { - href: '#/dashboard/dlna/profiles', - name: globalize.translate('TabProfiles') - }]; -} - -$(document).on('pageshow', '#dlnaProfilesPage', function () { - libraryMenu.setTabs('dlna', 1, getTabs); - loadProfiles(this); -}); - diff --git a/src/controllers/dashboard/dlna/settings.html b/src/controllers/dashboard/dlna/settings.html deleted file mode 100644 index 4bf5ffc81c..0000000000 --- a/src/controllers/dashboard/dlna/settings.html +++ /dev/null @@ -1,69 +0,0 @@ -
- -
-
- -
- -
-
-

${Settings}

- ${Help} -
-
- -
- -
${LabelEnableDlnaPlayToHelp}
-
- -
- -
${LabelEnableDlnaDebugLoggingHelp}
-
- -
- -
${LabelEnableDlnaClientDiscoveryIntervalHelp}
-
- -
- -
${LabelEnableDlnaServerHelp}
-
- -
- -
${LabelEnableBlastAliveMessagesHelp}
-
- -
- -
${LabelBlastMessageIntervalHelp}
-
-
- -
${LabelDefaultUserHelp}
-
-
- -
-
- -
-
-
diff --git a/src/controllers/dashboard/dlna/settings.js b/src/controllers/dashboard/dlna/settings.js deleted file mode 100644 index d12b6744af..0000000000 --- a/src/controllers/dashboard/dlna/settings.js +++ /dev/null @@ -1,60 +0,0 @@ -import escapeHtml from 'escape-html'; -import 'jquery'; -import loading from '../../../components/loading/loading'; -import libraryMenu from '../../../scripts/libraryMenu'; -import globalize from '../../../scripts/globalize'; -import Dashboard from '../../../utils/dashboard'; - -function loadPage(page, config, users) { - page.querySelector('#chkEnablePlayTo').checked = config.EnablePlayTo; - page.querySelector('#chkEnableDlnaDebugLogging').checked = config.EnableDebugLog; - $('#txtClientDiscoveryInterval', page).val(config.ClientDiscoveryIntervalSeconds); - $('#chkEnableServer', page).prop('checked', config.EnableServer); - $('#chkBlastAliveMessages', page).prop('checked', config.BlastAliveMessages); - $('#txtBlastInterval', page).val(config.BlastAliveMessageIntervalSeconds); - const usersHtml = users.map(function (u) { - return ''; - }).join(''); - $('#selectUser', page).html(usersHtml).val(config.DefaultUserId || ''); - loading.hide(); -} - -function onSubmit() { - loading.show(); - const form = this; - ApiClient.getNamedConfiguration('dlna').then(function (config) { - config.EnablePlayTo = form.querySelector('#chkEnablePlayTo').checked; - config.EnableDebugLog = form.querySelector('#chkEnableDlnaDebugLogging').checked; - config.ClientDiscoveryIntervalSeconds = $('#txtClientDiscoveryInterval', form).val(); - config.EnableServer = $('#chkEnableServer', form).is(':checked'); - config.BlastAliveMessages = $('#chkBlastAliveMessages', form).is(':checked'); - config.BlastAliveMessageIntervalSeconds = $('#txtBlastInterval', form).val(); - config.DefaultUserId = $('#selectUser', form).val(); - ApiClient.updateNamedConfiguration('dlna', config).then(Dashboard.processServerConfigurationUpdateResult); - }); - return false; -} - -function getTabs() { - return [{ - href: '#/dashboard/dlna', - name: globalize.translate('Settings') - }, { - href: '#/dashboard/dlna/profiles', - name: globalize.translate('TabProfiles') - }]; -} - -$(document).on('pageinit', '#dlnaSettingsPage', function () { - $('.dlnaSettingsForm').off('submit', onSubmit).on('submit', onSubmit); -}).on('pageshow', '#dlnaSettingsPage', function () { - libraryMenu.setTabs('dlna', 0, getTabs); - loading.show(); - const page = this; - const promise1 = ApiClient.getNamedConfiguration('dlna'); - const promise2 = ApiClient.getUsers(); - Promise.all([promise1, promise2]).then(function (responses) { - loadPage(page, responses[0], responses[1]); - }); -}); - diff --git a/src/strings/en-us.json b/src/strings/en-us.json index c7a6fe5edf..bde44f6886 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -165,7 +165,6 @@ "CopyStreamURLSuccess": "URL copied successfully.", "CriticRating": "Critics rating", "Cursive": "Cursive", - "CustomDlnaProfilesHelp": "Create a custom profile to target a new device or override a system profile.", "DailyAt": "Daily at {0}", "Data": "Data", "DateAdded": "Date added", @@ -208,6 +207,7 @@ "DisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons", "DisplayMissingEpisodesWithinSeasonsHelp": "This must also be enabled for TV libraries in the server configuration.", "DisplayModeHelp": "Select the layout style you want for the interface.", + "DlnaMovedMessage": "The DLNA functionality has moved to a plugin.", "DoNotRecord": "Do not record", "Down": "Down", "Download": "Download", @@ -338,21 +338,15 @@ "HeaderCastAndCrew": "Cast & Crew", "HeaderChannelAccess": "Channel Access", "HeaderChapterImages": "Chapter Images", - "HeaderCodecProfile": "Codec Profile", - "HeaderCodecProfileHelp": "Codec profiles indicate the limitations of a device when playing specific codecs. If a limitation applies then the media will be transcoded, even if the codec is configured for direct playback.", "HeaderConfigureRemoteAccess": "Set up Remote Access", "HeaderConfirmPluginInstallation": "Confirm Plugin Installation", "HeaderConfirmRepositoryInstallation": "Confirm Plugin Repository Installation", - "HeaderConfirmProfileDeletion": "Confirm Profile Deletion", "HeaderConfirmRevokeApiKey": "Revoke API Key", "HeaderConnectionFailure": "Connection Failure", "HeaderConnectToServer": "Connect to Server", - "HeaderContainerProfile": "Container Profile", - "HeaderContainerProfileHelp": "Container profiles indicate the limitations of a device when playing specific formats. If a limitation applies then the media will be transcoded, even if the format is configured for direct playback.", "HeaderContinueListening": "Continue Listening", "HeaderContinueWatching": "Continue Watching", "HeaderContinueReading": "Continue Reading", - "HeaderCustomDlnaProfiles": "Custom Profiles", "HeaderDateIssued": "Date Issued", "HeaderDefaultRecordingSettings": "Default Recording Settings", "HeaderDeleteDevice": "Delete Device", @@ -365,8 +359,6 @@ "HeaderDeveloperInfo": "Developer Info", "HeaderDeviceAccess": "Device Access", "HeaderDevices": "Devices", - "HeaderDirectPlayProfile": "Direct Playback Profile", - "HeaderDirectPlayProfileHelp": "Add direct playback profiles to indicate which formats the device can handle natively.", "HeaderDownloadSync": "Download & Sync", "HeaderDummyChapter": "Chapter Images", "HeaderDVR": "DVR", @@ -383,14 +375,9 @@ "HeaderFrequentlyPlayed": "Frequently Played", "HeaderGuestCast": "Guest Stars", "HeaderGuideProviders": "TV Guide Data Providers", - "HeaderHttpHeaders": "HTTP Headers", "HeaderHttpsSettings": "HTTPS Settings", - "HeaderIdentification": "Identification", - "HeaderIdentificationCriteriaHelp": "Enter at least one identification criteria.", - "HeaderIdentificationHeader": "Identification Header", "HeaderIdentifyItemHelp": "Enter one or more search criteria. Remove criteria to increase search results.", "HeaderImageOptions": "Image Options", - "HeaderImageSettings": "Image Settings", "HeaderInstall": "Install", "HeaderInstantMix": "Instant Mix", "HeaderKeepRecording": "Keep Recording", @@ -439,8 +426,6 @@ "HeaderPluginInstallation": "Plugin Installation", "HeaderPortRanges": "Firewall and Proxy Settings", "HeaderPreferredMetadataLanguage": "Preferred Metadata Language", - "HeaderProfileInformation": "Profile Information", - "HeaderProfileServerSettingsHelp": "These values control how the server will present itself to clients.", "HeaderRecentlyPlayed": "Recently Played", "HeaderRecordingMetadataSaving": "Recording Metadata", "HeaderRecordingOptions": "Recording Options", @@ -449,8 +434,6 @@ "HeaderRemoteControl": "Remote Control", "HeaderRemoveMediaFolder": "Remove Media Folder", "HeaderRemoveMediaLocation": "Remove Media Location", - "HeaderResponseProfile": "Response Profile", - "HeaderResponseProfileHelp": "Response profiles provide a way to customize information sent to the device when playing certain kinds of media.", "HeaderRevisionHistory": "Revision History", "HeaderRunningTasks": "Running Tasks", "HeaderScenes": "Scenes", @@ -468,7 +451,6 @@ "HeaderSeriesOptions": "Series Options", "HeaderSeriesStatus": "Series Status", "HeaderServerAddressSettings": "Server Address Settings", - "HeaderServerSettings": "Server Settings", "HeaderSetupLibrary": "Setup your media libraries", "HeaderSortBy": "Sort By", "HeaderSortOrder": "Sort Order", @@ -478,20 +460,14 @@ "HeaderStopRecording": "Stop Recording", "HeaderSubtitleAppearance": "Subtitle Appearance", "HeaderSubtitleDownloads": "Subtitle Downloads", - "HeaderSubtitleProfile": "Subtitle Profile", - "HeaderSubtitleProfiles": "Subtitle Profiles", - "HeaderSubtitleProfilesHelp": "Subtitle profiles describe the subtitle formats supported by the device.", "HeaderSyncPlayEnabled": "SyncPlay enabled", "HeaderSyncPlaySelectGroup": "Join a group", "HeaderSyncPlaySettings": "SyncPlay Settings", "HeaderSyncPlayPlaybackSettings": "Playback", "HeaderSyncPlayTimeSyncSettings": "Time sync", - "HeaderSystemDlnaProfiles": "System Profiles", "HeaderTaskTriggers": "Task Triggers", "HeaderThisUserIsCurrentlyDisabled": "This user is currently disabled", "HeaderTracks": "Tracks", - "HeaderTranscodingProfile": "Transcoding Profile", - "HeaderTranscodingProfileHelp": "Add transcoding profiles to indicate which formats should be used when transcoding is required.", "HeaderTunerDevices": "Tuner Devices", "HeaderTuners": "Tuners", "HeaderTypeImageFetchers": "Image fetchers ({0})", @@ -506,9 +482,6 @@ "HeaderVideos": "Videos", "HeaderVideoType": "Video Type", "HeaderVideoTypes": "Video Types", - "HeaderXmlDocumentAttribute": "XML Document Attribute", - "HeaderXmlDocumentAttributes": "XML Document Attributes", - "HeaderXmlSettings": "XML Settings", "HeaderYears": "Years", "Help": "Help", "Hide": "Hide", @@ -541,12 +514,7 @@ "LabelAirsBeforeSeason": "Airs before season", "LabelAirTime": "Air time", "LabelAlbum": "Album", - "LabelAlbumArtHelp": "PN used for album art, within the 'dlna:profileID' attribute on 'upnp:albumArtURI'. Some devices require a specific value, regardless of the size of the image.", "LabelAlbumArtists": "Album artists", - "LabelAlbumArtMaxHeight": "Album art max height", - "LabelAlbumArtMaxResHelp": "Maximum resolution of album art exposed via the 'upnp:albumArtURI' property.", - "LabelAlbumArtMaxWidth": "Album art max width", - "LabelAlbumArtPN": "Album art PN", "LabelAlbumGain": "Album Gain", "LabelAllowedRemoteAddresses": "Remote IP address filter", "LabelAllowedRemoteAddressesMode": "Remote IP address filter mode", @@ -618,12 +586,8 @@ "LabelDay": "Day of week", "LabelDeathDate": "Death date", "LabelDefaultScreen": "Default screen", - "LabelDefaultUser": "Default user", - "LabelDefaultUserHelp": "Determine which user library should be displayed on connected devices. This can be overridden for each device using profiles.", "LabelDeinterlaceMethod": "Deinterlacing method", "LabelDeveloper": "Developer", - "LabelDeviceDescription": "Device description", - "LabelDidlMode": "DIDL mode", "LabelDisableCustomCss": "Disable custom CSS code for theming/branding provided from the server.", "LabelDiscNumber": "Disc number", "LabelDisplayLanguage": "Display language", @@ -645,22 +609,10 @@ "LabelChapterImageResolution": "Resolution", "LabelChapterImageResolutionHelp": "The resolution of the extracted chapter images. Changing this will have no effect on existing dummy chapters.", "LabelDynamicExternalId": "{0} Id", - "LabelEmbedAlbumArtDidl": "Embed album art in DIDL", - "LabelEmbedAlbumArtDidlHelp": "Some devices prefer this method for getting the album art. Others may fail to play with this option enabled.", "LabelEnableAudioVbr": "Enable VBR audio encoding", "LabelEnableAudioVbrHelp": "Variable bitrate offers better quality to average bitrate ratio, but in some rare cases may cause buffering and compatibility issues.", "LabelEnableAutomaticPortMap": "Enable automatic port mapping", "LabelEnableAutomaticPortMapHelp": "Automatically forward public ports on your router to local ports on your server via UPnP. This may not work with some router models or network configurations. Changes will not apply until after a server restart.", - "LabelEnableBlastAliveMessages": "Blast alive messages", - "LabelEnableBlastAliveMessagesHelp": "Enable this if the server is not detected reliably by other UPnP devices on your network.", - "LabelEnableDlnaClientDiscoveryInterval": "Client discovery interval", - "LabelEnableDlnaClientDiscoveryIntervalHelp": "Determine the duration in seconds between two SSDP searches.", - "LabelEnableDlnaDebugLogging": "Enable DLNA debug logging", - "LabelEnableDlnaDebugLoggingHelp": "Create large log files and should only be used as needed for troubleshooting purposes.", - "LabelEnableDlnaPlayTo": "Enable 'Play To' DLNA feature", - "LabelEnableDlnaPlayToHelp": "Detect devices within your network and offer the ability to control them remotely.", - "LabelEnableDlnaServer": "Enable DLNA server", - "LabelEnableDlnaServerHelp": "Allow UPnP devices on your network to browse and play content.", "LabelEnableHardwareDecodingFor": "Enable hardware decoding for", "LabelEnableHttps": "Enable HTTPS", "LabelEnableHttpsHelp": "Listen on the configured HTTPS port. A valid certificate must also be supplied for this to take effect.", @@ -672,8 +624,6 @@ "LabelEnableLUFSScanHelp": "Clients can normalize audio playback to get equal loudness across tracks. This will make library scans longer and take more resources.", "LabelEnableRealtimeMonitor": "Enable real time monitoring", "LabelEnableRealtimeMonitorHelp": "Changes to files will be processed immediately on supported file systems.", - "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image", - "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within DIDL.", "LabelEncoderPreset": "Encoding preset", "LabelEndDate": "End date", "LabelEpisodeNumber": "Episode number", @@ -702,10 +652,6 @@ "LabelHomeScreenSectionValue": "Home screen section {0}", "LabelHttpsPort": "Local HTTPS port number", "LabelHttpsPortHelp": "The TCP port number for the HTTPS server.", - "LabelIconMaxHeight": "Icon maximum height", - "LabelIconMaxResHelp": "Maximum resolution of icons exposed via the 'upnp:icon' property.", - "LabelIconMaxWidth": "Icon maximum width", - "LabelIdentificationFieldHelp": "A case-insensitive substring or regex expression.", "LabelImageFetchersHelp": "Enable and rank your preferred image fetchers in order of priority.", "LabelImageType": "Image type", "LabelImportOnlyFavoriteChannels": "Restrict to channels marked as favorite", @@ -741,9 +687,6 @@ "LabelLoginDisclaimer": "Login disclaimer", "LabelLoginDisclaimerHelp": "A message that will be displayed at the bottom of the login page.", "LabelLogs": "Logs", - "LabelManufacturer": "Manufacturer", - "LabelManufacturerUrl": "Manufacturer URL", - "LabelMatchType": "Match type", "LabelMaxAudiobookResume": "Audiobook remaining minutes to resume", "LabelMaxAudiobookResumeHelp": "Titles are assumed fully played if stopped when the remaining duration is less than this value.", "LabelMaxBackdropsPerItem": "Maximum number of backdrops per item", @@ -753,8 +696,6 @@ "LabelMaxParentalRating": "Maximum allowed parental rating", "LabelMaxResumePercentage": "Maximum resume percentage", "LabelMaxResumePercentageHelp": "Titles are assumed fully played if stopped after this time.", - "LabelMaxStreamingBitrate": "Maximum streaming quality", - "LabelMaxStreamingBitrateHelp": "Specify a maximum bitrate when streaming.", "LabelMessageText": "Message text", "LabelMessageTitle": "Message title", "LabelMetadata": "Metadata", @@ -766,7 +707,6 @@ "LabelMetadataReadersHelp": "Rank your preferred local metadata sources in order of priority. The first file found will be read.", "LabelMetadataSavers": "Metadata savers", "LabelMetadataSaversHelp": "Pick the file formats to use when saving your metadata.", - "LabelMethod": "Method", "LabelMinAudiobookResume": "Minimum Audiobook resume in minutes", "LabelMinAudiobookResumeHelp": "Titles are assumed unplayed if stopped before this time.", "LabelMinBackdropDownloadWidth": "Minimum backdrop download width", @@ -774,16 +714,10 @@ "LabelMinResumeDurationHelp": "The shortest video length in seconds that will save playback location and let you resume.", "LabelMinResumePercentage": "Minimum resume percentage", "LabelMinResumePercentageHelp": "Titles are assumed unplayed if stopped before this time.", - "LabelModelDescription": "Model description", - "LabelModelName": "Model name", - "LabelModelNumber": "Model number", - "LabelModelUrl": "Model URL", "LabelMovieCategories": "Movie categories", "LabelMoviePrefix": "Movie prefix", "LabelMoviePrefixHelp": "If a prefix is applied to movie titles, enter it here so the server can handle it properly.", "LabelMovieRecordingPath": "Movie recording path", - "LabelMusicStreamingTranscodingBitrate": "Music transcoding bitrate", - "LabelMusicStreamingTranscodingBitrateHelp": "Specify a maximum bitrate when streaming music.", "LabelName": "Name", "LabelNewName": "New name", "LabelNewPassword": "New password", @@ -823,15 +757,8 @@ "LabelPostProcessorArgumentsHelp": "Use {path} as the path to the recording file.", "LabelPreferredDisplayLanguage": "Preferred display language", "LabelPreferredSubtitleLanguage": "Preferred subtitle language", - "LabelProfileAudioCodecs": "Audio codecs", - "LabelProfileCodecs": "Codecs", - "LabelProfileCodecsHelp": "Separated by comma. This can be left empty to apply to all codecs.", "LabelProfileContainer": "Container", - "LabelProfileContainersHelp": "Separated by comma. This can be left empty to apply to all containers.", - "LabelProfileVideoCodecs": "Video codecs", "LabelProtocol": "Protocol", - "LabelProtocolInfo": "Protocol info", - "LabelProtocolInfoHelp": "The value that will be used when responding to GetProtocolInfo requests from the device.", "LabelPublicHttpPort": "Public HTTP port number", "LabelPublicHttpPortHelp": "The public port number that should be mapped to the local HTTP port.", "LabelPublicHttpsPort": "Public HTTPS port number", @@ -862,7 +789,6 @@ "LabelSelectFolderGroups": "Automatically group content from the following folders into views such as 'Movies', 'Music' and 'TV'", "LabelSelectFolderGroupsHelp": "Folders that are unchecked will be displayed by themselves in their own view.", "LabelSelectVersionToInstall": "Select version to install", - "LabelSerialNumber": "Serial number", "LabelSeriesRecordingPath": "Series recording path", "LabelServerHost": "Host", "LabelServerHostHelp": "192.168.1.100:8096 or https://myserver.com", @@ -879,8 +805,6 @@ "LabelSkipIfGraphicalSubsPresentHelp": "Keeping text versions of subtitles will result in more efficient delivery and decrease the likelihood of video transcoding.", "LabelSlowResponseEnabled": "Log a warning message if the server was slow to answer", "LabelSlowResponseTime": "Time in ms after which a response is considered slow", - "LabelSonyAggregationFlags": "Sony aggregation flags", - "LabelSonyAggregationFlagsHelp": "Determine the content of the 'aggregationFlags' element in the 'urn:schemas-sonycom:av' namespace.", "LabelSortBy": "Sort by", "LabelSortName": "Sort name", "LabelSortOrder": "Sort order", @@ -895,10 +819,8 @@ "LabelStopWhenPossible": "Stop when possible", "LabelStreamType": "Stream type", "LabelSubtitleDownloaders": "Subtitle downloaders", - "LabelSubtitleFormatHelp": "Example: srt", "LabelSubtitlePlaybackMode": "Subtitle mode", "LabelSubtitleVerticalPosition": "Vertical position", - "LabelSupportedMediaTypes": "Supported Media Types", "LabelSyncPlayAccess": "SyncPlay access", "LabelSyncPlayAccessCreateAndJoinGroups": "Allow user to create and join groups", "LabelSyncPlayAccessJoinGroups": "Allow user to join groups", @@ -973,8 +895,6 @@ "LabelUnstable": "Unstable", "LabelUser": "User", "LabelUserAgent": "User agent", - "LabelUserLibrary": "User library", - "LabelUserLibraryHelp": "Select which user library to display to the device. Leave empty to inherit the default setting.", "LabelUserLoginAttemptsBeforeLockout": "Failed login tries before user is locked out", "LabelUserMaxActiveSessions": "Maximum number of simultaneous user sessions", "LabelUsername": "Username", @@ -990,10 +910,6 @@ "LabelVideoResolution": "Video resolution", "LabelWeb": "Web", "LabelWebVersion": "Web version", - "LabelXDlnaCap": "Device Capability ID", - "LabelXDlnaCapHelp": "Determine the content of the 'X_DLNACAP' element in the 'urn:schemas-dlna-org:device-1-0' namespace.", - "LabelXDlnaDoc": "Device Class ID", - "LabelXDlnaDocHelp": "Determine the content of the 'X_DLNADOC' element in the 'urn:schemas-dlna-org:device-1-0' namespace.", "LabelYear": "Year", "LabelYoureDone": "You're Done!", "LabelZipCode": "Zip Code", @@ -1070,7 +986,6 @@ "MessageConfirmAppExit": "Do you want to exit?", "MessageConfirmDeleteGuideProvider": "Are you sure you wish to delete this guide provider?", "MessageConfirmDeleteTunerDevice": "Are you sure you wish to delete this device?", - "MessageConfirmProfileDeletion": "Are you sure you wish to delete this profile?", "MessageConfirmRecordingCancellation": "Cancel recording?", "MessageConfirmRemoveMediaLocation": "Are you sure you wish to remove this location?", "MessageConfirmRestart": "Are you sure you wish to restart Jellyfin?", @@ -1215,7 +1130,6 @@ "OptionAutomaticallyGroupSeries": "Automatically merge series that are spread across multiple folders", "OptionAutomaticallyGroupSeriesHelp": "Series that are spread across multiple folders within this library will be automatically merged into a single series.", "OptionBluray": "BD", - "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", "OptionCommunityRating": "Community Rating", "OptionCriticRating": "Critics Rating", "OptionDaily": "Daily", @@ -1230,28 +1144,19 @@ "OptionDisplayFolderView": "Display a folder view to show plain media folders", "OptionDisplayFolderViewHelp": "Display folders alongside your other media libraries. This can be useful if you'd like to have a plain folder view.", "OptionDvd": "DVD", - "OptionEmbedSubtitles": "Embed within container", "OptionEnableAccessFromAllDevices": "Enable access from all devices", "OptionEnableAccessToAllChannels": "Enable access to all channels", "OptionEnableAccessToAllLibraries": "Enable access to all libraries", "OptionEnableExternalContentInSuggestions": "Enable external content in suggestions", "OptionEnableExternalContentInSuggestionsHelp": "Allow internet trailers and live TV programs to be included within suggested content.", "OptionEnableForAllTuners": "Enable for all tuner devices", - "OptionEnableM2tsMode": "Enable M2TS mode", - "OptionEnableM2tsModeHelp": "Enable M2TS mode when encoding to MPEG-TS.", - "OptionEquals": "Equals", - "OptionEstimateContentLength": "Estimate content length when transcoding", "OptionEveryday": "Every day", - "OptionExternallyDownloaded": "External download", "OptionExtractChapterImage": "Enable chapter image extraction", "OptionForceRemoteSourceTranscoding": "Force transcoding of remote media sources such as Live TV", "OptionHasThemeSong": "Theme Song", "OptionHasThemeVideo": "Theme Video", "OptionHideUser": "Hide this user from login screens", "OptionHideUserFromLoginHelp": "Useful for private or hidden administrator accounts. The user will need to sign in manually by entering their username and password.", - "OptionHlsSegmentedSubtitles": "HLS segmented subtitles", - "OptionIgnoreTranscodeByteRangeRequests": "Ignore transcode byte range requests", - "OptionIgnoreTranscodeByteRangeRequestsHelp": "These requests will be honored but will ignore the byte range header.", "OptionImdbRating": "IMDb Rating", "OptionIsHD": "HD", "OptionIsSD": "SD", @@ -1264,27 +1169,16 @@ "OptionNew": "New…", "OptionOnInterval": "On an interval", "OptionParentalRating": "Parental Rating", - "OptionPlainStorageFolders": "Display all folders as plain storage folders", - "OptionPlainStorageFoldersHelp": "All folders are represented in DIDL as 'object.container.storageFolder' instead of a more specific type, such as 'object.container.person.musicArtist'.", - "OptionPlainVideoItems": "Display all videos as plain video items", - "OptionPlainVideoItemsHelp": "All videos are represented in DIDL as 'object.item.videoItem' instead of a more specific type, such as 'object.item.videoItem.movie'.", "OptionPlayCount": "Play Count", "OptionPremiereDate": "Premiere Date", - "OptionProtocolHls": "HTTP Live Streaming (HLS)", - "OptionProtocolHttp": "HTTP", "OptionRandom": "Random", - "OptionRegex": "Regex", "OptionReleaseDate": "Release Date", - "OptionReportByteRangeSeekingWhenTranscoding": "Report that the server supports byte seeking when transcoding", - "OptionReportByteRangeSeekingWhenTranscodingHelp": "This is required for some devices that don't time seek very well.", "OptionRequirePerfectSubtitleMatch": "Only download subtitles that are a perfect match for video files", "OptionRequirePerfectSubtitleMatchHelp": "Requiring a perfect match will filter subtitles to include only those that have been tested and verified with your exact video file. Unchecking this will increase the likelihood of subtitles being downloaded, but will increase the chances of mistimed or incorrect subtitle text.", - "OptionResElement": "'res' element", "OptionResumable": "Resumable", "OptionSaveMetadataAsHidden": "Save metadata and images as hidden files", "OptionSaveMetadataAsHiddenHelp": "Changing this will apply to new metadata saved going forward. Existing metadata files will be updated the next time they are saved by the server.", "OptionSpecialEpisode": "Specials", - "OptionSubstring": "Substring", "OptionTrackName": "Track Name", "OptionTvdbRating": "TheTVDB Rating", "OptionUnairedEpisode": "Unaired Episodes", @@ -1501,14 +1395,10 @@ "Sunday": "Sunday", "SyncPlayAccessHelp": "The SyncPlay feature enables to sync playback with other devices. Select the level of access this user has to the SyncPlay.", "SyncPlayGroupDefaultTitle": "{0}'s group", - "SystemDlnaProfilesHelp": "System profiles are read-only. Changes to a system profile will be saved to a new custom profile.", "TabAccess": "Access", "TabAdvanced": "Advanced", "TabCatalog": "Catalog", - "TabCodecs": "Codecs", - "TabContainers": "Containers", "TabDashboard": "Dashboard", - "TabDirectPlay": "Direct Playback", "TabLatest": "Recently Added", "TabLogs": "Logs", "TabMusic": "Music", @@ -1519,9 +1409,7 @@ "TabOther": "Other", "TabParentalControl": "Parental Control", "TabPlugins": "Plugins", - "TabProfiles": "Profiles", "TabRepositories": "Repositories", - "TabResponses": "Responses", "TabScheduledTasks": "Scheduled Tasks", "TabServer": "Server", "TabStreaming": "Streaming", @@ -1578,10 +1466,6 @@ "UserMenu": "User Menu", "UserProfilesIntro": "Jellyfin includes support for user profiles with granular display settings, play state, and parental controls.", "ValueAlbumCount": "{0} albums", - "ValueAudioCodec": "Audio Codec: {0}", - "ValueCodec": "Codec: {0}", - "ValueConditions": "Conditions: {0}", - "ValueContainer": "Container: {0}", "ValueDiscNumber": "Disc {0}", "ValueEpisodeCount": "{0} episodes", "ValueMinutes": "{0} min", @@ -1599,7 +1483,6 @@ "ValueSpecialEpisodeName": "Special - {0}", "ValueTimeLimitMultiHour": "Time limit: {0} hours", "ValueTimeLimitSingleHour": "Time limit: 1 hour", - "ValueVideoCodec": "Video Codec: {0}", "Vertical": "Vertical", "Video": "Video", "VideoAudio": "Video Audio", @@ -1615,7 +1498,6 @@ "WriteAccessRequired": "Jellyfin requires write access to this folder. Please ensure write access and try again.", "Writer": "Writer", "Writers": "Writers", - "XmlDocumentAttributeListHelp": "These attributes are applied to the root element of every XML response.", "XmlTvKidsCategoriesHelp": "Programs with these categories will be displayed as programs for children. Separate multiple with '|'.", "XmlTvMovieCategoriesHelp": "Programs with these categories will be displayed as movies. Separate multiple with '|'.", "XmlTvNewsCategoriesHelp": "Programs with these categories will be displayed as news programs. Separate multiple with '|'.", From ec1f016d5b2a1e92b09047b742888a9a7eadaa84 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Mon, 4 Mar 2024 13:49:29 -0500 Subject: [PATCH 2/2] Update notifications page ui --- src/apps/dashboard/routes/notifications.tsx | 38 ++++++++++----------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/apps/dashboard/routes/notifications.tsx b/src/apps/dashboard/routes/notifications.tsx index 6f673c753f..7642ee033b 100644 --- a/src/apps/dashboard/routes/notifications.tsx +++ b/src/apps/dashboard/routes/notifications.tsx @@ -1,23 +1,13 @@ +import Alert from '@mui/material/Alert/Alert'; +import Box from '@mui/material/Box/Box'; +import Button from '@mui/material/Button/Button'; import React from 'react'; +import { Link } from 'react-router-dom'; import Page from 'components/Page'; import globalize from 'scripts/globalize'; -const PluginLink = () => ( -