diff --git a/app/assets/images/avatar-bg.png b/app/assets/images/avatar-bg.png new file mode 100644 index 000000000..1a42bffd7 Binary files /dev/null and b/app/assets/images/avatar-bg.png differ diff --git a/app/assets/javascripts/app/controllers/layout_ref.js.coffee b/app/assets/javascripts/app/controllers/layout_ref.js.coffee index 72f663cc0..bf0eca142 100644 --- a/app/assets/javascripts/app/controllers/layout_ref.js.coffee +++ b/app/assets/javascripts/app/controllers/layout_ref.js.coffee @@ -14,6 +14,24 @@ class Content extends App.ControllerContent super @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: -> @html App.view('layout_ref/content')() diff --git a/app/assets/javascripts/app/lib/base/seedrandom.min.js b/app/assets/javascripts/app/lib/base/seedrandom.min.js new file mode 100644 index 000000000..c1f5c2341 --- /dev/null +++ b/app/assets/javascripts/app/lib/base/seedrandom.min.js @@ -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;ea;)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"); \ No newline at end of file diff --git a/app/assets/javascripts/app/views/layout_ref/content.jst.eco b/app/assets/javascripts/app/views/layout_ref/content.jst.eco index cb60df4dc..757be48d7 100644 --- a/app/assets/javascripts/app/views/layout_ref/content.jst.eco +++ b/app/assets/javascripts/app/views/layout_ref/content.jst.eco @@ -14,6 +14,34 @@
+

Avatars

+ +

+ Users and customers might not have a profile images because: +

+
    +
  1. They didn't upload one +
  2. They didn't login using a authentication provider like facebook, twitter or google where we get an avatar +
  3. They have no avatar associated with their email address (gravatar) +
+

+ They will get a random avatar consisting of a blured version of the Zammad logo and their initials. +

+

+ The background is generated by using a random numbers generator (RNG) with the user-id as the seed. The RNG is then used to create the x and y 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. +

+ + + + + + + + + + +
+

Headlines

h1. Bootstrap heading

h2. Bootstrap heading

diff --git a/app/assets/stylesheets/zzz.css.erb b/app/assets/stylesheets/zzz.css.erb index cab56d4ce..9880e9642 100644 --- a/app/assets/stylesheets/zzz.css.erb +++ b/app/assets/stylesheets/zzz.css.erb @@ -7,8 +7,6 @@ body { ol, ul { - list-style: none; - padding: 0; } a.create { @@ -595,6 +593,7 @@ ol.tabs li { } .tabs { + padding: 0; margin-bottom: 20px; color: #b8b8b8; border: 1px solid rgba(0,8,14,.08); @@ -1864,6 +1863,23 @@ footer { 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 { width: 32%; max-width: 300px; @@ -3174,77 +3190,83 @@ footer { box-shadow: none; } -.recipientList-entry .recipientList-iconSpacer { - width: 20px; - margin-left: -5px; -} - -.recipientList-entry .icon:not(.plus) { - opacity: 0.2; -} - -.recipientList-entry:hover .icon { - opacity: 1; -} - -.recipientList-name { - margin-left: 10px; - margin-top: 2px; -} - -.recipientList-detail { - opacity: 0.5; -} - -.recipientList-icon.plus { - margin-left: 13px; -} - -.recipientList-new { - background: hsl(145,51%,45%); -} - -.dropdown .recipientList-new:hover { - background: hsl(147,52%,43%); -} - -li.recipientList-controls, -li.recipientList-controls:hover { - padding: 0; - background: hsl(206,7%,28%); -} - -.recipientList-backClickArea { - height: 100%; - float: left; - padding: 0 10px; -} - -.recipientList-backButton { - padding: 5px 10px; - font-size: 12px; - color: white; - border-radius: 3px; - border: 1px solid hsl(234,10%,10%); - box-shadow: 0 1px rgba(255,255,255,.03) inset; -} - -.recipientList-backClickArea:active .recipientList-backButton { - background: hsl(206,7%,25%); - box-shadow: 0 1px rgba(0,0,0,.1) inset; -} - -.recipientList-backButton .icon { - margin-bottom: -2px; -} - +.recipientList, .recipientList-organisationMembers { - position: absolute; - top: 0; - left: 0; - right: 0; + list-style: none; + padding: 0; } + .recipientList-entry .recipientList-iconSpacer { + width: 20px; + margin-left: -5px; + } + + .recipientList-entry .icon:not(.plus) { + opacity: 0.2; + } + + .recipientList-entry:hover .icon { + opacity: 1; + } + + .recipientList-name { + margin-left: 10px; + margin-top: 2px; + } + + .recipientList-detail { + opacity: 0.5; + } + + .recipientList-icon.plus { + margin-left: 13px; + } + + .recipientList-new { + background: hsl(145,51%,45%); + } + + .dropdown .recipientList-new:hover { + background: hsl(147,52%,43%); + } + + li.recipientList-controls, + li.recipientList-controls:hover { + padding: 0; + background: hsl(206,7%,28%); + } + + .recipientList-backClickArea { + height: 100%; + float: left; + padding: 0 10px; + } + + .recipientList-backButton { + padding: 5px 10px; + font-size: 12px; + color: white; + border-radius: 3px; + border: 1px solid hsl(234,10%,10%); + box-shadow: 0 1px rgba(255,255,255,.03) inset; + } + + .recipientList-backClickArea:active .recipientList-backButton { + background: hsl(206,7%,25%); + box-shadow: 0 1px rgba(0,0,0,.1) inset; + } + + .recipientList-backButton .icon { + margin-bottom: -2px; + } + + .recipientList-organisationMembers { + position: absolute; + top: 0; + left: 0; + right: 0; + } + /* ----------------