Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
knrt10 committed Mar 24, 2019
1 parent bc1722a commit da3e9a8
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 29 deletions.
78 changes: 59 additions & 19 deletions app/ui-flextab/client/tabs/userEdit.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,65 @@
<p class="secondary-font-color">{{_ "You_are_not_authorized_to_view_this_page"}}</p>
{{else}}
<form class="" action="index.html" method="post" autocomplete="off">
<div class="rc-input rc-form-group rc-form-group--small">
<label class="rc-input__label">
<div class="rc-input__title">{{_ "Name"}}</div>
<div class="rc-input__wrapper">
<input name="name" type="text" class="rc-input__element rc-input__element--small" id="name" autocomplete="off" value="{{user.name}}"/>
</div>
</label>
</div>
<div class="rc-input rc-form-group rc-form-group--small">
<label class="rc-input__label">
<div class="rc-input__title">{{_ "Username"}}</div>
<div class="rc-input__wrapper">
<div class="rc-input__icon">
{{> icon icon='at' }}
</div>
<input name="name" type="text" class="rc-input__element rc-input__element--small" id="username" autocomplete="off" value="{{user.username}}"/>
</div>
</label>
</div>
<div class="rc-form-group rc-form-group--small">
<label class="rc-form-label">{{_ "Profile_picture"}}</label>
<div class="rc-select-avatar">
<div class="rc-select-avatar__preview">
{{# unless avatarPreview}}
{{> avatar username=user.username}}
{{else}}
{{> avatar url=avatarPreview.blob}}
{{/unless}}
</div>

<div class="rc-select-avatar__list">
<div class="rc-select-avatar__list-item rc-tooltip js-select-avatar-initials" aria-label="{{_ "initials_avatar" }}">
{{> avatar username=initialsUsername }}
</div>
<div class="rc-select-avatar__list-item rc-tooltip js-select-avatar-upload" aria-label="{{_ "Upload_user_avatar" }}">
<label class="rc-select-avatar__upload-label avatar" for="upload-avatar">
{{> icon block="rc-select-avatar__upload-icon" icon="upload"}}
</label>
<input type="file" name="" value="" id="upload-avatar" style="display:none;" accept="image/x-png,image/gif,image/jpeg">
</div>
<div class="rc-select-avatar__list-item rc-tooltip js-select-avatar-url {{selectUrl}}" aria-label="{{_ "Use_url_for_avatar" }}">
<label class="rc-select-avatar__upload-label avatar">
{{> icon block="rc-select-avatar__upload-icon" icon="permalink"}}
</label>
</div>

<div class="rc-input">

<label class="rc-input__label">
<div class="rc-input__title">{{_ "Use_url_for_avatar"}}</div>
<div class="rc-input__wrapper">
<input name="avatar_url" class="rc-input__element js-avatar-url-input" placeholder="{{_ "Use_url_for_avatar"}}">
</div>
</label>
</div>
</div>
</div>

<div class="rc-input rc-form-group rc-form-group--small">
<label class="rc-input__label">
<div class="rc-input__title">{{_ "Name"}}</div>
<div class="rc-input__wrapper">
<input name="name" type="text" class="rc-input__element rc-input__element--small" id="name" autocomplete="off" value="{{user.name}}"/>
</div>
</label>
</div>
<div class="rc-input rc-form-group rc-form-group--small">
<label class="rc-input__label">
<div class="rc-input__title">{{_ "Username"}}</div>
<div class="rc-input__wrapper">
<div class="rc-input__icon">
{{> icon icon='at' }}
</div>
<input name="name" type="text" class="rc-input__element rc-input__element--small" id="username" autocomplete="off" value="{{user.username}}"/>
</div>
</label>
</div>
</div>
<div class="rc-form-group rc-form-group--small">
<div class="rc-input">
<label class="rc-input__label">
Expand Down
90 changes: 88 additions & 2 deletions app/ui-flextab/client/tabs/userEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ import { Template } from 'meteor/templating';
import { TAPi18n } from 'meteor/tap:i18n';
import { t, handleError } from '../../../utils';
import { Roles } from '../../../models';
import { Notifications } from '../../../notifications';
import { hasAtLeastOnePermission } from '../../../authorization';
import toastr from 'toastr';
import { callbacks } from '../../../callbacks';
import s from 'underscore.string';

const setAvatar = function(event, template) {
const { blob, contentType, service } = this.suggestion;

template.avatar.set({
service,
contentType,
blob,
});
};

Template.userEdit.helpers({

disabled(cursor) {
Expand All @@ -18,10 +30,23 @@ Template.userEdit.helpers({
return (Template.instance().user && hasAtLeastOnePermission('edit-other-user-info')) || (!Template.instance().user && hasAtLeastOnePermission('create-user'));
},

selectUrl() {
return Template.instance().url.get().trim() ? '' : 'disabled';
},

user() {
return Template.instance().user;
},

initialsUsername() {
const { user } = Template.instance();
return `@${ user && user.username }`;
},

avatarPreview() {
return Template.instance().avatar.get();
},

requirePasswordChange() {
return !Template.instance().user || Template.instance().user.requirePasswordChange;
},
Expand All @@ -41,6 +66,52 @@ Template.userEdit.helpers({
});

Template.userEdit.events({
'click .js-select-avatar-initials'() {
Meteor.call('resetAvatar', Template.instance().user, function() {
toastr.success(t('Avatar_changed_successfully'));
callbacks.run('userAvatarSet', 'initials');
});
},
'click .js-select-avatar-url'(e, instance, ...args) {
const url = instance.url.get().trim();
if (!url) {
return;
}
setAvatar.apply({
suggestion: {
service: 'url',
blob: url,
contentType: '',
},
}, [e, instance, ...args]);
},
'input .js-avatar-url-input'(e, instance) {
const text = e.target.value;
instance.url.set(text);
},
'change .js-select-avatar-upload [type=file]'(event, template) {
const e = event.originalEvent || event;
let { files } = e.target;
if (!files || files.length === 0) {
files = (e.dataTransfer && e.dataTransfer.files) || [];
}
Object.keys(files).forEach((key) => {
const blob = files[key];
if (!/image\/.+/.test(blob.type)) {
return;
}
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
template.avatar.set({
service: 'upload',
contentType: blob.type,
blob: reader.result,
});
callbacks.run('userAvatarSet', 'upload');
};
});
},
'click .cancel'(e, t) {
e.stopPropagation();
e.preventDefault();
Expand Down Expand Up @@ -98,7 +169,9 @@ Template.userEdit.events({
Template.userEdit.onCreated(function() {
this.user = this.data != null ? this.data.user : undefined;
this.roles = this.user ? new ReactiveVar(this.user.roles) : new ReactiveVar([]);

this.avatar = new ReactiveVar;
this.url = new ReactiveVar('');
Notifications.onLogged('updateAvatar', () => this.avatar.set());

const { tabBar } = Template.currentData();

Expand Down Expand Up @@ -162,7 +235,7 @@ Template.userEdit.onCreated(function() {
return;
}
const userData = this.getUserData();

const avatar = this.avatar.get();
if (this.user != null) {
for (const key in userData) {
if (key) {
Expand All @@ -176,6 +249,19 @@ Template.userEdit.onCreated(function() {
}
}

if (avatar) {
const params = [avatar.blob];

params.push(avatar.contentType);

params.push(avatar.service);
params.push(Template.instance().user);
Meteor.call('setAvatarFromService', ...params, function() {
toastr.success(t('Avatar_changed_successfully'));
callbacks.run('userAvatarSet', avatar.service);
});
}

Meteor.call('insertOrUpdateUser', userData, (error) => {
if (error) {
return handleError(error);
Expand Down
22 changes: 15 additions & 7 deletions server/methods/resetAvatar.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { settings } from '../../app/settings';
import { Notifications } from '../../app/notifications';

Meteor.methods({
resetAvatar() {
resetAvatar(args) {
if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'resetAvatar',
Expand All @@ -19,12 +19,20 @@ Meteor.methods({
});
}

const user = Meteor.user();
FileUpload.getStore('Avatars').deleteByName(user.username);
Users.unsetAvatarOrigin(user._id);
Notifications.notifyLogged('updateAvatar', {
username: user.username,
});
if (args) {
FileUpload.getStore('Avatars').deleteByName(args.username);
Users.unsetAvatarOrigin(args._id);
Notifications.notifyLogged('updateAvatar', {
username: args.username,
});
} else {
const user = Meteor.user();
FileUpload.getStore('Avatars').deleteByName(user.username);
Users.unsetAvatarOrigin(user._id);
Notifications.notifyLogged('updateAvatar', {
username: user.username,
});
}
},
});

Expand Down
7 changes: 6 additions & 1 deletion server/methods/setAvatarFromService.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { settings } from '../../app/settings';
import { setUserAvatar } from '../../app/lib';

Meteor.methods({
setAvatarFromService(dataURI, contentType, service) {
setAvatarFromService(dataURI, contentType, service, userData) {
check(dataURI, String);
check(contentType, Match.Optional(String));
check(service, Match.Optional(String));
check(userData, Match.Optional(Object));

if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
Expand All @@ -22,6 +23,10 @@ Meteor.methods({
});
}

if (userData) {
return setUserAvatar(userData, dataURI, contentType, service);
}

const user = Meteor.user();

return setUserAvatar(user, dataURI, contentType, service);
Expand Down

0 comments on commit da3e9a8

Please sign in to comment.