diff options
author | Arthur Schiwon <blizzz@arthur-schiwon.de> | 2017-05-16 02:46:42 +0200 |
---|---|---|
committer | Arthur Schiwon <blizzz@arthur-schiwon.de> | 2017-06-23 12:36:37 +0200 |
commit | 045f652ef2844e3917b4ae7f3bbb5abb3422d02b (patch) | |
tree | bc4dc49e5d83d7f2bd7220f55db6fa7b498df686 /settings | |
parent | 039ee7e3aa33284999526a15231ddd0b676c81bd (diff) | |
download | nextcloud-server-045f652ef2844e3917b4ae7f3bbb5abb3422d02b.tar.gz nextcloud-server-045f652ef2844e3917b4ae7f3bbb5abb3422d02b.zip |
completing PersonalInfo
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Diffstat (limited to 'settings')
-rw-r--r-- | settings/js/settings/personalInfo.js | 392 | ||||
-rw-r--r-- | settings/routes.php | 2 | ||||
-rw-r--r-- | settings/templates/settings/personal/personal.info.php | 16 |
3 files changed, 409 insertions, 1 deletions
diff --git a/settings/js/settings/personalInfo.js b/settings/js/settings/personalInfo.js new file mode 100644 index 00000000000..9496f65a8f3 --- /dev/null +++ b/settings/js/settings/personalInfo.js @@ -0,0 +1,392 @@ +/* global OC */ + +/** + * Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com> + * 2013, Morris Jobke <morris.jobke@gmail.com> + * 2016, Christoph Wurst <christoph@owncloud.com> + * 2017, Arthur Schiwon <blizzz@arthur-schiwon.de> + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +OC.Settings = OC.Settings || {}; + +/** + * The callback will be fired as soon as enter is pressed by the + * user or 1 second after the last data entry + * + * @param callback + * @param allowEmptyValue if this is set to true the callback is also called when the value is empty + */ +jQuery.fn.keyUpDelayedOrEnter = function (callback, allowEmptyValue) { + var cb = callback; + var that = this; + + this.on('input', _.debounce(function (event) { + // enter is already handled in keypress + if (event.keyCode === 13) { + return; + } + if (allowEmptyValue || that.val() !== '') { + cb(event); + } + }, 1000)); + + this.keypress(function (event) { + if (event.keyCode === 13 && (allowEmptyValue || that.val() !== '')) { + event.preventDefault(); + cb(event); + } + }); +}; + +function updateAvatar (hidedefault) { + var $headerdiv = $('#header .avatardiv'); + var $displaydiv = $('#displayavatar .avatardiv'); + + //Bump avatar avatarversion + oc_userconfig.avatar.version = -(Math.floor(Math.random() * 1000)); + + if (hidedefault) { + $headerdiv.hide(); + $('#header .avatardiv').removeClass('avatardiv-shown'); + } else { + $headerdiv.css({'background-color': ''}); + $headerdiv.avatar(OC.currentUser, 32, true); + $('#header .avatardiv').addClass('avatardiv-shown'); + } + $displaydiv.css({'background-color': ''}); + $displaydiv.avatar(OC.currentUser, 145, true, null, function() { + $displaydiv.removeClass('loading'); + $('#displayavatar img').show(); + if($('#displayavatar img').length === 0) { + $('#removeavatar').removeClass('inlineblock').addClass('hidden'); + } else { + $('#removeavatar').removeClass('hidden').addClass('inlineblock'); + } + }); +} + +function showAvatarCropper () { + var $cropper = $('#cropper'); + var $cropperImage = $('<img/>'); + $cropperImage.css('opacity', 0); // prevent showing the unresized image + $cropper.children('.inner-container').prepend($cropperImage); + + $cropperImage.attr('src', + OC.generateUrl('/avatar/tmp') + '?requesttoken=' + encodeURIComponent(oc_requesttoken) + '#' + Math.floor(Math.random() * 1000)); + + $cropperImage.load(function () { + var img = $cropperImage.get()[0]; + var selectSize = Math.min(img.width, img.height); + var offsetX = (img.width - selectSize) / 2; + var offsetY = (img.height - selectSize) / 2; + $cropperImage.Jcrop({ + onChange: saveCoords, + onSelect: saveCoords, + aspectRatio: 1, + boxHeight: Math.min(500, $('#app-content').height() -100), + boxWidth: Math.min(500, $('#app-content').width()), + setSelect: [offsetX, offsetY, selectSize, selectSize] + }, function() { + $cropper.show(); + }); + }); +} + +function sendCropData () { + cleanCropper(); + + var cropperData = $('#cropper').data(); + var data = { + x: cropperData.x, + y: cropperData.y, + w: cropperData.w, + h: cropperData.h + }; + $.post(OC.generateUrl('/avatar/cropped'), {crop: data}, avatarResponseHandler); +} + +function saveCoords (c) { + $('#cropper').data(c); +} + +function cleanCropper () { + var $cropper = $('#cropper'); + $('#displayavatar').show(); + $cropper.hide(); + $('.jcrop-holder').remove(); + $('#cropper img').removeData('Jcrop').removeAttr('style').removeAttr('src'); + $('#cropper img').remove(); +} + +function avatarResponseHandler (data) { + if (typeof data === 'string') { + data = JSON.parse(data); + } + var $warning = $('#avatarform .warning'); + $warning.hide(); + if (data.status === "success") { + updateAvatar(); + } else if (data.data === "notsquare") { + showAvatarCropper(); + } else { + $warning.show(); + $warning.text(data.data.message); + } +} + +$(document).ready(function () { + if($('#pass2').length) { + $('#pass2').showPassword().keyup(); + } + + var removeloader = function () { + setTimeout(function(){ + if ($('.password-state').length > 0) { + $('.password-state').remove(); + } + }, 5000) + }; + + $("#passwordbutton").click(function () { + var isIE8or9 = $('html').hasClass('lte9'); + // FIXME - TODO - once support for IE8 and IE9 is dropped + // for IE8 and IE9 this will check additionally if the typed in password + // is different from the placeholder, because in IE8/9 the placeholder + // is simply set as the value to look like a placeholder + if ($('#pass1').val() !== '' && $('#pass2').val() !== '' + && !(isIE8or9 && $('#pass2').val() === $('#pass2').attr('placeholder'))) { + // Serialize the data + var post = $("#passwordform").serialize(); + $('#passwordchanged').hide(); + $('#passworderror').hide(); + $("#passwordbutton").attr('disabled', 'disabled'); + $("#passwordbutton").after("<span class='password-loading icon icon-loading-small-dark password-state'></span>"); + $(".personal-show-label").hide(); + // Ajax foo + $.post(OC.generateUrl('/settings/personal/changepassword'), post, function (data) { + if (data.status === "success") { + $("#passwordbutton").after("<span class='checkmark icon icon-checkmark password-state'></span>"); + removeloader(); + $(".personal-show-label").show(); + $('#pass1').val(''); + $('#pass2').val('').change(); + } + if (typeof(data.data) !== "undefined") { + OC.msg.finishedSaving('#password-error-msg', data); + } else { + OC.msg.finishedSaving('#password-error-msg', + { + 'status' : 'error', + 'data' : { + 'message' : t('core', 'Unable to change password') + } + } + ); + } + $(".password-loading").remove(); + $("#passwordbutton").removeAttr('disabled'); + }); + return false; + } else { + OC.msg.finishedSaving('#password-error-msg', + { + 'status' : 'error', + 'data' : { + 'message' : t('core', 'Unable to change password') + } + } + ); + return false; + } + }); + + var showVerifyDialog = function(dialog, howToVerify, verificationCode) { + var dialogContent = dialog.children('.verification-dialog-content'); + dialogContent.children(".explainVerification").text(howToVerify); + dialogContent.children(".verificationCode").text(verificationCode); + dialog.css('display', 'block'); + }; + + $(".verify").click(function (event) { + + event.stopPropagation(); + + var verify = $(this); + var indicator = $(this).children('img'); + var accountId = indicator.attr('id'); + var status = indicator.data('status'); + + var onlyVerificationCode = false; + if (parseInt(status) === 1) { + onlyVerificationCode = true; + } + + if (indicator.hasClass('verify-action')) { + $.ajax( + OC.generateUrl('/settings/users/{account}/verify', {account: accountId}), + { + method: 'GET', + data: {onlyVerificationCode: onlyVerificationCode} + } + ).done(function (data) { + var dialog = verify.children('.verification-dialog'); + showVerifyDialog($(dialog), data.msg, data.code); + indicator.attr('data-origin-title', t('core', 'Verifying …')); + indicator.attr('src', OC.imagePath('core', 'actions/verifying.svg')); + indicator.data('status', '1'); + }); + } + + }); + + // When the user clicks anywhere outside of the verification dialog we close it + $(document).click(function(event){ + var element = event.target; + var isDialog = $(element).hasClass('verificationCode') + || $(element).hasClass('explainVerification') + || $(element).hasClass('verification-dialog-content') + || $(element).hasClass('verification-dialog'); + if (!isDialog) { + $(document).find('.verification-dialog').css('display', 'none'); + } + }); + + + var federationSettingsView = new OC.Settings.FederationSettingsView({ + el: '#personal-settings' + }); + federationSettingsView.render(); + + $("#languageinput").change(function () { + // Serialize the data + var post = $("#languageinput").serialize(); + // Ajax foo + $.ajax( + 'ajax/setlanguage.php', + { + method: 'POST', + data: post + } + ).done(function() { + location.reload(); + }).fail(function(jqXHR) { + $('#passworderror').text(jqXHR.responseJSON.message); + }); + return false; + }); + + var uploadparms = { + pasteZone: null, + done: function (e, data) { + var response = data; + if (typeof data.result === 'string') { + response = JSON.parse(data.result); + } else if (data.result && data.result.length) { + // fetch response from iframe + response = JSON.parse(data.result[0].body.innerText); + } else { + response = data.result; + } + avatarResponseHandler(response); + }, + submit: function(e, data) { + $('#displayavatar img').hide(); + $('#displayavatar .avatardiv').addClass('loading'); + data.formData = _.extend(data.formData || {}, { + requesttoken: OC.requestToken + }); + }, + fail: function (e, data){ + var msg = data.jqXHR.statusText + ' (' + data.jqXHR.status + ')'; + if (!_.isUndefined(data.jqXHR.responseJSON) && + !_.isUndefined(data.jqXHR.responseJSON.data) && + !_.isUndefined(data.jqXHR.responseJSON.data.message) + ) { + msg = data.jqXHR.responseJSON.data.message; + } + avatarResponseHandler({ + data: { + message: msg + } + }); + } + }; + + $('#uploadavatar').fileupload(uploadparms); + + $('#selectavatar').click(function () { + OC.dialogs.filepicker( + t('settings', "Select a profile picture"), + function (path) { + $('#displayavatar img').hide(); + $('#displayavatar .avatardiv').addClass('loading'); + $.ajax({ + type: "POST", + url: OC.generateUrl('/avatar/'), + data: { path: path } + }).done(avatarResponseHandler) + .fail(function(jqXHR) { + var msg = jqXHR.statusText + ' (' + jqXHR.status + ')'; + if (!_.isUndefined(jqXHR.responseJSON) && + !_.isUndefined(jqXHR.responseJSON.data) && + !_.isUndefined(jqXHR.responseJSON.data.message) + ) { + msg = jqXHR.responseJSON.data.message; + } + avatarResponseHandler({ + data: { + message: msg + } + }); + }); + }, + false, + ["image/png", "image/jpeg"] + ); + }); + + $('#removeavatar').click(function () { + $.ajax({ + type: 'DELETE', + url: OC.generateUrl('/avatar/'), + success: function () { + updateAvatar(true); + } + }); + }); + + $('#abortcropperbutton').click(function () { + $('#displayavatar .avatardiv').removeClass('loading'); + $('#displayavatar img').show(); + cleanCropper(); + }); + + $('#sendcropperbutton').click(function () { + sendCropData(); + }); + + $('#pass2').strengthify({ + zxcvbn: OC.linkTo('core','vendor/zxcvbn/dist/zxcvbn.js'), + titles: [ + t('core', 'Very weak password'), + t('core', 'Weak password'), + t('core', 'So-so password'), + t('core', 'Good password'), + t('core', 'Strong password') + ], + drawTitles: true, + }); + + // Load the big avatar + $('#avatarform .avatardiv').avatar(OC.currentUser, 145, true, null, function() { + if($('#displayavatar img').length === 0) { + $('#removeavatar').removeClass('inlineblock').addClass('hidden'); + } else { + $('#removeavatar').removeClass('hidden').addClass('inlineblock'); + } + }); +}); + +OC.Settings.updateAvatar = updateAvatar; diff --git a/settings/routes.php b/settings/routes.php index 52523ff50c6..12da950ed2f 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -65,7 +65,7 @@ $application->registerRoutes($this, [ ['name' => 'Certificate#removePersonalRootCertificate', 'url' => '/settings/personal/certificate/{certificateIdentifier}', 'verb' => 'DELETE'], ['name' => 'Certificate#addSystemRootCertificate', 'url' => '/settings/admin/certificate', 'verb' => 'POST'], ['name' => 'Certificate#removeSystemRootCertificate', 'url' => '/settings/admin/certificate/{certificateIdentifier}', 'verb' => 'DELETE'], - ['name' => 'PersonalSettings#index', 'url' => '/settings/personal/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'personal-info']], + ['name' => 'PersonalSettings#index', 'url' => '/settings/user/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'personal-info']], ['name' => 'AdminSettings#index', 'url' => '/settings/admin/{section}', 'verb' => 'GET', 'defaults' => ['section' => 'server']], ['name' => 'AdminSettings#form', 'url' => '/settings/admin/{section}', 'verb' => 'GET'], ['name' => 'ChangePassword#changePersonalPassword', 'url' => '/settings/personal/changepassword', 'verb' => 'POST'], diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php index 7a19752912c..eb1bb43d267 100644 --- a/settings/templates/settings/personal/personal.info.php +++ b/settings/templates/settings/personal/personal.info.php @@ -24,6 +24,22 @@ /** @var \OCP\IL10N $l */ /** @var array $_ */ +script('settings', [ + 'usersettings', + 'federationsettingsview', + 'federationscopemenu', + 'settings/personalInfo', +]); +style('settings', 'settings'); +vendor_script('strengthify/jquery.strengthify'); +vendor_style('strengthify/strengthify'); +script('files', 'jquery.fileupload'); +vendor_script('jcrop/js/jquery.Jcrop'); +vendor_style('jcrop/css/jquery.Jcrop'); + +//TODO: delete js/personal.js once the Encryption and AuthToken things are, +// where they belong + ?> <div id="personal-settings"> |