mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
fixes #672 - Support path mapping
This commit is contained in:
parent
7e45bd999d
commit
35f693e709
7 changed files with 147 additions and 10 deletions
|
@ -790,7 +790,7 @@ a.itemTag:hover {
|
|||
|
||||
@media all and (min-width: 1920px) {
|
||||
.ehsContent {
|
||||
max-width: 1240px;
|
||||
max-width: 1260px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="#" data-role="button" class="ui-btn-active">Media Folders</a>
|
||||
<a href="librarypathmapping.html" data-role="button">Path Mapping</a>
|
||||
<a href="librarypathmapping.html" data-role="button">Path Substitution</a>
|
||||
<a href="librarysettings.html" data-role="button">Advanced</a>
|
||||
</div>
|
||||
<div class="readOnlyContent">
|
||||
|
|
|
@ -10,12 +10,48 @@
|
|||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="library.html" data-role="button">Media Folders</a>
|
||||
<a href="#" data-role="button" class="ui-btn-active">Path Mapping</a>
|
||||
<a href="#" data-role="button" class="ui-btn-active">Path Substitution</a>
|
||||
<a href="librarysettings.html" data-role="button">Advanced</a>
|
||||
</div>
|
||||
|
||||
<form id="libraryPathMappingForm">
|
||||
<div class="readOnlyContent">
|
||||
<p>Path substitutions are used for mapping a path on the server to a path that clients are able to access. By allowing clients direct access to media on the server they may be able to play them directly over the network and avoid using server resources to stream and transcode them.</p>
|
||||
</div>
|
||||
|
||||
<table id="tblPaths" data-role="table" data-mode="reflow" class="ui-responsive">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="tbodyPathSubstitutions">
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
<form class="libraryPathMappingForm">
|
||||
|
||||
<div>
|
||||
<h3 class="ui-bar-a" style="padding: .7em 1em;">Add Substitution</h3>
|
||||
<div>
|
||||
<label for="txtFrom">From:</label>
|
||||
<input id="txtFrom" type="text" required="required" data-mini="true" />
|
||||
<div class="fieldDescription">Example: D:\Movies (on the server)</div>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<label for="txtTo">To:</label>
|
||||
<input id="txtTo" type="text" required="required" data-mini="true" />
|
||||
<div class="fieldDescription">Example: \\MyServer\Movies (a path clients can access)</div>
|
||||
</div>
|
||||
<br />
|
||||
<p>
|
||||
<button type="submit" data-mini="true" data-icon="plus">Add</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<div class="content-primary">
|
||||
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
|
||||
<a href="library.html" data-role="button">Media Folders</a>
|
||||
<a href="librarypathmapping.html" data-role="button">Path Mapping</a>
|
||||
<a href="librarypathmapping.html" data-role="button">Path Substitution</a>
|
||||
<a href="#" data-role="button" class="ui-btn-active">Advanced</a>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
}
|
||||
|
||||
options.header = options.header || "Select Media Path";
|
||||
options.instruction = options.instruction || "Any path will do, but for optimal playback of bluray, dvd folders, and games, <b>network paths (UNC)</b> are recommended.";
|
||||
options.instruction = options.instruction || "";
|
||||
|
||||
var html = '<div data-transition="fade" data-role="popup" id="popupDirectoryPicker" class="popup" style="min-width:65%;">';
|
||||
|
||||
|
@ -101,9 +101,12 @@
|
|||
|
||||
html += '<div data-role="content" class="ui-content">';
|
||||
html += '<form>';
|
||||
html += '<p class="directoryPickerHeadline">' + options.instruction + '<br/><br/>Network paths can be entered manually in the event the Network button fails to locate your devices. For example, <b>\\\\my-server</b> or <b>\\\\192.168.1.101</b>.</p>';
|
||||
|
||||
html += '<div style="margin:0;">';
|
||||
var instruction = options.instruction ? options.instruction + '<br/><br/>' : '';
|
||||
|
||||
html += '<p class="directoryPickerHeadline">' + instruction + 'Network paths can be entered manually in the event the Network button fails to locate your devices. For example, <b>\\\\my-server</b> or <b>\\\\192.168.1.101</b>.</p>';
|
||||
|
||||
html += '<div style="margin:20px 0 0;">';
|
||||
html += '<label for="txtDirectoryPickerPath" class="lblDirectoryPickerPath">Current Path:</label>';
|
||||
html += '<div style="width:92%;display:inline-block;"><input id="txtDirectoryPickerPath" name="txtDirectoryPickerPath" type="text" required="required" style="font-weight:bold;" /></div>';
|
||||
html += '<button class="btnRefreshDirectories" type="button" data-icon="refresh" data-inline="true" data-mini="true" data-iconpos="notext">Refresh</button>';
|
||||
|
|
|
@ -1,12 +1,100 @@
|
|||
(function ($, document, window) {
|
||||
|
||||
var currentConfig;
|
||||
|
||||
function remove(page, index) {
|
||||
|
||||
Dashboard.confirm("Are you sure you wish to delete this path substitution?", "Confirm Deletion", function (result) {
|
||||
|
||||
if (result) {
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
config.PathSubstitutions.splice(index, 1);
|
||||
|
||||
ApiClient.updateServerConfiguration(config).done(function () {
|
||||
|
||||
reload(page);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
function addSubstitution(page, config) {
|
||||
|
||||
config.PathSubstitutions.push({
|
||||
From: $('#txtFrom', page).val(),
|
||||
To: $('#txtTo', page).val()
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function reloadPathMappings(page, config) {
|
||||
|
||||
var index = 0;
|
||||
|
||||
var html = config.PathSubstitutions.map(function (map) {
|
||||
|
||||
var mapHtml = '<tr>';
|
||||
|
||||
mapHtml += '<td>';
|
||||
mapHtml += '<button class="btnDeletePath" data-index="' + index + '" data-mini="true" data-inline="true" data-icon="delete" data-iconpos="notext" type="button" style="margin:0 .5em 0 0;">Delete</button>';
|
||||
mapHtml += '</td>';
|
||||
|
||||
mapHtml += '<td style="vertical-align:middle;">';
|
||||
mapHtml += map.From;
|
||||
mapHtml += '</td>';
|
||||
|
||||
mapHtml += '<td style="vertical-align:middle;">';
|
||||
mapHtml += map.To;
|
||||
mapHtml += '</td>';
|
||||
|
||||
mapHtml += '</tr>';
|
||||
|
||||
index++;
|
||||
|
||||
return mapHtml;
|
||||
});
|
||||
|
||||
var elem = $('.tbodyPathSubstitutions', page).html(html.join('')).parents('table').table('refresh').trigger('create');
|
||||
|
||||
$('.btnDeletePath', elem).on('click', function () {
|
||||
|
||||
remove(page, parseInt(this.getAttribute('data-index')));
|
||||
});
|
||||
|
||||
if (config.PathSubstitutions.length) {
|
||||
$('#tblPaths', page).show();
|
||||
} else {
|
||||
$('#tblPaths', page).hide();
|
||||
}
|
||||
}
|
||||
|
||||
function loadPage(page, config) {
|
||||
|
||||
currentConfig = config;
|
||||
|
||||
reloadPathMappings(page, config);
|
||||
Dashboard.hideLoadingMsg();
|
||||
}
|
||||
|
||||
$(document).on('pageshow', ".libraryPathMappingForm", function () {
|
||||
function reload(page) {
|
||||
|
||||
$('#txtFrom', page).val('');
|
||||
$('#txtTo', page).val('');
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
loadPage(page, config);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
$(document).on('pageshow', "#libraryPathMappingPage", function () {
|
||||
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
|
@ -18,6 +106,10 @@
|
|||
|
||||
});
|
||||
|
||||
}).on('pagehide', "#libraryPathMappingPage", function () {
|
||||
|
||||
currentConfig = null;
|
||||
|
||||
});
|
||||
|
||||
window.LibraryPathMappingPage = {
|
||||
|
@ -27,11 +119,15 @@
|
|||
Dashboard.showLoadingMsg();
|
||||
|
||||
var form = this;
|
||||
var page = $(form).parents('.page');
|
||||
|
||||
ApiClient.getServerConfiguration().done(function (config) {
|
||||
|
||||
addSubstitution(page, config);
|
||||
ApiClient.updateServerConfiguration(config).done(function () {
|
||||
|
||||
ApiClient.updateServerConfiguration(config).done(Dashboard.processServerConfigurationUpdateResult);
|
||||
reload(page);
|
||||
});
|
||||
});
|
||||
|
||||
// Disable default form submission
|
||||
|
|
|
@ -155,6 +155,8 @@
|
|||
}
|
||||
html += '</ul>';
|
||||
|
||||
html += '<p>Use <a href="librarypathmapping.html">path substitution</a> to map server paths to network shares that clients are able to access.</p>';
|
||||
|
||||
html += '<p>';
|
||||
html += '<button type="button" data-inline="true" data-icon="minus" data-folderindex="' + index + '" onclick="MediaLibraryPage.deleteVirtualFolder(this);" data-mini="true">Remove</button>';
|
||||
html += '<button type="button" data-inline="true" data-icon="edit" data-folderindex="' + index + '" onclick="MediaLibraryPage.renameVirtualFolder(this);" data-mini="true">Rename</button>';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue