mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update startup wizard
This commit is contained in:
parent
681639cc95
commit
b4c8cb07c9
16 changed files with 256 additions and 70 deletions
|
@ -221,7 +221,7 @@
|
|||
|
||||
var html = '';
|
||||
html += '<h2 class="dialogHeader">';
|
||||
html += '<button type="button" is="emby-button" icon="arrow-back" class="fab mini btnCloseDialog" tabindex="-1"><iron-icon icon="arrow-back"></iron-icon></button>';
|
||||
html += '<button type="button" is="emby-button" icon="arrow-back" class="fab mini btnCloseDialog autoSize" tabindex="-1"><i class="md-icon">arrow_back</i></button>';
|
||||
html += '<div style="display:inline-block;margin-left:.6em;vertical-align:middle;">' + (options.header || Globalize.translate('HeaderSelectPath')) + '</div>';
|
||||
html += '</h2>';
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
var currentItem;
|
||||
var currentItemType;
|
||||
var currentDeferred;
|
||||
var currentResolve;
|
||||
var currentReject;
|
||||
var hasChanges = false;
|
||||
var currentSearchResult;
|
||||
|
||||
|
@ -288,7 +289,8 @@
|
|||
currentItemType = currentItem.Type;
|
||||
|
||||
var dlg = dialogHelper.createDialog({
|
||||
size: 'medium'
|
||||
size: 'medium',
|
||||
removeOnClose: true
|
||||
});
|
||||
|
||||
dlg.classList.add('ui-body-b');
|
||||
|
@ -336,9 +338,12 @@
|
|||
|
||||
function onDialogClosed() {
|
||||
|
||||
$(this).remove();
|
||||
loading.hide();
|
||||
currentDeferred.resolveWith(null, [hasChanges]);
|
||||
if (hasChanges) {
|
||||
currentResolve();
|
||||
} else {
|
||||
currentReject();
|
||||
}
|
||||
}
|
||||
|
||||
function showEditorFindNew(itemName, itemYear, itemType, resolveFunc) {
|
||||
|
@ -417,13 +422,14 @@
|
|||
return {
|
||||
show: function (itemId) {
|
||||
|
||||
var deferred = jQuery.Deferred();
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
currentDeferred = deferred;
|
||||
currentResolve = resolve;
|
||||
currentReject = reject;
|
||||
hasChanges = false;
|
||||
|
||||
showEditor(itemId);
|
||||
return deferred.promise();
|
||||
});
|
||||
},
|
||||
|
||||
showFindNew: function (itemName, itemYear, itemType) {
|
||||
|
|
|
@ -311,7 +311,9 @@
|
|||
switch (id) {
|
||||
|
||||
case 'identify':
|
||||
LibraryBrowser.identifyItem(currentItem.Id);
|
||||
LibraryBrowser.identifyItem(currentItem.Id).then(function () {
|
||||
reload(context, currentItem.Id);
|
||||
});
|
||||
break;
|
||||
case 'refresh':
|
||||
showRefreshMenu(context, button);
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
</div>
|
||||
<div class="fieldDescription">
|
||||
<div>${LabelffmpegPathHelp}</div>
|
||||
<div>${LabelffmpegPathHelp2}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
|
|
|
@ -13,6 +13,20 @@
|
|||
Dashboard.hideLoadingMsg();
|
||||
}
|
||||
|
||||
function onSaveEncodingPathFailure(response) {
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
|
||||
var msg = '';
|
||||
|
||||
// This is a fallback that handles both 404 and 400 (no path entered)
|
||||
msg = Globalize.translate('FFmpegSavePathNotFound');
|
||||
|
||||
require(['alert'], function (alert) {
|
||||
alert(msg);
|
||||
});
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
|
||||
var form = this;
|
||||
|
@ -24,13 +38,22 @@
|
|||
|
||||
config.DownMixAudioBoost = $('#txtDownMixAudioBoost', form).val();
|
||||
config.TranscodingTempPath = $('#txtTranscodingTempPath', form).val();
|
||||
config.EncoderAppPath = $('.txtEncoderPath', form).val();
|
||||
config.EncodingThreadCount = $('#selectThreadCount', form).val();
|
||||
config.HardwareAccelerationType = $('#selectVideoDecoder', form).val();
|
||||
|
||||
config.EnableThrottling = form.querySelector('#chkEnableThrottle').checked;
|
||||
|
||||
ApiClient.updateNamedConfiguration("encoding", config).then(Dashboard.processServerConfigurationUpdateResult);
|
||||
ApiClient.updateNamedConfiguration("encoding", config).then(function () {
|
||||
|
||||
ApiClient.ajax({
|
||||
url: ApiClient.getUrl('System/MediaEncoder/Path'),
|
||||
type: 'POST',
|
||||
data: {
|
||||
Path: form.querySelector('.txtEncoderPath').value
|
||||
}
|
||||
}).then(Dashboard.processServerConfigurationUpdateResult, onSaveEncodingPathFailure);
|
||||
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -80,12 +103,11 @@
|
|||
|
||||
require(['directorybrowser'], function (directoryBrowser) {
|
||||
|
||||
var picker = new directoryBrowser({
|
||||
includeFiles: true
|
||||
});
|
||||
var picker = new directoryBrowser();
|
||||
|
||||
picker.show({
|
||||
|
||||
includeFiles: true,
|
||||
callback: function (path) {
|
||||
|
||||
if (path) {
|
||||
|
|
|
@ -981,9 +981,12 @@
|
|||
|
||||
identifyItem: function (itemId) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require(['components/itemidentifier/itemidentifier'], function (itemidentifier) {
|
||||
|
||||
itemidentifier.show(itemId);
|
||||
itemidentifier.show(itemId).then(resolve, reject);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
html += '<button type="button" is="paper-icon-button-light" class=headerButton headerButtonRight headerSearchButton hide autoSize" onclick="Search.showSearchPanel();"><i class="md-icon">search</i></button>';
|
||||
html += '<div class="viewMenuSearch hide">';
|
||||
html += '<form class="viewMenuSearchForm">';
|
||||
html += '<input type="text" data-role="none" data-type="search" class="headerSearchInput" autocomplete="off" spellcheck="off" />';
|
||||
html += '<input type="text" class="headerSearchInput" autocomplete="off" />';
|
||||
html += '<button type="button" is="paper-icon-button-light" class="btnCloseSearch autoSize"><i class="md-icon">close</i></button>';
|
||||
html += '</form>';
|
||||
html += '</div>';
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['libraryBrowser', 'events', 'scrollStyles'], function (libraryBrowser, events) {
|
||||
define(['libraryBrowser', 'events', 'scrollStyles', 'scripts/librarymenu'], function (libraryBrowser, events) {
|
||||
|
||||
var searchHintTimeout;
|
||||
|
||||
|
@ -233,7 +233,6 @@
|
|||
require(['searchmenu'], function (searchmenu) {
|
||||
events.on(window.SearchMenu, 'closed', closeSearchResults);
|
||||
events.on(window.SearchMenu, 'change', function (e, value) {
|
||||
|
||||
onHeaderSearchChange(value);
|
||||
});
|
||||
});
|
||||
|
@ -259,10 +258,7 @@
|
|||
|
||||
document.addEventListener('viewbeforehide', closeSearchResults);
|
||||
|
||||
document.addEventListener('headercreated', function () {
|
||||
|
||||
bindSearchEvents();
|
||||
});
|
||||
|
||||
// dismiss search UI if user clicks a play button on a search result
|
||||
events.on(MediaController, 'beforeplaybackstart', closeSearchResults);
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
function searchMenu() {
|
||||
|
||||
var self = this;
|
||||
var headerSearchInput = document.querySelector('.headerSearchInput');
|
||||
|
||||
self.show = function () {
|
||||
|
||||
require(['css!css/search.css'], function () {
|
||||
|
||||
document.querySelector('.headerSearchInput').value = '';
|
||||
headerSearchInput.value = '';
|
||||
|
||||
document.querySelector('.btnCloseSearch').classList.add('hide');
|
||||
var elem = document.querySelector('.viewMenuSearch');
|
||||
|
@ -25,7 +26,7 @@
|
|||
elem.classList.remove('hide');
|
||||
|
||||
var onFinish = function() {
|
||||
document.querySelector('.headerSearchInput').focus();
|
||||
headerSearchInput.focus();
|
||||
document.querySelector('.btnCloseSearch').classList.remove('hide');
|
||||
};
|
||||
|
||||
|
@ -62,24 +63,8 @@
|
|||
Events.trigger(self, 'closed');
|
||||
});
|
||||
|
||||
document.querySelector('.headerSearchInput').addEventListener('keyup', function (e) {
|
||||
|
||||
// Down key
|
||||
if (e.keyCode == 40) {
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
headerSearchInput.addEventListener('input', function (e) {
|
||||
Events.trigger(self, 'change', [this.value]);
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelector('.headerSearchInput').addEventListener('search', function (e) {
|
||||
if (!this.value) {
|
||||
Events.trigger(self, 'change', ['']);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3019,6 +3019,14 @@ var AppInfo = {};
|
|||
anonymous: true
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
path: '/wizardcomponents.html',
|
||||
dependencies: ['dashboardcss', 'emby-button', 'emby-input'],
|
||||
autoFocus: false,
|
||||
anonymous: true,
|
||||
controller: 'scripts/wizardcomponents'
|
||||
});
|
||||
|
||||
defineRoute({
|
||||
path: '/wizardfinish.html',
|
||||
dependencies: ['emby-button', 'dashboardcss'],
|
||||
|
|
88
dashboard-ui/scripts/wizardcomponents.js
Normal file
88
dashboard-ui/scripts/wizardcomponents.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
define([], function () {
|
||||
|
||||
function goNext() {
|
||||
require(['scripts/wizardcontroller'], function (wizardcontroller) {
|
||||
wizardcontroller.navigateToService();
|
||||
});
|
||||
}
|
||||
|
||||
function loadDownloadInfo(view) {
|
||||
ApiClient.getSystemInfo().then(function (systemInfo) {
|
||||
|
||||
if (systemInfo.OperatingSystem == 'Windows' && systemInfo.SystemArchitecture != 'Arm') {
|
||||
view.querySelector('.suggestedLocation').innerHTML = Globalize.translate('FFmpegSuggestedDownload', '<a target="_blank" href="https://ffmpeg.zeranoe.com/builds">https://ffmpeg.zeranoe.com</a>');
|
||||
|
||||
var instructions = '';
|
||||
|
||||
if (systemInfo.SystemArchitecture == 'X86') {
|
||||
instructions = 'Download 32-Bit Static';
|
||||
}
|
||||
else if (systemInfo.SystemArchitecture == 'X64') {
|
||||
instructions = 'Download 64-Bit Static';
|
||||
}
|
||||
|
||||
view.querySelector('.downloadInstructions').innerHTML = instructions;
|
||||
} else {
|
||||
view.querySelector('.suggestedLocation').innerHTML = Globalize.translate('FFmpegSuggestedDownload', '<a target="_blank" href="http://ffmpeg.org">http://ffmpeg.org</a>');
|
||||
view.querySelector('.downloadInstructions').innerHTML = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onSaveEncodingPathFailure(response) {
|
||||
|
||||
var msg = '';
|
||||
|
||||
// This is a fallback that handles both 404 and 400 (no path entered)
|
||||
msg = Globalize.translate('FFmpegSavePathNotFound');
|
||||
|
||||
require(['alert'], function (alert) {
|
||||
alert(msg);
|
||||
});
|
||||
}
|
||||
|
||||
return function (view, params) {
|
||||
|
||||
view.querySelector('#btnSelectEncoderPath').addEventListener("click", function () {
|
||||
|
||||
require(['directorybrowser'], function (directoryBrowser) {
|
||||
|
||||
var picker = new directoryBrowser();
|
||||
|
||||
picker.show({
|
||||
|
||||
includeFiles: true,
|
||||
callback: function (path) {
|
||||
|
||||
if (path) {
|
||||
view.querySelector('.txtEncoderPath').value = path;
|
||||
}
|
||||
picker.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
view.querySelector('form').addEventListener('submit', function (e) {
|
||||
|
||||
var form = this;
|
||||
|
||||
ApiClient.ajax({
|
||||
url: ApiClient.getUrl('System/MediaEncoder/Path'),
|
||||
type: 'POST',
|
||||
data: {
|
||||
Path: form.querySelector('.txtEncoderPath').value
|
||||
}
|
||||
}).then(goNext, onSaveEncodingPathFailure);
|
||||
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
view.addEventListener('viewbeforeshow', function (e) {
|
||||
|
||||
loadDownloadInfo(view);
|
||||
});
|
||||
};
|
||||
});
|
35
dashboard-ui/scripts/wizardcontroller.js
Normal file
35
dashboard-ui/scripts/wizardcontroller.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
define([], function () {
|
||||
|
||||
function navigateToComponents() {
|
||||
var apiClient = ApiClient;
|
||||
|
||||
apiClient.getJSON(apiClient.getUrl('Startup/Info')).then(function (info) {
|
||||
|
||||
if (info.HasMediaEncoder) {
|
||||
navigateToService();
|
||||
|
||||
} else {
|
||||
Dashboard.navigate('wizardcomponents.html');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function navigateToService() {
|
||||
var apiClient = ApiClient;
|
||||
|
||||
apiClient.getJSON(apiClient.getUrl('Startup/Info')).then(function (info) {
|
||||
|
||||
if (info.SupportsRunningAsService) {
|
||||
Dashboard.navigate('wizardservice.html');
|
||||
|
||||
} else {
|
||||
Dashboard.navigate('wizardagreement.html');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
navigateToComponents: navigateToComponents,
|
||||
navigateToService: navigateToService
|
||||
};
|
||||
});
|
|
@ -56,17 +56,8 @@
|
|||
}
|
||||
|
||||
function skip() {
|
||||
var apiClient = ApiClient;
|
||||
|
||||
apiClient.getJSON(apiClient.getUrl('Startup/Info')).then(function (info) {
|
||||
|
||||
if (info.SupportsRunningAsService) {
|
||||
Dashboard.navigate('wizardservice.html');
|
||||
|
||||
} else {
|
||||
Dashboard.navigate('wizardagreement.html');
|
||||
}
|
||||
|
||||
require(['scripts/wizardcontroller'], function (wizardcontroller) {
|
||||
wizardcontroller.navigateToComponents();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -60,16 +60,8 @@
|
|||
}
|
||||
|
||||
function skip() {
|
||||
var apiClient = ApiClient;
|
||||
|
||||
apiClient.getJSON(apiClient.getUrl('Startup/Info')).then(function (info) {
|
||||
|
||||
if (info.SupportsRunningAsService) {
|
||||
Dashboard.navigate('wizardservice.html');
|
||||
|
||||
} else {
|
||||
Dashboard.navigate('wizardagreement.html');
|
||||
}
|
||||
require(['scripts/wizardcontroller'], function (wizardcontroller) {
|
||||
wizardcontroller.navigateToComponents();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -2373,7 +2373,13 @@
|
|||
"TitleHostingSettings": "Hosting Settings",
|
||||
"SettingsWarning": "Changing these values may cause instability or connectivity failures. If you experience any problems, we recommend changing them back to default.",
|
||||
"MapChannels": "Map Channels",
|
||||
"LabelffmpegPath": "FFMpeg path:",
|
||||
"LabelffmpegPathHelp": "The path to your ffmpeg application, or folder containing ffmpeg.",
|
||||
"LabelffmpegPathHelp2": "Important: FFProbe must also exist within the same folder."
|
||||
"LabelffmpegPath": "FFmpeg path:",
|
||||
"LabelffmpegPathHelp": "The path to your downloaded FFmpeg application, or folder containing FFmpeg.",
|
||||
"SetupFFmpeg": "Setup FFmpeg",
|
||||
"SetupFFmpegHelp": "FFmpeg is a required component and needs to be configured.",
|
||||
"EnterFFmpegLocation": "Enter FFmpeg path",
|
||||
"DownloadFFmpeg": "Download FFmpeg",
|
||||
"FFmpegSuggestedDownload": "Suggested download: {0}",
|
||||
"UnzipFFmpegFile": "Unzip the downloaded file to a folder of your choice.",
|
||||
"FFmpegSavePathNotFound": "We're unable to locaate FFmpeg using the path you've entered. FFprobe is also required and must exist in the same folder. These components are normally bundled together in the same download. Please check the path and try again."
|
||||
}
|
||||
|
|
53
dashboard-ui/wizardcomponents.html
Normal file
53
dashboard-ui/wizardcomponents.html
Normal file
|
@ -0,0 +1,53 @@
|
|||
<div id="wizardComponentsPage" data-role="page" class="page standalonePage wizardPage">
|
||||
|
||||
<div data-role="content">
|
||||
|
||||
<div class="ui-corner-all ui-shadow wizardContent" style="position:relative;">
|
||||
<form>
|
||||
|
||||
<h1>
|
||||
${SetupFFmpeg}
|
||||
</h1>
|
||||
|
||||
<div>${SetupFFmpegHelp}</div>
|
||||
<br />
|
||||
<br />
|
||||
<div style="display: flex; align-items: center;">
|
||||
<div style="width: 24px; height: 24px; border-radius: 1000px; background: #52B54B; color: #fff; display: flex; align-items: center; justify-content: center;">1</div>
|
||||
<div style="margin-left: .5em;">${DownloadFFmpeg}</div>
|
||||
</div>
|
||||
<div style="margin-left:34px;">
|
||||
<p class="suggestedLocation"></p>
|
||||
<div class="downloadInstructions"></div>
|
||||
</div>
|
||||
<br />
|
||||
<div style="display: flex; align-items: center;">
|
||||
<div style="width: 24px; height: 24px; border-radius: 1000px; background: #52B54B; color: #fff; display: flex; align-items: center; justify-content: center;">2</div>
|
||||
<div style="margin-left:.5em;">${UnzipFFmpegFile}</div>
|
||||
</div>
|
||||
<br />
|
||||
<div style="display: flex; align-items: center;">
|
||||
<div style="width: 24px; height: 24px; border-radius: 1000px; background: #52B54B; color: #fff; display: flex; align-items: center; justify-content: center;">3</div>
|
||||
<div style="margin-left:.5em;">${EnterFFmpegLocation}</div>
|
||||
</div>
|
||||
|
||||
<div class="inputContainer fldEncoderPath" style="margin-top:1em;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<div style="flex-grow:1;">
|
||||
<input is="emby-input" class="txtEncoderPath" label="${LabelffmpegPath}" autocomplete="off" required />
|
||||
</div>
|
||||
<button type="button" is="paper-icon-button-light" id="btnSelectEncoderPath" class="autoSize"><i class="md-icon">search</i></button>
|
||||
</div>
|
||||
<div class="fieldDescription">
|
||||
<div>${LabelffmpegPathHelp}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wizardNavigation">
|
||||
<button is="emby-button" type="button" onclick="history.back();" class="raised subdued"><iron-icon icon="arrow-back"></iron-icon><span>${LabelPrevious}</span></button>
|
||||
<button is="emby-button" type="submit" class="raised raised accent"><iron-icon icon="arrow-forward"></iron-icon><span>${LabelNext}</span></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
Loading…
Add table
Add a link
Reference in a new issue