1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Convert userPasswordPage & UserImagePage to react

This commit is contained in:
grafixeyehero 2022-01-05 20:35:58 +03:00 committed by Bill Thornton
parent 4a8806e1f6
commit 2aa41f8a33
8 changed files with 498 additions and 424 deletions

View file

@ -1,72 +1,3 @@
<div id="userPasswordPage" data-role="page" class="page type-interior userPasswordPage">
<div>
<div class="content-primary">
<div class="verticalSection">
<div class="sectionTitleContainer flex align-items-center">
<h2 class="sectionTitle username"></h2>
<a is="emby-linkbutton" rel="noopener noreferrer" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/server/users/">${Help}</a>
</div>
</div>
<div data-role="controlgroup" data-type="horizontal" class="localnav" data-mini="true">
<a is="emby-linkbutton" href="#" data-role="button" onclick="Dashboard.navigate('useredit.html', true);">${Profile}</a>
<a is="emby-linkbutton" href="#" data-role="button" onclick="Dashboard.navigate('userlibraryaccess.html', true);">${TabAccess}</a>
<a is="emby-linkbutton" href="#" data-role="button" onclick="Dashboard.navigate('userparentalcontrol.html', true);">${TabParentalControl}</a>
<a is="emby-linkbutton" href="#" data-role="button" onclick="Dashboard.navigate('userpassword.html', true);" class="ui-btn-active">${HeaderPassword}</a>
</div>
<div class="readOnlyContent">
<form class="updatePasswordForm passwordSection hide" style="margin: 0 auto 2em;">
<div class="detailSection">
<div id="fldCurrentPassword" class="inputContainer hide">
<input is="emby-input" type="password" id="txtCurrentPassword" label="${LabelCurrentPassword}" autocomplete="off" />
</div>
<div class="inputContainer">
<input is="emby-input" type="password" id="txtNewPassword" label="${LabelNewPassword}" autocomplete="off" />
</div>
<div class="inputContainer">
<input is="emby-input" type="password" id="txtNewPasswordConfirm" label="${LabelNewPasswordConfirm}" autocomplete="off" />
</div>
<br />
<div>
<button is="emby-button" type="submit" class="raised button-submit block"><span>${Save}</span></button>
<button is="emby-button" type="button" id="btnResetPassword" class="raised button-cancel block hide">
<span>${ResetPassword}</span>
</button>
</div>
</div>
</form>
<br />
<form class="localAccessForm localAccessSection" style="margin: 0 auto;">
<div class="detailSection">
<div class="detailSectionHeader">
${HeaderEasyPinCode}
</div>
<br />
<div>${EasyPasswordHelp}</div>
<br />
<div class="inputContainer">
<input is="emby-input" type="number" id="txtEasyPassword" label="${LabelEasyPinCode}" autocomplete="off" pattern="[0-9]*" step="1" maxlength="5" />
</div>
<br />
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input type="checkbox" is="emby-checkbox" class="chkEnableLocalEasyPassword" />
<span>${LabelInNetworkSignInWithEasyPassword}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${LabelInNetworkSignInWithEasyPasswordHelp}</div>
</div>
<div>
<button is="emby-button" type="submit" class="raised button-submit block">
<span>${Save}</span>
</button>
<button is="emby-button" type="button" id="btnResetEasyPassword" class="raised button-cancel block hide">
<span>${ButtonResetEasyPassword}</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>

View file

@ -1,182 +0,0 @@
import loading from '../../../components/loading/loading';
import libraryMenu from '../../../scripts/libraryMenu';
import globalize from '../../../scripts/globalize';
import '../../../elements/emby-button/emby-button';
import Dashboard from '../../../scripts/clientUtils';
import toast from '../../../components/toast/toast';
import confirm from '../../../components/confirm/confirm';
/* eslint-disable indent */
function loadUser(page, params) {
const userid = params.userId;
ApiClient.getUser(userid).then(function (user) {
Dashboard.getCurrentUser().then(function (loggedInUser) {
libraryMenu.setTitle(user.Name);
page.querySelector('.username').innerText = user.Name;
let showPasswordSection = true;
let showLocalAccessSection = false;
if (user.ConnectLinkType == 'Guest') {
page.querySelector('.localAccessSection').classList.add('hide');
showPasswordSection = false;
} else if (user.HasConfiguredPassword) {
page.querySelector('#btnResetPassword').classList.remove('hide');
page.querySelector('#fldCurrentPassword').classList.remove('hide');
showLocalAccessSection = true;
} else {
page.querySelector('#btnResetPassword').classList.add('hide');
page.querySelector('#fldCurrentPassword').classList.add('hide');
}
if (showPasswordSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) {
page.querySelector('.passwordSection').classList.remove('hide');
} else {
page.querySelector('.passwordSection').classList.add('hide');
}
if (showLocalAccessSection && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) {
page.querySelector('.localAccessSection').classList.remove('hide');
} else {
page.querySelector('.localAccessSection').classList.add('hide');
}
const txtEasyPassword = page.querySelector('#txtEasyPassword');
txtEasyPassword.value = '';
if (user.HasConfiguredEasyPassword) {
txtEasyPassword.placeholder = '******';
page.querySelector('#btnResetEasyPassword').classList.remove('hide');
} else {
txtEasyPassword.removeAttribute('placeholder');
txtEasyPassword.placeholder = '';
page.querySelector('#btnResetEasyPassword').classList.add('hide');
}
page.querySelector('.chkEnableLocalEasyPassword').checked = user.Configuration.EnableLocalPassword;
import('../../../components/autoFocuser').then(({default: autoFocuser}) => {
autoFocuser.autoFocus(page);
});
});
});
page.querySelector('#txtCurrentPassword').value = '';
page.querySelector('#txtNewPassword').value = '';
page.querySelector('#txtNewPasswordConfirm').value = '';
}
export default function (view, params) {
function saveEasyPassword() {
const userId = params.userId;
const easyPassword = view.querySelector('#txtEasyPassword').value;
if (easyPassword) {
ApiClient.updateEasyPassword(userId, easyPassword).then(function () {
onEasyPasswordSaved(userId);
});
} else {
onEasyPasswordSaved(userId);
}
}
function onEasyPasswordSaved(userId) {
ApiClient.getUser(userId).then(function (user) {
user.Configuration.EnableLocalPassword = view.querySelector('.chkEnableLocalEasyPassword').checked;
ApiClient.updateUserConfiguration(user.Id, user.Configuration).then(function () {
loading.hide();
toast(globalize.translate('SettingsSaved'));
loadUser(view, params);
});
});
}
function savePassword() {
const userId = params.userId;
let currentPassword = view.querySelector('#txtCurrentPassword').value;
const newPassword = view.querySelector('#txtNewPassword').value;
if (view.querySelector('#fldCurrentPassword').classList.contains('hide')) {
// Firefox does not respect autocomplete=off, so clear it if the field is supposed to be hidden (and blank)
// This should only happen when user.HasConfiguredPassword is false, but this information is not passed on
currentPassword = '';
}
ApiClient.updateUserPassword(userId, currentPassword, newPassword).then(function () {
loading.hide();
toast(globalize.translate('PasswordSaved'));
loadUser(view, params);
}, function () {
loading.hide();
Dashboard.alert({
title: globalize.translate('HeaderLoginFailure'),
message: globalize.translate('MessageInvalidUser')
});
});
}
function onSubmit(e) {
const form = this;
if (form.querySelector('#txtNewPassword').value != form.querySelector('#txtNewPasswordConfirm').value) {
toast(globalize.translate('PasswordMatchError'));
} else {
loading.show();
savePassword();
}
e.preventDefault();
return false;
}
function onLocalAccessSubmit(e) {
loading.show();
saveEasyPassword();
e.preventDefault();
return false;
}
function resetPassword() {
const msg = globalize.translate('PasswordResetConfirmation');
confirm(msg, globalize.translate('ResetPassword')).then(function () {
const userId = params.userId;
loading.show();
ApiClient.resetUserPassword(userId).then(function () {
loading.hide();
Dashboard.alert({
message: globalize.translate('PasswordResetComplete'),
title: globalize.translate('ResetPassword')
});
loadUser(view, params);
});
});
}
function resetEasyPassword() {
const msg = globalize.translate('PinCodeResetConfirmation');
confirm(msg, globalize.translate('HeaderPinCodeReset')).then(function () {
const userId = params.userId;
loading.show();
ApiClient.resetEasyPassword(userId).then(function () {
loading.hide();
Dashboard.alert({
message: globalize.translate('PinCodeResetComplete'),
title: globalize.translate('HeaderPinCodeReset')
});
loadUser(view, params);
});
});
}
view.querySelector('.updatePasswordForm').addEventListener('submit', onSubmit);
view.querySelector('.localAccessForm').addEventListener('submit', onLocalAccessSubmit);
view.querySelector('#btnResetEasyPassword').addEventListener('click', resetEasyPassword);
view.querySelector('#btnResetPassword').addEventListener('click', resetPassword);
view.addEventListener('viewshow', function () {
loadUser(view, params);
});
}
/* eslint-enable indent */

View file

@ -1,69 +1,3 @@
<div id="userImagePage" data-role="page" class="page libraryPage userPreferencesPage userPasswordPage noSecondaryNavPage" data-title="${Profile}" data-menubutton="false">
<div class="padded-left padded-right padded-bottom-page">
<div class="readOnlyContent" style="margin: 0 auto; padding: 0 1em;">
<div style="position:relative;display:inline-block;max-width:200px;">
<input id="uploadImage" type="file" accept="image/*" style="position:absolute;right:0;width:100%;height:100%;opacity:0;" />
<div id="image" style="width:200px;height:200px;background-repeat:no-repeat;background-position:center;border-radius:100%;background-size:cover;"></div>
</div>
<div style="vertical-align:top;margin:1em 2em;display:inline-block;">
<h2 class="username" style="margin:0;font-size:xx-large;"></h2>
<br/>
<button is="emby-button" type="button" class="raised hide" id="btnAddImage">
<span>${ButtonAddImage}</span>
</button>
<button is="emby-button" type="button" class="raised hide" id="btnDeleteImage">
<span>${DeleteImage}</span>
</button>
</div>
</div>
<form class="updatePasswordForm passwordSection userProfileSettingsForm hide" style="margin: 3em auto 0;">
<div class="verticalSection">
<h2 class="sectionTitle">
${HeaderPassword}
</h2>
<div id="fldCurrentPassword" class="inputContainer hide">
<input is="emby-input" type="password" id="txtCurrentPassword" label="${LabelCurrentPassword}" autocomplete="off" />
</div>
<div class="inputContainer">
<input is="emby-input" type="password" id="txtNewPassword" label="${LabelNewPassword}" autocomplete="off" />
</div>
<div class="inputContainer">
<input is="emby-input" type="password" id="txtNewPasswordConfirm" label="${LabelNewPasswordConfirm}" autocomplete="off" />
</div>
<div>
<button is="emby-button" type="submit" class="raised button-submit block">
<span>${Save}</span>
</button>
<button is="emby-button" type="button" id="btnResetPassword" class="raised cancel block hide">
<span>${ResetPassword}</span>
</button>
</div>
</div>
</form>
<form class="localAccessForm localAccessSection userProfileSettingsForm hide" style="margin: 3em auto 0;">
<div class="verticalSection">
<h2 class="sectionTitle">${HeaderEasyPinCode}</h2>
<div>${EasyPasswordHelp}</div>
<br />
<div class="inputContainer">
<input is="emby-input" type="number" id="txtEasyPassword" label="${LabelEasyPinCode}" autocomplete="off" pattern="[0-9]*" step="1" maxlength="5" />
</div>
<div class="checkboxContainer checkboxContainer-withDescription">
<label>
<input type="checkbox" is="emby-checkbox" class="chkEnableLocalEasyPassword" />
<span>${LabelInNetworkSignInWithEasyPassword}</span>
</label>
<div class="fieldDescription checkboxFieldDescription">${LabelInNetworkSignInWithEasyPasswordHelp}</div>
</div>
<div>
<button is="emby-button" type="submit" class="raised button-submit block">
<span>${Save}</span>
</button>
<button is="emby-button" type="button" id="btnResetEasyPassword" class="raised cancel block hide">
<span>${ButtonResetEasyPassword}</span>
</button>
</div>
</div>
</form>
</div>
</div>

View file

@ -1,104 +0,0 @@
import UserPasswordPage from '../../dashboard/users/userpasswordpage';
import loading from '../../../components/loading/loading';
import libraryMenu from '../../../scripts/libraryMenu';
import { appHost } from '../../../components/apphost';
import globalize from '../../../scripts/globalize';
import '../../../elements/emby-button/emby-button';
import Dashboard from '../../../scripts/clientUtils';
import toast from '../../../components/toast/toast';
import confirm from '../../../components/confirm/confirm';
function reloadUser(page) {
const userId = getParameterByName('userId');
loading.show();
ApiClient.getUser(userId).then(function (user) {
page.querySelector('.username').innerText = user.Name;
libraryMenu.setTitle(user.Name);
let imageUrl = 'assets/img/avatar.png';
if (user.PrimaryImageTag) {
imageUrl = ApiClient.getUserImageUrl(user.Id, {
tag: user.PrimaryImageTag,
type: 'Primary'
});
}
const userImage = page.querySelector('#image');
userImage.style.backgroundImage = 'url(' + imageUrl + ')';
Dashboard.getCurrentUser().then(function (loggedInUser) {
if (user.PrimaryImageTag) {
page.querySelector('#btnAddImage').classList.add('hide');
page.querySelector('#btnDeleteImage').classList.remove('hide');
} else if (appHost.supports('fileinput') && (loggedInUser.Policy.IsAdministrator || user.Policy.EnableUserPreferenceAccess)) {
page.querySelector('#btnDeleteImage').classList.add('hide');
page.querySelector('#btnAddImage').classList.remove('hide');
}
});
loading.hide();
});
}
function onFileReaderError(evt) {
loading.hide();
switch (evt.target.error.code) {
case evt.target.error.NOT_FOUND_ERR:
toast(globalize.translate('FileNotFound'));
break;
case evt.target.error.ABORT_ERR:
onFileReaderAbort();
break;
case evt.target.error.NOT_READABLE_ERR:
default:
toast(globalize.translate('FileReadError'));
}
}
function onFileReaderAbort() {
loading.hide();
toast(globalize.translate('FileReadCancelled'));
}
function setFiles(page, files) {
const userImage = page.querySelector('#image');
const file = files[0];
if (!file || !file.type.match('image.*')) {
return false;
}
const reader = new FileReader();
reader.onerror = onFileReaderError;
reader.onabort = onFileReaderAbort;
reader.onload = function (evt) {
userImage.style.backgroundImage = 'url(' + evt.target.result + ')';
const userId = getParameterByName('userId');
ApiClient.uploadUserImage(userId, 'Primary', file).then(function () {
loading.hide();
reloadUser(page);
});
};
reader.readAsDataURL(file);
}
export default function (view, params) {
reloadUser(view);
new UserPasswordPage(view, params);
view.querySelector('#btnDeleteImage').addEventListener('click', function () {
confirm(globalize.translate('DeleteImageConfirmation'), globalize.translate('DeleteImage')).then(function () {
loading.show();
const userId = getParameterByName('userId');
ApiClient.deleteUserImage(userId, 'primary').then(function () {
loading.hide();
reloadUser(view);
});
});
});
view.querySelector('#btnAddImage').addEventListener('click', function () {
view.querySelector('#uploadImage').click();
});
view.querySelector('#uploadImage').addEventListener('change', function (evt) {
setFiles(view, evt.target.files);
});
}