diff --git a/dashboard-ui/library.html b/dashboard-ui/library.html index 13a317a158..2ae1751a64 100644 --- a/dashboard-ui/library.html +++ b/dashboard-ui/library.html @@ -40,20 +40,18 @@
- +
- ${LabelFolderType} - -
- ${MediaFolderHelpPluginRequired} -
${ButtonOk} diff --git a/dashboard-ui/scripts/backdrops.js b/dashboard-ui/scripts/backdrops.js index 7d240f19d3..3cc2d8bd04 100644 --- a/dashboard-ui/scripts/backdrops.js +++ b/dashboard-ui/scripts/backdrops.js @@ -16,7 +16,7 @@ return Math.floor(Math.random() * (max - min) + min); } - function getBackdropItemIds(userId, types, parentId) { + function getBackdropItemIds(apiClient, userId, types, parentId) { var key = 'backdrops2_' + userId + (types || '') + (parentId || ''); @@ -42,7 +42,7 @@ ParentId: parentId }; - ApiClient.getItems(Dashboard.getCurrentUserId(), options).done(function (result) { + apiClient.getItems(Dashboard.getCurrentUserId(), options).done(function (result) { var images = result.Items.map(function (i) { return { @@ -61,31 +61,37 @@ function showBackdrop(type) { - getBackdropItemIds(Dashboard.getCurrentUserId(), + var apiClient = ConnectionManager.currentApiClient(); + + if (!apiClient) { + return; + } + + getBackdropItemIds(apiClient, Dashboard.getCurrentUserId(), type, LibraryMenu.getTopParentId()).done(function (images) { - if (images.length) { + if (images.length) { - var index = getRandom(0, images.length - 1); - var item = images[index]; + var index = getRandom(0, images.length - 1); + var item = images[index]; - var screenWidth = $(window).width(); + var screenWidth = $(window).width(); - var imgUrl = ApiClient.getScaledImageUrl(item.id, { - type: "Backdrop", - tag: item.tag, - maxWidth: screenWidth, - quality: 80 - }); + var imgUrl = apiClient.getScaledImageUrl(item.id, { + type: "Backdrop", + tag: item.tag, + maxWidth: screenWidth, + quality: 80 + }); - getElement().css('backgroundImage', 'url(\'' + imgUrl + '\')'); + getElement().css('backgroundImage', 'url(\'' + imgUrl + '\')'); - } else { + } else { - clearBackdrop(); - } - }); + clearBackdrop(); + } + }); } function clearBackdrop() { diff --git a/dashboard-ui/scripts/connectlogin.js b/dashboard-ui/scripts/connectlogin.js index d5e2891f71..17665e02c2 100644 --- a/dashboard-ui/scripts/connectlogin.js +++ b/dashboard-ui/scripts/connectlogin.js @@ -2,28 +2,7 @@ function onLoggedIn() { - ConnectionManager.connect().done(function (result) { - - Dashboard.hideLoadingMsg(); - - switch (result.State) { - - case MediaBrowser.ConnectionState.Unavilable: - // Login succeeded so this should never happen - break; - case MediaBrowser.ConnectionState.ServerSelection: - window.location = 'selectserver.html'; - break; - case MediaBrowser.ConnectionState.ServerSignIn: - // This should never happen in connect mode - break; - case MediaBrowser.ConnectionState.SignedIn: - window.location = 'selectserver.html'; - break; - default: - break; - } - }); + window.location = 'selectserver.html'; } function login(page, username, password) { diff --git a/dashboard-ui/scripts/librarybrowser.js b/dashboard-ui/scripts/librarybrowser.js index d822ad52ca..d20ede70fa 100644 --- a/dashboard-ui/scripts/librarybrowser.js +++ b/dashboard-ui/scripts/librarybrowser.js @@ -1195,7 +1195,9 @@ cssClass += ' ' + LibraryBrowser.getUserDataCssClass(item.UserData.Key); } - if (options.showChildCountIndicator && item.ChildCount) { + // The click through hasn't been working on chrome android + // The > 1 can be removed once this is resolved + if (options.showChildCountIndicator && item.ChildCount > 1) { cssClass += ' groupedCard'; if (item.Type == 'Series') { @@ -1467,6 +1469,10 @@ getPosterViewDisplayName: function (item, displayAsSpecial, includeParentInfo) { + if (!item) { + throw new Error("null item passed into getPosterViewDisplayName"); + } + var name = item.EpisodeTitle || item.Name; if (item.Type == "TvChannel") { diff --git a/dashboard-ui/scripts/medialibrarypage.js b/dashboard-ui/scripts/medialibrarypage.js index 0cc34a3987..01becfb6c8 100644 --- a/dashboard-ui/scripts/medialibrarypage.js +++ b/dashboard-ui/scripts/medialibrarypage.js @@ -1,5 +1,22 @@ var MediaLibraryPage = { + onPageInit: function () { + + var page = this; + $('#selectCollectionType', page).on('change', function() { + + var index = this.selectedIndex; + if (index != -1) { + + var name = this.options[index].innerHTML + .replace('*', '') + .replace('&', '&'); + + $('#txtValue', page).val(name); + } + }); + }, + onPageShow: function () { var page = this; @@ -112,7 +129,7 @@ $('.collectionTypeFieldDescription').show(); - MediaLibraryPage.getTextValue(Globalize.translate('HeaderAddMediaFolder'), Globalize.translate('HeaderAddMediaFolderHelp'), "", true, function (name, type) { + MediaLibraryPage.getTextValue(Globalize.translate('HeaderAddMediaFolder'), Globalize.translate('LabelName'), "", true, function (name, type) { MediaLibraryPage.lastVirtualFolderName = name; @@ -170,9 +187,7 @@ $('#selectCollectionType', popup).html(MediaLibraryPage.getCollectionTypeOptionsHtml()).val('').selectmenu('refresh'); - popup.on("popupafteropen", function () { - $('#textEntryForm input:first', this).focus(); - }).on("popupafterclose", function () { + popup.on("popupafterclose", function () { $(this).off("popupafterclose").off("click"); $('#textEntryForm', this).off("submit"); }).popup("open"); @@ -322,7 +337,7 @@ } }; -$(document).on('pageshow', ".mediaLibraryPage", MediaLibraryPage.onPageShow); +$(document).on('pageinit', ".mediaLibraryPage", MediaLibraryPage.onPageInit).on('pageshow', ".mediaLibraryPage", MediaLibraryPage.onPageShow); var WizardLibraryPage = { diff --git a/dashboard-ui/scripts/myprofile.js b/dashboard-ui/scripts/myprofile.js index 13e6041582..ec818baa85 100644 --- a/dashboard-ui/scripts/myprofile.js +++ b/dashboard-ui/scripts/myprofile.js @@ -15,17 +15,23 @@ Dashboard.setPageTitle(user.Name); + var imageUrl; + if (user.PrimaryImageTag) { - var imageUrl = ApiClient.getUserImageUrl(user.Id, { + imageUrl = ApiClient.getUserImageUrl(user.Id, { height: 200, tag: user.PrimaryImageTag, type: "Primary" }); - $('#fldImage', page).show().html('').html(""); + } else { + imageUrl = "css/images/logindefault.png"; } + $('#fldImage', page).show().html('').html(""); + + if (user.ConnectLinkType == 'Guest') { $('.newImageForm', page).hide(); @@ -40,10 +46,9 @@ $('.connectMessage', page).hide(); } else { - $('.newImageSection', page).show(); - $('#fldImage', page).hide().html(''); + $('.newImageForm', page).show(); $('#btnDeleteImage', page).hide(); - $('#headerUploadNewImage', page).hide(); + $('#headerUploadNewImage', page).show(); $('.connectMessage', page).hide(); } diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index e7b0bbecd8..005dc62603 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -56,7 +56,7 @@ var Dashboard = { Dashboard.alert({ message: Globalize.translate('MessageLoggedOutParentalControl'), - callback: function() { + callback: function () { Dashboard.logout(false); } }); @@ -82,6 +82,11 @@ var Dashboard = { } }, + onApiClientServerAddressChanged: function () { + + Dashboard.serverAddress(ApiClient.serverAddress()); + }, + getCurrentUser: function () { if (!Dashboard.getUserPromise) { @@ -1236,7 +1241,8 @@ var Dashboard = { $(apiClient).off('.dashboard') .on("websocketmessage.dashboard", Dashboard.onWebSocketMessageReceived) - .on('requestfail.dashboard', Dashboard.onRequestFail); + .on('requestfail.dashboard', Dashboard.onRequestFail) + .on('serveraddresschanged.dashboard', Dashboard.onApiClientServerAddressChanged); // TODO: Improve with http://webpjs.appspot.com/ apiClient.supportsWebP($.browser.chrome); diff --git a/dashboard-ui/scripts/useredit.js b/dashboard-ui/scripts/useredit.js index 9b29839108..93ee790edc 100644 --- a/dashboard-ui/scripts/useredit.js +++ b/dashboard-ui/scripts/useredit.js @@ -2,47 +2,21 @@ var currentUser; - function loadUser(page, user, loggedInUser) { + function loadUser(page, user) { currentUser = user; - if (!loggedInUser.Configuration.IsAdministrator) { - - $('#fldIsAdmin', page).hide(); - $('#featureAccessFields', page).hide(); - $('#accessControlDiv', page).hide(); - - } else { - - $('#accessControlDiv', page).show(); - $('#fldIsAdmin', page).show(); - $('#featureAccessFields', page).show(); - $('.lnkEditUserPreferencesContainer', page).show(); - } - - if (user.Id && loggedInUser.Configuration.IsAdministrator && user.ConnectLinkType != 'Guest') { - $('#fldConnectInfo', page).show(); - } else { - $('#fldConnectInfo', page).hide(); - } - if (user.ConnectLinkType == 'Guest') { + $('#fldConnectInfo', page).hide(); $('#txtUserName', page).prop("disabled", "disabled"); } else { $('#txtUserName', page).prop("disabled", "").removeAttr('disabled'); + $('#fldConnectInfo', page).show(); } - if (!loggedInUser.Configuration.IsAdministrator || !user.Id) { + $('.lnkEditUserPreferences', page).attr('href', 'mypreferencesdisplay.html?userId=' + user.Id); - $('.lnkEditUserPreferencesContainer', page).hide(); - - } else { - - $('.lnkEditUserPreferencesContainer', page).show(); - $('.lnkEditUserPreferences', page).attr('href', 'mypreferencesdisplay.html?userId=' + user.Id); - } - - Dashboard.setPageTitle(user.Name || Globalize.translate('AddUser')); + Dashboard.setPageTitle(user.Name); $('#txtUserName', page).val(user.Name); $('#txtConnectUserName', page).val(currentUser.ConnectUserName); @@ -68,24 +42,17 @@ Dashboard.hideLoadingMsg(); - var userId = getParameterByName("userId"); + var currentConnectUsername = currentUser.ConnectUserName || ''; + var enteredConnectUsername = $('#txtConnectUserName', page).val(); - if (userId) { - - var currentConnectUsername = currentUser.ConnectUserName || ''; - var enteredConnectUsername = $('#txtConnectUserName', page).val(); - - if (currentConnectUsername == enteredConnectUsername) { - Dashboard.alert(Globalize.translate('SettingsSaved')); - } else { - - ConnectHelper.updateUserInfo(user, $('#txtConnectUserName', page).val(), function () { - - loadData(page); - }); - } + if (currentConnectUsername == enteredConnectUsername) { + Dashboard.alert(Globalize.translate('SettingsSaved')); } else { - Dashboard.navigate("userprofiles.html"); + + ConnectHelper.updateUserInfo(user, $('#txtConnectUserName', page).val(), function () { + + loadData(page); + }); } } @@ -106,18 +73,9 @@ user.Configuration.EnableContentDeletion = $('#chkEnableContentDeletion', page).checked(); user.Configuration.EnableUserPreferenceAccess = !$('#chkDisableUserPreferences', page).checked(); - var userId = getParameterByName("userId"); - - if (userId) { - ApiClient.updateUser(user).done(function () { - onSaveComplete(page, user); - }); - } else { - ApiClient.createUser(user).done(function (newUser) { - Dashboard.navigate("useredit.html?userId=" + newUser.Id); - - }); - } + ApiClient.updateUser(user).done(function () { + onSaveComplete(page, user); + }); } function editUserPage() { @@ -143,36 +101,16 @@ var userId = getParameterByName("userId"); - if (userId) { - - return ApiClient.getUser(userId); - } - - var deferred = $.Deferred(); - - deferred.resolveWith(null, [{ - Configuration: { - IsAdministrator: false, - EnableLiveTvManagement: true, - EnableLiveTvAccess: true, - EnableRemoteControlOfOtherUsers: true, - EnableMediaPlayback: true - } - }]); - - return deferred.promise(); + return ApiClient.getUser(userId); } function loadData(page) { Dashboard.showLoadingMsg(); - var promise1 = getUser(); - var promise2 = Dashboard.getCurrentUser(); + getUser().done(function (user) { - $.when(promise1, promise2).done(function (response1, response2) { - - loadUser(page, response1[0] || response1, response2[0]); + loadUser(page, user); }); } @@ -183,27 +121,6 @@ var page = this; - var userId = getParameterByName("userId"); - - if (userId) { - $('#userProfileNavigation', page).show(); - } else { - $('#userProfileNavigation', page).hide(); - } - - Dashboard.getCurrentUser().done(function (loggedInUser) { - - if (loggedInUser.Configuration.IsAdministrator) { - $('#lnkParentalControl', page).show(); - } else { - $('#lnkParentalControl', page).hide(); - } - }); - - }).on('pageshow', "#editUserPage", function () { - - var page = this; - loadData(page); }); @@ -254,7 +171,7 @@ }, dataType: 'json' - }).done(function(result) { + }).done(function (result) { var msgKey = result.IsPending ? 'MessagePendingMediaBrowserAccountAdded' : 'MessageMediaBrowserAccountAdded'; diff --git a/dashboard-ui/scripts/usernew.js b/dashboard-ui/scripts/usernew.js new file mode 100644 index 0000000000..204c329e2c --- /dev/null +++ b/dashboard-ui/scripts/usernew.js @@ -0,0 +1,54 @@ +(function ($, window, document) { + + function loadUser(page, user) { + + $('#txtUserName', page).val(user.Name); + } + + function saveUser(user, page) { + + user.Name = $('#txtUserName', page).val(); + + ApiClient.createUser(user).done(function (newUser) { + Dashboard.navigate("useredit.html?userId=" + newUser.Id); + }); + } + + function newUserPage() { + + var self = this; + + self.onSubmit = function () { + + var page = $(this).parents('.page'); + + Dashboard.showLoadingMsg(); + + saveUser(getUser(), page); + + // Disable default form submission + return false; + }; + } + + function getUser() { + + return {}; + } + + function loadData(page) { + + loadUser(page, getUser()); + } + + window.NewUserPage = new newUserPage(); + + $(document).on('pageshow', "#newUserPage", function () { + + var page = this; + + loadData(page); + + }); + +})(jQuery, window, document); \ No newline at end of file diff --git a/dashboard-ui/scripts/userpassword.js b/dashboard-ui/scripts/userpassword.js new file mode 100644 index 0000000000..764f764ff9 --- /dev/null +++ b/dashboard-ui/scripts/userpassword.js @@ -0,0 +1,33 @@ +(function ($, window, document) { + + function loadUser(page, user) { + + Dashboard.setPageTitle(user.Name); + + $('.lnkEditUserPreferences', page).attr('href', 'myprofile.html?userId=' + user.Id); + + Dashboard.hideLoadingMsg(); + } + + function loadData(page) { + + Dashboard.showLoadingMsg(); + + var userId = getParameterByName("userId"); + + ApiClient.getUser(userId).done(function (user) { + + loadUser(page, user); + + }); + } + + $(document).on('pagebeforeshow', "#userPasswordPage", function () { + + var page = this; + + loadData(page); + + }); + +})(jQuery, window, document); \ No newline at end of file diff --git a/dashboard-ui/thirdparty/apiclient/connectionmanager.js b/dashboard-ui/thirdparty/apiclient/connectionmanager.js index 00928b700b..ec602cf202 100644 --- a/dashboard-ui/thirdparty/apiclient/connectionmanager.js +++ b/dashboard-ui/thirdparty/apiclient/connectionmanager.js @@ -8,7 +8,8 @@ Unavilable: 0, ServerSelection: 1, ServerSignIn: 2, - SignedIn: 3 + SignedIn: 3, + ConnectSignIn: 4 }; globalScope.MediaBrowser.ConnectionMode = { @@ -519,60 +520,41 @@ if (servers.length == 1) { - if (!servers[0].DateLastAccessed && !self.connectUserId()) { + self.connectToServer(servers[0]).done(function (result) { - deferred.resolveWith(null, [ - { - Servers: servers, - State: MediaBrowser.ConnectionState.ServerSelection, - ConnectUser: self.connectUser() - } - ]); + if (result.State == MediaBrowser.ConnectionState.Unavailable) { - } else { + result.State = result.ConnectUser == null ? + MediaBrowser.ConnectionState.ConnectSignIn : + MediaBrowser.ConnectionState.ServerSelection; + } - self.connectToServer(servers[0]).done(function (result) { + deferred.resolveWith(null, [result]); - if (result.State == MediaBrowser.ConnectionState.Unavailable) { - result.State = MediaBrowser.ConnectionState.ServerSelection; - } - - deferred.resolveWith(null, [result]); - - }).fail(function () { - - deferred.resolveWith(null, [ - { - Servers: servers, - State: MediaBrowser.ConnectionState.ServerSelection, - ConnectUser: self.connectUser() - } - ]); - - }); - } + }); } else { // Find the first server with a saved access token var currentServer = servers.filter(function (s) { - return s.AccessToken; + return s.AccessToken || (s.ExchangeToken && self.connectUser()); })[0]; if (currentServer) { self.connectToServer(currentServer).done(function (result) { - deferred.resolveWith(null, [result]); + if (result.State == MediaBrowser.ConnectionState.SignedIn) { - }).fail(function () { + deferred.resolveWith(null, [result]); - deferred.resolveWith(null, [ + } else { + deferred.resolveWith(null, [ { Servers: servers, - State: MediaBrowser.ConnectionState.ServerSelection, + State: (!servers.length && !self.connectUser()) ? MediaBrowser.ConnectionState.ConnectSignIn : MediaBrowser.ConnectionState.ServerSelection, ConnectUser: self.connectUser() - } - ]); + }]); + } }); } else { @@ -580,7 +562,7 @@ deferred.resolveWith(null, [ { Servers: servers, - State: (!servers.length && !self.connectUser()) ? MediaBrowser.ConnectionState.Unavailable : MediaBrowser.ConnectionState.ServerSelection, + State: (!servers.length && !self.connectUser()) ? MediaBrowser.ConnectionState.ConnectSignIn : MediaBrowser.ConnectionState.ServerSelection, ConnectUser: self.connectUser() }]); } diff --git a/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js b/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js index 8cf8e75509..fda1ac7ea9 100644 --- a/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js +++ b/dashboard-ui/thirdparty/apiclient/mediabrowser.apiclient.js @@ -31,7 +31,18 @@ /** * Gets the server address. */ - self.serverAddress = function () { + self.serverAddress = function (val) { + + if (val != null) { + + var changed = val != serverAddress; + + serverAddress = val; + + if (changed) { + $(this).trigger('serveraddresschanged'); + } + } return serverAddress; }; @@ -141,6 +152,7 @@ } if (!self.enableAutomaticNetwork || !self.serverInfo() || self.connectionMode == null) { + console.log('Requesting url without automatic networking: ' + request.url); return $.ajax(request).fail(onRequestFail); } @@ -172,6 +184,8 @@ self.serverInfo().LocalAddress : self.serverInfo().RemoteAddress; + console.log("Attempting reconnection to " + url); + $.ajax({ type: "GET", @@ -182,6 +196,8 @@ }).done(function () { + console.log("Reconnect succeeeded to " + url); + self.connectionMode = connectionMode; self.serverAddress(url); @@ -189,6 +205,8 @@ }).fail(function () { + console.log("Reconnect attempt failed to " + url); + if (currentRetryCount <= 6) { var newConnectionMode = switchConnectionMode(connectionMode); @@ -234,20 +252,31 @@ request.url = replaceServerAddress(request.url, baseUrl); } + console.log("Requesting " + request.url); + + request.timeout = 3000; + $.ajax(request).done(function (response) { - deferred.resolveWith(null, [response]); + deferred.resolve(response, 0); }).fail(function (e, textStatus) { + console.log("Request failed with textStatus " + textStatus + " to " + request.url); + + var statusCode = parseInt(e.status || '0'); + var isUserErrorCode = statusCode >= 400 && statusCode < 500; + // http://api.jquery.com/jQuery.ajax/ - if (enableReconnection && textStatus == "timeout") { + if (enableReconnection && !isUserErrorCode) { tryReconnect().done(function () { + console.log("Reconnect succeesed"); self.ajaxWithFailover(request, deferred, false, true); }).fail(function () { + console.log("Reconnect failed"); onRetryRequestFail(request); deferred.reject(); diff --git a/dashboard-ui/useredit.html b/dashboard-ui/useredit.html index 7a3527662e..34ff137475 100644 --- a/dashboard-ui/useredit.html +++ b/dashboard-ui/useredit.html @@ -9,10 +9,11 @@ - + ${TabProfile} - ${TabLibraryAccess} + ${TabLibraryAccess} ${TabParentalControl} + ${TabPassword} ${ButtonEditOtherUserPreferences} @@ -33,7 +34,7 @@ - + ${OptionAllowUserToManageServer} @@ -52,7 +53,7 @@ ${OptionAllowRemoteControlOthers} - + ${HeaderAdvancedControl} diff --git a/dashboard-ui/userlibraryaccess.html b/dashboard-ui/userlibraryaccess.html index a4c92163d9..1701237f1f 100644 --- a/dashboard-ui/userlibraryaccess.html +++ b/dashboard-ui/userlibraryaccess.html @@ -12,6 +12,7 @@ ${TabProfile} ${TabLibraryAccess} ${TabParentalControl} + ${TabPassword} diff --git a/dashboard-ui/usernew.html b/dashboard-ui/usernew.html new file mode 100644 index 0000000000..ddbf049f69 --- /dev/null +++ b/dashboard-ui/usernew.html @@ -0,0 +1,38 @@ + + + + ${TitleNewUser} + + + + + + + + + + + ${LabelName} + + + + + + + + ${ButtonSave} + + + ${ButtonCancel} + + + + + + + + + + diff --git a/dashboard-ui/userparentalcontrol.html b/dashboard-ui/userparentalcontrol.html index 621d629c90..2dee9746f8 100644 --- a/dashboard-ui/userparentalcontrol.html +++ b/dashboard-ui/userparentalcontrol.html @@ -12,6 +12,7 @@ ${TabProfile} ${TabLibraryAccess} ${TabParentalControl} + ${TabPassword} @@ -80,7 +81,7 @@ ${OptionEveryday} ${OptionWeekdays} ${OptionWeekends} - + ${LabelAccessStart} diff --git a/dashboard-ui/userpassword.html b/dashboard-ui/userpassword.html new file mode 100644 index 0000000000..71c9214ad6 --- /dev/null +++ b/dashboard-ui/userpassword.html @@ -0,0 +1,28 @@ + + + + + + + + + + + + ${TabProfile} + ${TabLibraryAccess} + ${TabParentalControl} + ${TabPassword} + + + + ${HeaderDashboardUserPassword} + + ${ButtonConfigurePassword} + + + + + + + diff --git a/dashboard-ui/userprofiles.html b/dashboard-ui/userprofiles.html index df01f06042..60abb7b2fb 100644 --- a/dashboard-ui/userprofiles.html +++ b/dashboard-ui/userprofiles.html @@ -16,7 +16,7 @@ ${HeaderUsers} - + ${ButtonAddUser} diff --git a/dashboard-ui/wizardlibrary.html b/dashboard-ui/wizardlibrary.html index 951bf554ca..de88c7d10f 100644 --- a/dashboard-ui/wizardlibrary.html +++ b/dashboard-ui/wizardlibrary.html @@ -29,20 +29,22 @@ + + ${LabelType} + + + ${MediaFolderHelpPluginRequired} + + - + - - - ${LabelFolderType} - - - - ${MediaFolderHelpPluginRequired} - + - ${ButtonOk} + + ${ButtonOk} + ${ButtonCancel}
${ButtonEditOtherUserPreferences} @@ -33,7 +34,7 @@
${HeaderDashboardUserPassword}
+ ${ButtonConfigurePassword} +
${MediaFolderHelpPluginRequired}
- ${ButtonOk} + + ${ButtonOk} + ${ButtonCancel}