Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .meteor/packages
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ percolate:migrations
underscorestring:underscore.string
meteorhacks:kadira
yasaricli:slugify
jparker:gravatar
http
cfs:filesystem
cfs:standard-packages
17 changes: 17 additions & 0 deletions .meteor/versions
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,23 @@ blaze@2.1.2
blaze-tools@1.0.3
boilerplate-generator@1.0.3
callback-hook@1.0.3
cfs:access-point@0.1.49
cfs:base-package@0.0.30
cfs:collection@0.5.5
cfs:collection-filters@0.2.4
cfs:data-man@0.0.6
cfs:file@0.1.17
cfs:filesystem@0.1.2
cfs:http-methods@0.0.29
cfs:http-publish@0.0.13
cfs:power-queue@0.9.11
cfs:reactive-list@0.0.9
cfs:reactive-property@0.0.4
cfs:standard-packages@0.5.9
cfs:storage-adapter@0.2.2
cfs:tempstore@0.1.5
cfs:upload-http@0.0.20
cfs:worker@0.1.4
check@1.0.5
chrismbeckett:toastr@2.1.0
coffeescript@1.0.6
Expand Down Expand Up @@ -83,6 +99,7 @@ ordered-dict@1.0.3
percolate:migrations@0.7.5
percolatestudio:synced-cron@1.1.0
qnub:emojione@0.0.3
raix:eventemitter@0.1.2
raix:handlebar-helpers@0.2.4
random@1.0.3
reactive-dict@1.1.0
Expand Down
4 changes: 4 additions & 0 deletions client/routes/router.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ Router.onBeforeAction ->
this.layout('usernameLayout')
return this.render('usernamePrompt')

if Meteor.userId()? and not Meteor.user().avatarOrigin?
this.layout('usernameLayout')
return this.render('avatarPrompt')

this.next()
, {
except: ['login']
Expand Down
41 changes: 41 additions & 0 deletions client/stylesheets/base.less
Original file line number Diff line number Diff line change
Expand Up @@ -2675,6 +2675,47 @@ a.github-fork {
}
}

.avatar-suggestion-item {
height: 80px;
margin: 10px 0px;
text-align: left;

> div {
height: 80px;
width: 80px;
background-size: cover;
display: inline-block;
border: 1px solid #DDD;
font-size: 80px;
text-align: center;
line-height: 80px;
background-color: #EEE;
color: #CCC;
&.question-mark:before {
content: "?";
position: absolute;
left: 0;
width: 80px;
}
}
button {
display: inline-block;
top: -35px;
}
input[type=file] {
position: absolute !important;
width: 100%;
top: 0;
left: 0;
height: 100%;
opacity: 0;
z-index: 10000;
* {
cursor: pointer;
}
}
}

@media all and(max-width: 1100px) {
#rocket-chat {
.flex-opened {
Expand Down
53 changes: 53 additions & 0 deletions client/views/avatar/avatar.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Template.avatarPrompt.onCreated ->
self = this
self.suggestions = new ReactiveVar
self.upload = new ReactiveVar

self.getSuggestions = ->
self.suggestions.set undefined
Meteor.call 'getAvatarSuggestion', (error, avatars) ->
self.suggestions.set
ready: true
avatars: avatars

self.getSuggestions()


Template.avatarPrompt.helpers
suggestions: ->
return Template.instance().suggestions.get()

upload: ->
return Template.instance().upload.get()


Template.avatarPrompt.events
'click .select-service': (e) ->
Meteor.call 'setAvatarFromService', this.blob, this.service, ->
console.log arguments

'click .login-with-service': (event, template) ->
loginWithService = "loginWith#{_.capitalize(this)}"

serviceConfig = {}

Meteor[loginWithService] serviceConfig, (error) ->
if error?.error is 'github-no-public-email'
alert t("loginServices.github_no_public_email")
return

console.log error
if error?
toastr.error error.message
return

template.getSuggestions()

'change .myFileInput': (event, template) ->
FS.Utility.eachFile event, (blob) ->
reader = new FileReader()
reader.readAsDataURL(blob)
reader.onloadend = ->
template.upload.set
service: 'upload'
blob: reader.result
74 changes: 74 additions & 0 deletions client/views/avatar/avatar.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<template name="avatarSuggestion">
{{#if .}}
<div class="avatar-suggestion-item">
<div style="background-image: url({{blob}});">
</div>
<button type="button" class="button primary select-service">{{_ "avatar.Use_service_avatar" service}}</button>
</div>
{{/if}}
</template>

<template name="avatarSuggestionLogin">
{{#if .}}
<div class="avatar-suggestion-item">
<div class="question-mark"></div>
<button type="button" class="button primary login-with-service">{{_ "avatar.Login_with" .}}</button>
</div>
{{/if}}
</template>

<template name="avatarPrompt">
<form id="login-card" method='/'>
<div class="fields">
<h2>{{_ "avatar.Select_an_avatar"}}</h2>
</div>
<div class="fields">
<div class='input-text active'>
<div class='field'>
<div class="avatar-suggestions">
{{#if suggestions.ready}}
{{> avatarSuggestion suggestions.avatars.gravatar}}
{{> avatarSuggestion suggestions.avatars.facebook}}
{{> avatarSuggestion suggestions.avatars.google}}
{{> avatarSuggestion suggestions.avatars.github}}

{{#unless suggestions.avatars.gravatar}}
{{> avatarSuggestionLogin 'gravatar'}}
{{/unless}}
{{#unless suggestions.avatars.facebook}}
{{> avatarSuggestionLogin 'facebook'}}
{{/unless}}
{{#unless suggestions.avatars.google}}
{{> avatarSuggestionLogin 'google'}}
{{/unless}}
{{#unless suggestions.avatars.github}}
{{> avatarSuggestionLogin 'github'}}
{{/unless}}

<div class="avatar-suggestion-item">
<div style="background-image: url({{upload.blob}});" class="{{#unless upload}}question-mark{{/unless}}">
</div>
{{#with upload}}
<button type="button" class="button primary select-service">{{_ "avatar.Use_uploaded_avatar"}}</button>
{{/with}}
{{#unless upload}}
<button type="button" class="button primary">{{_ "avatar.Select_file"}}
<input type="file" class="myFileInput">
</button>
{{/unless}}
</div>
{{else}}
{{_ "usernameRegistration.Loading_suggestion"}}
{{/if}}
</div>
</div>
</div>
</div>

{{#if username.ready}}
<div class="submit">
<button data-loading-text="{{_ "general.Please_wait"}}..." class='button primary login'><span>{{_ "usernameRegistration.Use_this_username"}}</span></button>
</div>
{{/if}}
</form>
</template>
7 changes: 7 additions & 0 deletions i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,12 @@
},
"error": {
"Not_found_or_not_allowed": "Not Found or Not Allowed"
},
"avatar": {
"Use_service_avatar": "Use %s avatar",
"Login_with": "Login with %s",
"Select_an_avatar": "Select an avatar",
"Use_uploaded_avatar": "Use uploaded avatar",
"Select_file": "Select file"
}
}
7 changes: 7 additions & 0 deletions i18n/pt.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,12 @@
},
"error": {
"Not_found_or_not_allowed": "Não encontrado ou não permitido"
},
"avatar": {
"Use_service_avatar": "Use o avatar de %s",
"Login_with": "Login com %s",
"Select_an_avatar": "Selecione um avatar",
"Use_uploaded_avatar": "Use o avatar de upload",
"Select_file": "Selecione um arquivo"
}
}
40 changes: 40 additions & 0 deletions lib/file.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
uploadPath = "~/uploads"

store = new FS.Store.FileSystem "avatars",
path: uploadPath
fileKeyMaker: (fileObj) ->
filename = fileObj.name()
filenameInStore = fileObj.name({store: 'avatars'})

return filenameInStore || filename

@Avatars = new FS.Collection "avatars",
stores: [store]

@Avatars.allow
insert: ->
return true
update: ->
return true
download: ->
return true

Meteor.startup ->
if Meteor.isServer
FS.HTTP.mount ['/avatar/:filename'], ->
self = this
opts = FS.Utility.extend({}, self.query || {}, self.params || {})

collectionName = opts.collectionName

collection = FS._collections['avatars']

file = if collection? then collection.findOne({ "copies.avatars.key": opts.filename }) else null

return {
collection: collection
file: file
storeName: 'avatars'
download: opts.download
filename: opts.filename
}
43 changes: 43 additions & 0 deletions server/methods/getAvatarSuggestion.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Meteor.methods
getAvatarSuggestion: ->
if not Meteor.userId()
throw new Meteor.Error 203, '[methods] typingStatus -> Usuário não logado'

user = Meteor.user()

avatars = []

if user.services.facebook?.id?
avatars.push
service: 'facebook'
url: "https://graph.facebook.com/#{user.services.facebook.id}/picture?type=large"

if user.services.google?.picture?
avatars.push
service: 'google'
url: user.services.google.picture

if user.services.github?.username?
avatars.push
service: 'github'
url: "https://avatars.githubusercontent.com/#{user.services.github.username}?s=200"

if user.emails?.length > 0
for email in user.emails when email.verified is true
avatars.push
service: 'gravatar'
url: Gravatar.imageUrl email.address

validAvatars = {}
for avatar in avatars
try
result = HTTP.get avatar.url, npmRequestOptions: {encoding: null}
if result.statusCode is 200
blob = "data:#{result.headers['content-type']};base64,"
blob += Buffer(result.content, 'binary').toString('base64')
avatar.blob = blob
validAvatars[avatar.service] = avatar
catch e
# ...

return validAvatars
14 changes: 14 additions & 0 deletions server/methods/setAvatarFromService.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Meteor.methods
setAvatarFromService: (image, service) ->
if not Meteor.userId()
throw new Meteor.Error 203, '[methods] typingStatus -> Usuário não logado'

user = Meteor.user()

file = new FS.File image
file.attachData image, ->
file.name user.username

Avatars.insert file, (err, fileObj) ->
Meteor.users.update {_id: user._id}, {$set: {avatarOrigin: service}}

1 change: 1 addition & 0 deletions server/publications.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Meteor.publish 'userData', ->
status: 1
statusDefault: 1
statusConnection: 1
avatarOrigin: 1
emails: 1
'services.facebook.id': 1
'services.google.picture': 1
Expand Down