mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Remove dlna configuration pages
This commit is contained in:
parent
d3b9b347ba
commit
7f42b4e8b6
12 changed files with 39 additions and 1831 deletions
|
@ -1,584 +0,0 @@
|
|||
<div id="dlnaProfilePage" data-role="page" class="page type-interior dlnaPage withTabs">
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<form class="dlnaProfileForm" style="max-width: 650px;">
|
||||
<div class="verticalSection">
|
||||
<div class="sectionTitleContainer flex align-items-center">
|
||||
<h2 class="sectionTitle">${HeaderProfileInformation}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="controlgroup" data-type="horizontal" data-mini="true">
|
||||
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioInfo" data-value="tabInfo">${ButtonInfo}</a>
|
||||
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioDirectPlay" data-value="tabDirectPlayProfiles">${TabDirectPlay}</a>
|
||||
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioTranscoding" data-value="tabTranscodingProfiles">${Transcoding}</a>
|
||||
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioContainers" data-value="tabContainerProfiles">${TabContainers}</a>
|
||||
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioCodecs" data-value="tabCodecProfiles">${TabCodecs}</a>
|
||||
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioMediaProfiles" data-value="tabMediaProfiles">${TabResponses}</a>
|
||||
</div>
|
||||
<br />
|
||||
<div class="tabContent tabInfo">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtName" required="required" label="${LabelName}" />
|
||||
</div>
|
||||
<div class="selectContainer">
|
||||
<select is="emby-select" id="selectUser" label="${LabelUserLibrary}"></select>
|
||||
<div class="fieldDescription">${LabelUserLibraryHelp}</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="checkboxListLabel">${LabelSupportedMediaTypes}</h3>
|
||||
<div class="checkboxList paperList checkboxList-paperList">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkAudio" data-value="Audio" class="chkMediaType" />
|
||||
<span>${Audio}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkPhoto" data-value="Photo" class="chkMediaType" />
|
||||
<span>${Photo}</span>
|
||||
</label>
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkVideo" data-value="Video" class="chkMediaType" />
|
||||
<span>${Video}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" id="txtMaxAllowedBitrate" pattern="[0-9]*" min="1" label="${LabelMaxStreamingBitrate}" />
|
||||
<div class="fieldDescription">${LabelMaxStreamingBitrateHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" id="txtMusicStreamingTranscodingBitrate" pattern="[0-9]*" min="1" label="${LabelMusicStreamingTranscodingBitrate}" />
|
||||
<div class="fieldDescription">${LabelMusicStreamingTranscodingBitrateHelp}</div>
|
||||
</div>
|
||||
<div style="display:none;">
|
||||
<label for="chkIgnoreTranscodeByteRangeRequests">${OptionIgnoreTranscodeByteRangeRequests}</label>
|
||||
<input type="checkbox" id="chkIgnoreTranscodeByteRangeRequests" data-mini="true" />
|
||||
<div class="fieldDescription">${OptionIgnoreTranscodeByteRangeRequestsHelp}</div>
|
||||
</div>
|
||||
<div is="emby-collapse" title="${HeaderIdentification}">
|
||||
<div class="collapseContent">
|
||||
<h3>${HeaderIdentificationCriteriaHelp}</h3>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdFriendlyName" label="${LabelFriendlyName}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdManufacturer" label="${LabelManufacturer}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdManufacturerUrl" label="${LabelManufacturerUrl}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdModelName" label="${LabelModelName}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdModelNumber" label="${LabelModelNumber}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdModelDesription" label="${LabelModelDescription}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdModelUrl" label="${LabelModelUrl}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdSerialNumber" label="${LabelSerialNumber}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdDeviceDescription" label="${LabelDeviceDescription}" />
|
||||
<div class="fieldDescription">${LabelIdentificationFieldHelp}</div>
|
||||
</div>
|
||||
<div>
|
||||
<h2 style="vertical-align:middle;display:inline-block;">${HeaderHttpHeaders}</h2>
|
||||
<button is="emby-button" type="button" class="fab btnAddIdentificationHttpHeader submit sectionTitleButton" style="margin-left:1em;" title="${Add}">
|
||||
<span class="material-icons add" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="httpHeaderIdentificationList"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div is="emby-collapse" title="${Display}">
|
||||
<div class="collapseContent">
|
||||
<br />
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkRequiresPlainFolders" />
|
||||
<span>${OptionPlainStorageFolders}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${OptionPlainStorageFoldersHelp}</div>
|
||||
</div>
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkRequiresPlainVideoItems" />
|
||||
<span>${OptionPlainVideoItems}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${OptionPlainVideoItemsHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div is="emby-collapse" title="${HeaderImageSettings}">
|
||||
<div class="collapseContent">
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkEnableAlbumArtInDidl" data-mini="true" />
|
||||
<span>${LabelEmbedAlbumArtDidl}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${LabelEmbedAlbumArtDidlHelp}</div>
|
||||
</div>
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkEnableSingleImageLimit" data-mini="true" />
|
||||
<span>${LabelEnableSingleImageInDidlLimit}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${LabelEnableSingleImageInDidlLimitHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input type="text" is="emby-input" id="txtAlbumArtPn" label="${LabelAlbumArtPN}" />
|
||||
<div class="fieldDescription">${LabelAlbumArtHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input type="number" is="emby-input" id="txtAlbumArtMaxWidth" pattern="[0-9]*" min="1" label="${LabelAlbumArtMaxWidth}" />
|
||||
<div class="fieldDescription">${LabelAlbumArtMaxResHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input type="number" is="emby-input" id="txtAlbumArtMaxHeight" pattern="[0-9]*" min="1" label="${LabelAlbumArtMaxHeight}" />
|
||||
<div class="fieldDescription">${LabelAlbumArtMaxResHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input type="number" is="emby-input" id="txtIconMaxWidth" pattern="[0-9]*" min="1" label="${LabelIconMaxWidth}" />
|
||||
<div class="fieldDescription">${LabelIconMaxResHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input type="number" is="emby-input" id="txtIconMaxHeight" pattern="[0-9]*" min="1" label="${LabelIconMaxHeight}" />
|
||||
<div class="fieldDescription">${LabelIconMaxResHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div is="emby-collapse" title="${HeaderServerSettings}">
|
||||
<div class="collapseContent">
|
||||
<p>${HeaderProfileServerSettingsHelp}</p>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtInfoFriendlyName" label="${LabelFriendlyName}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtInfoManufacturer" label="${LabelManufacturer}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtInfoManufacturerUrl" label="${LabelManufacturerUrl}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtInfoModelName" label="${LabelModelName}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtInfoModelNumber" label="${LabelModelNumber}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtInfoModelDesription" label="${LabelModelDescription}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtInfoModelUrl" label="${LabelModelUrl}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtInfoSerialNumber" label="${LabelSerialNumber}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtProtocolInfo" label="${LabelProtocolInfo}" />
|
||||
<div class="fieldDescription">${LabelProtocolInfoHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtXDlnaCap" label="${LabelXDlnaCap}" />
|
||||
<div class="fieldDescription">${LabelXDlnaCapHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtXDlnaDoc" label="${LabelXDlnaDoc}" />
|
||||
<div class="fieldDescription">${LabelXDlnaDocHelp}</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtSonyAggregationFlags" label="${LabelSonyAggregationFlags}" />
|
||||
<div class="fieldDescription">${LabelSonyAggregationFlagsHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div is="emby-collapse" title="${HeaderSubtitleProfiles}">
|
||||
<div class="collapseContent">
|
||||
<p>${HeaderSubtitleProfilesHelp}</p>
|
||||
<button is="emby-button" type="button" class="raised submit block btnAddSubtitleProfile">
|
||||
<span>${Add}</span>
|
||||
</button>
|
||||
<div class="subtitleProfileList"></div>
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
<div is="emby-collapse" title="${HeaderXmlSettings}">
|
||||
<div class="collapseContent">
|
||||
<div>
|
||||
<h2 style="vertical-align:middle;display:inline-block;">${HeaderXmlDocumentAttributes}</h2>
|
||||
<button is="emby-button" type="button" class="fab btnAddXmlDocumentAttribute submit sectionTitleButton" style="margin-left:1em;" title="${Add}">
|
||||
<span class="material-icons add" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="xmlDocumentAttributeList"></div>
|
||||
<div class="fieldDescription">${XmlDocumentAttributeListHelp}</div>
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabContent tabDirectPlayProfiles">
|
||||
<p>${HeaderDirectPlayProfileHelp}</p>
|
||||
<button is="emby-button" class="raised submit block btnAddDirectPlayProfile" type="button" data-mini="true" data-icon="plus">${New}</button>
|
||||
<br />
|
||||
<div class="directPlayProfiles"></div>
|
||||
</div>
|
||||
<div class="tabContent tabTranscodingProfiles">
|
||||
<p>${HeaderTranscodingProfileHelp}</p>
|
||||
<button is="emby-button" class="raised submit block btnAddTranscodingProfile" type="button" data-mini="true" data-icon="plus">${New}</button>
|
||||
<br />
|
||||
<div class="transcodingProfiles"></div>
|
||||
</div>
|
||||
<div class="tabContent tabContainerProfiles">
|
||||
<p>${HeaderContainerProfileHelp}</p>
|
||||
<button is="emby-button" class="raised submit block btnAddContainerProfile" type="button" data-mini="true" data-icon="plus">${New}</button>
|
||||
<br />
|
||||
<div class="containerProfiles"></div>
|
||||
</div>
|
||||
<div class="tabContent tabCodecProfiles">
|
||||
<p>${HeaderCodecProfileHelp}</p>
|
||||
<button is="emby-button" class="raised submit block btnAddCodecProfile" type="button" data-icon="plus">${New}</button>
|
||||
<br />
|
||||
<div class="codecProfiles"></div>
|
||||
</div>
|
||||
<div class="tabContent tabMediaProfiles">
|
||||
<p>${HeaderResponseProfileHelp}</p>
|
||||
<button is="emby-button" class="raised submit block btnAddResponseProfile" type="button" data-mini="true" data-icon="plus">${New}</button>
|
||||
<br />
|
||||
<div class="mediaProfiles"></div>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block">
|
||||
<span>${Save}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="button-cancel raised block" onclick="Dashboard.navigate('dashboard/dlna/profiles');">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div data-role="popup" id="popupEditDirectPlayProfile" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
|
||||
<form class="editDirectPlayProfileForm" style="padding:1em;">
|
||||
<div class="ui-bar-a">
|
||||
<h3 class="sectionTitle">${HeaderDirectPlayProfile}</h3>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div class="selectContainer">
|
||||
<select id="selectDirectPlayProfileType" name="selectDirectPlayProfileType" is="emby-select" label="${LabelType}">
|
||||
<option value="Audio">${Audio}</option>
|
||||
<option value="Photo">${Photo}</option>
|
||||
<option value="Video">${Video}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtDirectPlayContainer" label="${LabelProfileContainer}" />
|
||||
<div class="fieldDescription">${LabelProfileContainersHelp}</div>
|
||||
</div>
|
||||
<div id="fldDirectPlayVideoCodec" style="margin: 1em 0;">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtDirectPlayVideoCodec" label="${LabelProfileVideoCodecs}" />
|
||||
<div class="fieldDescription">${LabelProfileCodecsHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="fldDirectPlayAudioCodec" style="margin: 1em 0 2em;">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtDirectPlayAudioCodec" label="${LabelProfileAudioCodecs}" />
|
||||
<div class="fieldDescription">${LabelProfileCodecsHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block" data-icon="check" data-mini="true">
|
||||
<span>${ButtonOk}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block" data-icon="delete" onclick="$(this).parents('.dialog').addClass('hide');" data-mini="true">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div data-role="popup" id="transcodingProfilePopup" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
|
||||
<form class="transcodingProfileForm" style="padding:1em;">
|
||||
<div class="ui-bar-a">
|
||||
<h3 class="sectionTitle">${HeaderTranscodingProfile}</h3>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div data-role="controlgroup" data-type="horizontal" data-mini="true">
|
||||
<input type="radio" name="radioTranscodingTab" class="radioTabButton" id="radioTranscodingBasics" value="tabTranscodingBasics">
|
||||
<label for="radioTranscodingBasics">${ButtonInfo}</label>
|
||||
<input type="radio" name="radioTranscodingTab" class="radioTabButton" id="radioTranscodingAdvanced" value="tabTranscodingAdvanced">
|
||||
<label for="radioTranscodingAdvanced">${TabAdvanced}</label>
|
||||
</div>
|
||||
<br />
|
||||
<div class="tabContent tabTranscodingBasics" style="display: none;">
|
||||
<div class="selectContainer">
|
||||
<select id="selectTranscodingProfileType" name="selectTranscodingProfileType" is="emby-select" label="${LabelType}">
|
||||
<option value="Audio">${Audio}</option>
|
||||
<option value="Photo">${Photo}</option>
|
||||
<option value="Video">${Video}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="fldTranscodingProtocol" style="margin: 1em 0;">
|
||||
<div class="selectContainer">
|
||||
<select id="selectTranscodingProtocol" name="selectTranscodingProtocol" is="emby-select" label="${LabelProtocol}">
|
||||
<option value="Http">${OptionProtocolHttp}</option>
|
||||
<option value="Hls">${OptionProtocolHls}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtTranscodingContainer" label="${LabelProfileContainer}"; required="required" />
|
||||
</div>
|
||||
<div id="fldTranscodingVideoCodec" style="margin: 1em 0;">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtTranscodingVideoCodec" label="${LabelVideoCodec}" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="fldTranscodingAudioCodec" style="margin: 1em 0;">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtTranscodingAudioCodec" label="${LabelAudioCodec}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabContent tabTranscodingAdvanced" style="display: none;">
|
||||
<div id="fldEnableMpegtsM2TsMode" style="margin: 1em 0;">
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkEnableMpegtsM2TsMode" />
|
||||
<span>${OptionEnableM2tsMode}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${OptionEnableM2tsModeHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="fldEstimateContentLength" style="margin: 1em 0;">
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkEstimateContentLength" />
|
||||
<span>${OptionEstimateContentLength}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="fldReportByteRangeRequests" style="margin: 1em 0;">
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input is="emby-checkbox" type="checkbox" id="chkReportByteRangeRequests" />
|
||||
<span>${OptionReportByteRangeSeekingWhenTranscoding}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${OptionReportByteRangeSeekingWhenTranscodingHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block" data-icon="check" data-mini="true">
|
||||
<span>${ButtonOk}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block" data-icon="delete" onclick="$(this).parents('.dialog').addClass('hide');" data-mini="true">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div data-role="popup" id="containerProfilePopup" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
|
||||
<form class="containerProfileForm" style="padding:1em;">
|
||||
<div class="ui-bar-a">
|
||||
<h3 class="sectionTitle">${HeaderContainerProfile}</h3>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<p>${HeaderContainerProfileHelp}</p>
|
||||
<div class="tabContent tabContainerBasics">
|
||||
<div class="selectContainer">
|
||||
<select id="selectContainerProfileType" name="selectContainerProfileType" is="emby-select" label="${LabelType}">
|
||||
<option value="Audio">${Audio}</option>
|
||||
<option value="Photo">${Photo}</option>
|
||||
<option value="Video">${Video}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtContainerProfileContainer" label="${LabelProfileContainer}" />
|
||||
<div class="fieldDescription">${LabelProfileContainersHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tabContent tabContainerConditions" style="display: none;"></div>
|
||||
<p>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block" data-icon="check" data-mini="true">
|
||||
<span>${ButtonOk}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block" data-icon="delete" onclick="$(this).parents('.dialog').addClass('hide');" data-mini="true">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div data-role="popup" id="codecProfilePopup" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
|
||||
<form class="codecProfileForm" style="padding:1em;">
|
||||
<div class="ui-bar-a">
|
||||
<h3 class="sectionTitle">${HeaderCodecProfile}</h3>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<p>${HeaderCodecProfileHelp}</p>
|
||||
<div class="selectContainer">
|
||||
<select id="selectCodecProfileType" name="selectCodecProfileType" is="emby-select" label="${LabelType}">
|
||||
<option value="Video">${Video}</option>
|
||||
<option value="VideoAudio">${VideoAudio}</option>
|
||||
<option value="Audio">${Audio}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtCodecProfileCodec" label="${LabelProfileCodecs}" />
|
||||
<div class="fieldDescription">${LabelProfileCodecsHelp}</div>
|
||||
</div>
|
||||
<p>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block" data-icon="check" data-mini="true">
|
||||
<span>${ButtonOk}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block" data-icon="delete" onclick="$(this).parents('.dialog').addClass('hide');" data-mini="true">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div data-role="popup" id="responseProfilePopup" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
|
||||
<form class="editResponseProfileForm" style="padding:1em;">
|
||||
<div class="ui-bar-a">
|
||||
<h3 class="sectionTitle">${HeaderResponseProfile}</h3>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div class="selectContainer">
|
||||
<select id="selectResponseProfileType" name="selectResponseProfileType" is="emby-select" label="${LabelType}">
|
||||
<option value="Audio">${Audio}</option>
|
||||
<option value="Photo">${Photo}</option>
|
||||
<option value="Video">${Video}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtResponseProfileContainer" label="${LabelProfileContainer}" />
|
||||
<div class="fieldDescription">${LabelProfileContainersHelp}</div>
|
||||
</div>
|
||||
<div id="fldResponseProfileVideoCodec" style="margin: 1em 0;">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtResponseProfileVideoCodec" label="${LabelProfileVideoCodecs}" />
|
||||
<div class="fieldDescription">${LabelProfileCodecsHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="fldResponseProfileAudioCodec" style="margin: 1em 0 2em;">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtResponseProfileAudioCodec" label="${LabelProfileAudioCodecs}" />
|
||||
<div class="fieldDescription">${LabelProfileCodecsHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block" data-icon="check" data-mini="true">
|
||||
<span>${ButtonOk}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block" data-icon="delete" onclick="$(this).parents('.dialog').addClass('hide');" data-mini="true">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div data-role="popup" id="identificationHeaderPopup" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
|
||||
<form class="identificationHeaderForm" style="padding:1em;">
|
||||
<div class="ui-bar-a">
|
||||
<h3 class="sectionTitle">${HeaderIdentificationHeader}</h3>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdentificationHeaderName" label="${LabelName}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtIdentificationHeaderValue" label="${LabelValue}" />
|
||||
</div>
|
||||
<div class="selectContainer">
|
||||
<select id="selectMatchType" name="selectMatchType" is="emby-select" label="${LabelMatchType}">
|
||||
<option value="Equals">${OptionEquals}</option>
|
||||
<option value="Regex">${OptionRegex}</option>
|
||||
<option value="Substring">${OptionSubstring}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block" data-icon="check" data-mini="true">
|
||||
<span>${ButtonOk}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block" data-icon="delete" onclick="$(this).parents('.dialog').addClass('hide');" data-mini="true">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div data-role="popup" id="xmlAttributePopup" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
|
||||
<form class="xmlAttributeForm" style="padding:1em;">
|
||||
<div class="ui-bar-a">
|
||||
<h3 class="sectionTitle">${HeaderXmlDocumentAttribute}</h3>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtXmlAttributeName" label="${LabelName}" />
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtXmlAttributeValue" label="${LabelValue}" />
|
||||
</div>
|
||||
<p>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block" data-icon="check" data-mini="true">
|
||||
<span>${ButtonOk}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block" data-icon="delete" onclick="$(this).parents('.dialog').addClass('hide');" data-mini="true">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div data-role="popup" id="subtitleProfilePopup" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
|
||||
<form class="subtitleProfileForm" style="padding:1em;">
|
||||
<div class="ui-bar-a">
|
||||
<h3 class="sectionTitle">${HeaderSubtitleProfile}</h3>
|
||||
</div>
|
||||
<div data-role="content">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" id="txtSubtitleProfileFormat" label="${LabelFormat}" />
|
||||
<div class="fieldDescription">${LabelSubtitleFormatHelp}</div>
|
||||
</div>
|
||||
<div class="selectContainer">
|
||||
<select id="selectSubtitleProfileMethod" name="selectSubtitleProfileMethod" is="emby-select" label="${LabelMethod}">
|
||||
<option value="Embed">${OptionEmbedSubtitles}</option>
|
||||
<option value="External">${OptionExternallyDownloaded}</option>
|
||||
<option value="Hls">${OptionHlsSegmentedSubtitles}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="selectContainer">
|
||||
<select id="selectSubtitleProfileDidlMode" name="selectSubtitleProfileDidlMode" is="emby-select" label="${LabelDidlMode}">
|
||||
<option value="">${OptionResElement}</option>
|
||||
<option value="CaptionInfoEx">${OptionCaptionInfoExSamsung}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block" data-icon="check" data-mini="true">
|
||||
<span>${ButtonOk}</span>
|
||||
</button>
|
||||
<button is="emby-button" type="button" class="raised button-cancel block" data-icon="delete" onclick="$(this).parents('.dialog').addClass('hide');" data-mini="true">
|
||||
<span>${ButtonCancel}</span>
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -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 = '<option></option>' + users.map(function (u) {
|
||||
return '<option value="' + u.Id + '">' + escapeHtml(u.Name) + '</option>';
|
||||
}).join('');
|
||||
$('#selectUser', page).html(usersHtml).val(profile.UserId || '');
|
||||
renderSubProfiles(page, profile);
|
||||
}
|
||||
|
||||
function renderIdentificationHeaders(page, headers) {
|
||||
let index = 0;
|
||||
const html = '<div class="paperList">' + headers.map(function (h) {
|
||||
let li = '<div class="listItem">';
|
||||
li += '<span class="material-icons listItemIcon info" aria-hidden="true"></span>';
|
||||
li += '<div class="listItemBody">';
|
||||
li += '<h3 class="listItemBodyText">' + escapeHtml(h.Name + ': ' + (h.Value || '')) + '</h3>';
|
||||
li += '<div class="listItemBodyText secondary">' + escapeHtml(h.Match || '') + '</div>';
|
||||
li += '</div>';
|
||||
li += '<button type="button" is="paper-icon-button-light" class="btnDeleteIdentificationHeader listItemButton" data-index="' + index + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
li += '</div>';
|
||||
index++;
|
||||
return li;
|
||||
}).join('') + '</div>';
|
||||
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 = '<div class="paperList">' + attribute.map(function (h) {
|
||||
let li = '<div class="listItem">';
|
||||
li += '<span class="material-icons listItemIcon info" aria-hidden="true"></span>';
|
||||
li += '<div class="listItemBody">';
|
||||
li += '<h3 class="listItemBodyText">' + escapeHtml(h.Name + ' = ' + (h.Value || '')) + '</h3>';
|
||||
li += '</div>';
|
||||
li += '<button type="button" is="paper-icon-button-light" class="btnDeleteXmlAttribute listItemButton" data-index="0"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
li += '</div>';
|
||||
return li;
|
||||
}).join('') + '</div>';
|
||||
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 = '<div class="paperList">' + profiles.map(function (h) {
|
||||
let li = '<div class="listItem lnkEditSubProfile" data-index="' + index + '">';
|
||||
li += '<span class="material-icons listItemIcon info" aria-hidden="true"></span>';
|
||||
li += '<div class="listItemBody">';
|
||||
li += '<h3 class="listItemBodyText">' + escapeHtml(h.Format || '') + '</h3>';
|
||||
li += '</div>';
|
||||
li += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile listItemButton" data-index="' + index + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
li += '</div>';
|
||||
index++;
|
||||
return li;
|
||||
}).join('') + '</div>';
|
||||
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 += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
let currentType;
|
||||
|
||||
for (const [index, profile] of profiles.entries()) {
|
||||
if (profile.Type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + profile.Type + '</li>';
|
||||
currentType = profile.Type;
|
||||
}
|
||||
|
||||
html += '<div>';
|
||||
html += '<a is="emby-linkbutton" href="#" class="lnkEditSubProfile" data-profileindex="' + index + '">';
|
||||
html += '<p>' + globalize.translate('ValueContainer', profile.Container || allText) + '</p>';
|
||||
|
||||
if (profile.Type == 'Video') {
|
||||
html += '<p>' + globalize.translate('ValueVideoCodec', profile.VideoCodec || allText) + '</p>';
|
||||
html += '<p>' + globalize.translate('ValueAudioCodec', profile.AudioCodec || allText) + '</p>';
|
||||
} else if (profile.Type == 'Audio') {
|
||||
html += '<p>' + globalize.translate('ValueCodec', profile.AudioCodec || allText) + '</p>';
|
||||
}
|
||||
|
||||
html += '</a>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile listItemButton" data-profileindex="' + index + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</ul>';
|
||||
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 += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
let currentType;
|
||||
|
||||
for (let i = 0, length = profiles.length; i < length; i++) {
|
||||
const profile = profiles[i];
|
||||
|
||||
if (profile.Type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + profile.Type + '</li>';
|
||||
currentType = profile.Type;
|
||||
}
|
||||
|
||||
html += '<div>';
|
||||
html += '<a is="emby-linkbutton" href="#" class="lnkEditSubProfile" data-profileindex="' + i + '">';
|
||||
html += '<p>Protocol: ' + (profile.Protocol || 'Http') + '</p>';
|
||||
html += '<p>' + globalize.translate('ValueContainer', profile.Container || allText) + '</p>';
|
||||
|
||||
if (profile.Type == 'Video') {
|
||||
html += '<p>' + globalize.translate('ValueVideoCodec', profile.VideoCodec || allText) + '</p>';
|
||||
html += '<p>' + globalize.translate('ValueAudioCodec', profile.AudioCodec || allText) + '</p>';
|
||||
} else if (profile.Type == 'Audio') {
|
||||
html += '<p>' + globalize.translate('ValueCodec', profile.AudioCodec || allText) + '</p>';
|
||||
}
|
||||
|
||||
html += '</a>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile listItemButton" data-profileindex="' + i + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</ul>';
|
||||
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 += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
let currentType;
|
||||
|
||||
for (let i = 0, length = profiles.length; i < length; i++) {
|
||||
const profile = profiles[i];
|
||||
|
||||
if (profile.Type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + profile.Type + '</li>';
|
||||
currentType = profile.Type;
|
||||
}
|
||||
|
||||
html += '<div>';
|
||||
html += '<a is="emby-linkbutton" href="#" class="lnkEditSubProfile" data-profileindex="' + i + '">';
|
||||
html += '<p>' + globalize.translate('ValueContainer', profile.Container || allText) + '</p>';
|
||||
|
||||
if (profile.Conditions?.length) {
|
||||
html += '<p>';
|
||||
html += globalize.translate('ValueConditions', profile.Conditions.map(function (c) {
|
||||
return c.Property;
|
||||
}).join(', '));
|
||||
html += '</p>';
|
||||
}
|
||||
|
||||
html += '</a>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile listItemButton" data-profileindex="' + i + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</ul>';
|
||||
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 += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
let currentType;
|
||||
|
||||
for (let i = 0, length = profiles.length; i < length; i++) {
|
||||
const profile = profiles[i];
|
||||
const type = profile.Type.replace('VideoAudio', 'Video Audio');
|
||||
|
||||
if (type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + type + '</li>';
|
||||
currentType = type;
|
||||
}
|
||||
|
||||
html += '<div>';
|
||||
html += '<a is="emby-linkbutton" href="#" class="lnkEditSubProfile" data-profileindex="' + i + '">';
|
||||
html += '<p>' + globalize.translate('ValueCodec', profile.Codec || allText) + '</p>';
|
||||
|
||||
if (profile.Conditions?.length) {
|
||||
html += '<p>';
|
||||
html += globalize.translate('ValueConditions', profile.Conditions.map(function (c) {
|
||||
return c.Property;
|
||||
}).join(', '));
|
||||
html += '</p>';
|
||||
}
|
||||
|
||||
html += '</a>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile listItemButton" data-profileindex="' + i + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</ul>';
|
||||
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 += '<ul data-role="listview" data-inset="true" data-split-icon="delete">';
|
||||
let currentType;
|
||||
|
||||
for (let i = 0, length = profiles.length; i < length; i++) {
|
||||
const profile = profiles[i];
|
||||
|
||||
if (profile.Type !== currentType) {
|
||||
html += '<li data-role="list-divider">' + profile.Type + '</li>';
|
||||
currentType = profile.Type;
|
||||
}
|
||||
|
||||
html += '<div>';
|
||||
html += '<a is="emby-linkbutton" href="#" class="lnkEditSubProfile" data-profileindex="' + i + '">';
|
||||
html += '<p>' + globalize.translate('ValueContainer', profile.Container || allText) + '</p>';
|
||||
|
||||
if (profile.Type == 'Video') {
|
||||
html += '<p>' + globalize.translate('ValueVideoCodec', profile.VideoCodec || allText) + '</p>';
|
||||
html += '<p>' + globalize.translate('ValueAudioCodec', profile.AudioCodec || allText) + '</p>';
|
||||
} else if (profile.Type == 'Audio') {
|
||||
html += '<p>' + globalize.translate('ValueCodec', profile.AudioCodec || allText) + '</p>';
|
||||
}
|
||||
|
||||
if (profile.Conditions?.length) {
|
||||
html += '<p>';
|
||||
html += globalize.translate('ValueConditions', profile.Conditions.map(function (c) {
|
||||
return c.Property;
|
||||
}).join(', '));
|
||||
html += '</p>';
|
||||
}
|
||||
|
||||
html += '</a>';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile listItemButton" data-profileindex="' + i + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
html += '</ul>';
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<div id="dlnaProfilesPage" data-role="page" class="page type-interior dlnaPage withTabs">
|
||||
|
||||
<div>
|
||||
<div class="content-primary">
|
||||
|
||||
<div class="readOnlyContent">
|
||||
|
||||
<div class="verticalSection verticalSection-extrabottompadding">
|
||||
<div class="sectionTitleContainer flex align-items-center">
|
||||
<h2 class="sectionTitle">${HeaderCustomDlnaProfiles}</h2>
|
||||
<a is="emby-linkbutton" href="#/dashboard/dlna/profiles/edit" class="fab submit" style="margin:0 0 0 1em">
|
||||
<span class="material-icons add" aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p>${CustomDlnaProfilesHelp}</p>
|
||||
<div class="customProfiles"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="verticalSection">
|
||||
<div class="sectionTitleContainer flex align-items-center">
|
||||
<h2 class="sectionTitle">${HeaderSystemDlnaProfiles}</h2>
|
||||
</div>
|
||||
|
||||
<p>${SystemDlnaProfilesHelp}</p>
|
||||
<div class="systemProfiles"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -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 += '<div class="paperList">';
|
||||
}
|
||||
|
||||
for (let i = 0, length = profiles.length; i < length; i++) {
|
||||
const profile = profiles[i];
|
||||
html += '<div class="listItem listItem-border">';
|
||||
html += '<span class="listItemIcon material-icons live_tv" aria-hidden="true"></span>';
|
||||
html += '<div class="listItemBody two-line">';
|
||||
html += "<a is='emby-linkbutton' style='padding:0;margin:0;' data-ripple='false' class='clearLink' href='#/dashboard/dlna/profiles/edit?id=" + profile.Id + "'>";
|
||||
html += '<div>' + escapeHtml(profile.Name) + '</div>';
|
||||
html += '</a>';
|
||||
html += '</div>';
|
||||
|
||||
if (profile.Type == 'User') {
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnDeleteProfile" data-profileid="' + profile.Id + '" title="' + globalize.translate('Delete') + '"><span class="material-icons delete" aria-hidden="true"></span></button>';
|
||||
}
|
||||
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
if (profiles.length) {
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
<div id="dlnaSettingsPage" data-role="page" class="page type-interior withTabs">
|
||||
|
||||
<div>
|
||||
<div class="content-primary">
|
||||
|
||||
<form class="dlnaSettingsForm">
|
||||
|
||||
<div class="verticalSection">
|
||||
<div class="sectionTitleContainer flex align-items-center">
|
||||
<h2 class="sectionTitle">${Settings}</h2>
|
||||
<a is="emby-linkbutton" rel="noopener noreferrer" class="raised button-alt headerHelpButton" target="_blank" href="https://jellyfin.org/docs/general/networking/dlna">${Help}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkEnablePlayTo" />
|
||||
<span>${LabelEnableDlnaPlayTo}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${LabelEnableDlnaPlayToHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkEnableDlnaDebugLogging" />
|
||||
<span>${LabelEnableDlnaDebugLogging}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${LabelEnableDlnaDebugLoggingHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" id="txtClientDiscoveryInterval" min="1" max="300" label="${LabelEnableDlnaClientDiscoveryInterval}" />
|
||||
<div class="fieldDescription">${LabelEnableDlnaClientDiscoveryIntervalHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkEnableServer" />
|
||||
<span>${LabelEnableDlnaServer}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${LabelEnableDlnaServerHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkBlastAliveMessages" />
|
||||
<span>${LabelEnableBlastAliveMessages}</span>
|
||||
</label>
|
||||
<div class="fieldDescription checkboxFieldDescription">${LabelEnableBlastAliveMessagesHelp}</div>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" id="txtBlastInterval" min="1" max="3600" label="${LabelBlastMessageInterval}" />
|
||||
<div class="fieldDescription">${LabelBlastMessageIntervalHelp}</div>
|
||||
</div>
|
||||
<div class="selectContainer">
|
||||
<select is="emby-select" id="selectUser" data-mini="true" label="${LabelDefaultUser}"></select>
|
||||
<div class="fieldDescription">${LabelDefaultUserHelp}</div>
|
||||
</div>
|
||||
<div>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block">
|
||||
<span>${Save}</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -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 '<option value="' + u.Id + '">' + escapeHtml(u.Name) + '</option>';
|
||||
}).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]);
|
||||
});
|
||||
});
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue