aboutsummaryrefslogtreecommitdiffstats
path: root/settings
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@arthur-schiwon.de>2017-05-16 02:46:42 +0200
committerArthur Schiwon <blizzz@arthur-schiwon.de>2017-06-23 12:36:37 +0200
commit045f652ef2844e3917b4ae7f3bbb5abb3422d02b (patch)
treebc4dc49e5d83d7f2bd7220f55db6fa7b498df686 /settings
parent039ee7e3aa33284999526a15231ddd0b676c81bd (diff)
downloadnextcloud-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.js392
-rw-r--r--settings/routes.php2
-rw-r--r--settings/templates/settings/personal/personal.info.php16
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">