1
0
Fork 0
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:
Luke Pulverenti 2014-01-30 00:20:18 -05:00
parent 7e45bd999d
commit 35f693e709
7 changed files with 147 additions and 10 deletions

View file

@ -790,7 +790,7 @@ a.itemTag:hover {
@media all and (min-width: 1920px) {
.ehsContent {
max-width: 1240px;
max-width: 1260px;
}
}

View file

@ -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">

View file

@ -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>

View file

@ -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>

View file

@ -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>';

View file

@ -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

View file

@ -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>';