add unique avatar support

This commit is contained in:
Felix Niklas 2014-09-18 12:40:17 +02:00
parent 367e6ab8be
commit db4df87be1
5 changed files with 139 additions and 70 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -14,6 +14,24 @@ class Content extends App.ControllerContent
super super
@render() @render()
for avatar in @$('.user.avatar')
avatar = $(avatar)
size = if avatar.hasClass('big') then 50 else 40
@createUniqueAvatar avatar, size, avatar.data('firstname'), avatar.data('lastname'), avatar.data('userid')
createUniqueAvatar: (holder, size, firstname, lastname, id) ->
width = 300
height = 226
holder.addClass 'unique'
rng = new Math.seedrandom(id);
x = rng() * (width - size)
y = rng() * (height - size)
holder.css('background-position', "-#{ x }px -#{ y }px")
holder.text(firstname[0] + lastname[0])
render: -> render: ->
@html App.view('layout_ref/content')() @html App.view('layout_ref/content')()

View file

@ -0,0 +1 @@
!function(a,b,c,d,e,f,g,h,i){function j(a){var b,c=a.length,e=this,f=0,g=e.i=e.j=0,h=e.S=[];for(c||(a=[c++]);d>f;)h[f]=f++;for(f=0;d>f;f++)h[f]=h[g=r&g+a[f%c]+(b=h[f])],h[g]=b;(e.g=function(a){for(var b,c=0,f=e.i,g=e.j,h=e.S;a--;)b=h[f=r&f+1],c=c*d+h[r&(h[f]=h[g=r&g+b])+(h[g]=b)];return e.i=f,e.j=g,c})(d)}function k(a,b){var c,d=[],e=typeof a;if(b&&"object"==e)for(c in a)try{d.push(k(a[c],b-1))}catch(f){}return d.length?d:"string"==e?a:a+"\0"}function l(a,b){for(var c,d=a+"",e=0;e<d.length;)b[r&e]=r&(c^=19*b[r&e])+d.charCodeAt(e++);return n(b)}function m(c){try{return a.crypto.getRandomValues(c=new Uint8Array(d)),n(c)}catch(e){return[+new Date,a,(c=a.navigator)&&c.plugins,a.screen,n(b)]}}function n(a){return String.fromCharCode.apply(0,a)}var o=c.pow(d,e),p=c.pow(2,f),q=2*p,r=d-1,s=c["seed"+i]=function(a,f,g){var h=[];f=1==f?{entropy:!0}:f||{};var r=l(k(f.entropy?[a,n(b)]:null==a?m():a,3),h),s=new j(h);return l(n(s.S),b),(f.pass||g||function(a,b,d){return d?(c[i]=a,b):a})(function(){for(var a=s.g(e),b=o,c=0;p>a;)a=(a+c)*d,b*=d,c=s.g(1);for(;a>=q;)a/=2,b/=2,c>>>=1;return(a+c)/b},r,"global"in f?f.global:this==c)};l(c[i](),b),g&&g.exports?g.exports=s:h&&h.amd&&h(function(){return s})}(this,[],Math,256,6,52,"object"==typeof module&&module,"function"==typeof define&&define,"random");

View file

@ -14,6 +14,34 @@
<hr> <hr>
<h2>Avatars</h2>
<p>
Users and customers might not have a profile images because:
</p>
<ol>
<li>They didn't upload one
<li>They didn't login using a authentication provider like facebook, twitter or google where we get an avatar
<li>They have no avatar associated with their email address (gravatar)
</ol>
<p>
They will get a random avatar consisting of a blured version of the Zammad logo and their initials.
</p>
<p>
The background is generated by using a <i>random numbers generator</i> (RNG) with the user-id as the <b>seed</b>. The RNG is then used to create the <code>x</code> and <code>y</code> position of the background. Since the user-id is unique and does not change it's guaranteed that the avatar background stays the same and this makes it possible to calculate the avatar on the client without having to store the coordinates on the server side.
</p>
<span class="user avatar" data-firstname="Hans" data-lastname="Huber" data-userid="5"></span>
<span class="user avatar" data-firstname="Rafael" data-lastname="Schweizer" data-userid="6"></span>
<span class="user avatar" data-firstname="Stefanie" data-lastname="Lingerl" data-userid="7"></span>
<span class="user avatar" data-firstname="Igor" data-lastname="Kaufer" data-userid="8"></span>
<span class="user avatar" data-firstname="Ina" data-lastname="Lingerl" data-userid="12"></span>
<span class="big user avatar" data-firstname="Andreas" data-lastname="Berger" data-userid="9"></span>
<span class="big user avatar" data-firstname="Luisa" data-lastname="Hofner" data-userid="10"></span>
<span class="big user avatar" data-firstname="Clara" data-lastname="Altman" data-userid="11"></span>
<hr>
<h2>Headlines</h2> <h2>Headlines</h2>
<h1>h1. Bootstrap heading</h1> <h1>h1. Bootstrap heading</h1>
<h2>h2. Bootstrap heading</h2> <h2>h2. Bootstrap heading</h2>

View file

@ -7,8 +7,6 @@ body {
ol, ol,
ul { ul {
list-style: none;
padding: 0;
} }
a.create { a.create {
@ -595,6 +593,7 @@ ol.tabs li {
} }
.tabs { .tabs {
padding: 0;
margin-bottom: 20px; margin-bottom: 20px;
color: #b8b8b8; color: #b8b8b8;
border: 1px solid rgba(0,8,14,.08); border: 1px solid rgba(0,8,14,.08);
@ -1864,6 +1863,23 @@ footer {
height: 50px; height: 50px;
} }
.unique.avatar {
background-image: url(<%= asset_path "avatar-bg.png" %>);
background-size: auto;
color: white;
line-height: 42px;
text-align: center;
font-size: 13px;
letter-spacing: 1px;
text-transform: uppercase;
text-shadow: 0 1px rgba(0,0,0,.2);
}
.unique.big.avatar {
font-size: 16px;
line-height: 52px;
}
.sidebar { .sidebar {
width: 32%; width: 32%;
max-width: 300px; max-width: 300px;
@ -3174,76 +3190,82 @@ footer {
box-shadow: none; box-shadow: none;
} }
.recipientList-entry .recipientList-iconSpacer { .recipientList,
.recipientList-organisationMembers {
list-style: none;
padding: 0;
}
.recipientList-entry .recipientList-iconSpacer {
width: 20px; width: 20px;
margin-left: -5px; margin-left: -5px;
} }
.recipientList-entry .icon:not(.plus) { .recipientList-entry .icon:not(.plus) {
opacity: 0.2; opacity: 0.2;
} }
.recipientList-entry:hover .icon { .recipientList-entry:hover .icon {
opacity: 1; opacity: 1;
} }
.recipientList-name { .recipientList-name {
margin-left: 10px; margin-left: 10px;
margin-top: 2px; margin-top: 2px;
} }
.recipientList-detail { .recipientList-detail {
opacity: 0.5; opacity: 0.5;
} }
.recipientList-icon.plus { .recipientList-icon.plus {
margin-left: 13px; margin-left: 13px;
} }
.recipientList-new { .recipientList-new {
background: hsl(145,51%,45%); background: hsl(145,51%,45%);
} }
.dropdown .recipientList-new:hover { .dropdown .recipientList-new:hover {
background: hsl(147,52%,43%); background: hsl(147,52%,43%);
} }
li.recipientList-controls, li.recipientList-controls,
li.recipientList-controls:hover { li.recipientList-controls:hover {
padding: 0; padding: 0;
background: hsl(206,7%,28%); background: hsl(206,7%,28%);
} }
.recipientList-backClickArea { .recipientList-backClickArea {
height: 100%; height: 100%;
float: left; float: left;
padding: 0 10px; padding: 0 10px;
} }
.recipientList-backButton { .recipientList-backButton {
padding: 5px 10px; padding: 5px 10px;
font-size: 12px; font-size: 12px;
color: white; color: white;
border-radius: 3px; border-radius: 3px;
border: 1px solid hsl(234,10%,10%); border: 1px solid hsl(234,10%,10%);
box-shadow: 0 1px rgba(255,255,255,.03) inset; box-shadow: 0 1px rgba(255,255,255,.03) inset;
} }
.recipientList-backClickArea:active .recipientList-backButton { .recipientList-backClickArea:active .recipientList-backButton {
background: hsl(206,7%,25%); background: hsl(206,7%,25%);
box-shadow: 0 1px rgba(0,0,0,.1) inset; box-shadow: 0 1px rgba(0,0,0,.1) inset;
} }
.recipientList-backButton .icon { .recipientList-backButton .icon {
margin-bottom: -2px; margin-bottom: -2px;
} }
.recipientList-organisationMembers { .recipientList-organisationMembers {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
} }
/* /*