#156 Rework the hubs' avatar and include possible notifications there
Merged 7 years ago by pingou. Opened 7 years ago by pingou.
pingou/fedora-hubs avatar_favicon  into  develop

file modified
+1 -1
@@ -23,7 +23,7 @@ 

  def days_since(then):

      return (datetime.datetime.utcnow() - then).days

  app.template_filter('days_since')(days_since)

- app.template_filter('avatar')(hubs.widgets.base.avatar)

+ app.template_filter('avatar')(username2avatar)

  

  logging.basicConfig()

  

empty or binary file added
@@ -0,0 +1,185 @@ 

+ /*

+ Notificon :: Client-side Favicon Notifications - Usage: Notificon(label='',favicon_url={default_favicon})

+ =========================================================================================================

+ 

+ Copyright (c) 2011 Matt Williams <matt@makeable.co.uk>. All rights reserved.

+ 

+ Redistribution and use in source and binary forms, with or without modification, are

+ permitted provided that the following conditions are met:

+ 

+    1. Redistributions of source code must retain the above copyright notice, this list of

+       conditions and the following disclaimer.

+ 

+    2. Redistributions in binary form must reproduce the above copyright notice, this list

+       of conditions and the following disclaimer in the documentation and/or other materials

+       provided with the distribution.

+ 

+ THIS SOFTWARE IS PROVIDED BY MATT WILLIAMS ''AS IS'' AND ANY EXPRESS OR IMPLIED

+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND

+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATT WILLIAMS OR

+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON

+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING

+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF

+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 

+ The views and conclusions contained in the software and documentation are those of the

+ authors and should not be interpreted as representing official policies,

+ either expressed or implied, of Matt Williams.

+ 

+ Modified by Pierre-Yves Chibon <pingou@pingoured.fr> using code from the

+ favicon-notification project (https://github.com/igorprado/favicon-notification)

+ licensed under the MIT license.

+ 

+ */

+ 

+ (function(){

+ 

+   var unsupported = false;

+   var _options = {};

+ 

+   var checkSupport = function checkSupport() {

+     if (unsupported) {

+         return false;

+     }

+     if (!document.createElement('canvas').getContext) {

+         unsupported = true;

+         if (console) {

+             console.log('Notificon: requires canvas support');

+         }

+         return false;

+     }

+     return true;

+   }

+ 

+ 

+   var _defaults = {

+     color: '#eb361e',

+     lineColor: '#ffffff'

+   };

+ 

+   var _setOptions = function(options) {

+     if (!options) {

+       _options = _defaults;

+       return;

+     }

+ 

+     _options = {};

+ 

+     for(var key in _defaults){

+          _options[key] = options.hasOwnProperty(key) ? options[key] : _defaults[key];

+     }

+   };

+ 

+   var findFaviconTag = function findFaviconTag(notificon) {

+     var link_tags = document.getElementsByTagName('link');

+     for (var i=0; i < link_tags.length; i++) {

+       if (notificon && (/\bnotificon\b/i).test(link_tags[i].getAttribute('rel'))) {

+         return link_tags[i];

+       } else if (!notificon && (/\bicon\b/i).test(link_tags[i].getAttribute('rel'))) {

+         return link_tags[i];

+       }

+     }

+     return false;

+   };

+ 

+   var getExistingFavicon = function getExistingFavicon() {

+     var favicon = findFaviconTag();

+     return favicon ? favicon.getAttribute('href') : '/favicon.ico';

+   };

+ 

+   var removeNotificon = function removeNotificon() {

+     var notificon = findFaviconTag(true);

+     if (notificon) {

+       notificon.parentNode.removeChild(notificon);

+       removeNotificon();

+     }

+   };

+ 

+   var changeFavicon = function changeFavicon(canvas) {

+     var link = document.createElement('link');

+     link.type = 'image/x-icon';

+     link.rel = 'icon notificon';

+     link.href = canvas.toDataURL("image/png");

+     removeNotificon();

+     document.getElementsByTagName('head')[0].appendChild(link);

+   };

+ 

+   var drawLabel = function drawLabel(canvas, color, favicon) {

+     var img = document.createElement('img');

+     img.src = favicon;

+ 

+     img.onload = function() {

+       var lineWidth = 2;

+ 

+       canvas.width = img.width;

+       canvas.height = img.height;

+ 

+       var context = canvas.getContext('2d');

+       context.clearRect(0, 0, img.width, img.height);

+       context.drawImage(img, 0, 0);

+ 

+       var centerX = img.width - (img.width / 4.5) - lineWidth;

+       var centerY = img.height - (img.height / 4.5) - lineWidth;

+       var radius = img.width / 4.5;

+ 

+       context.fillStyle = color;

+       context.strokeStyle = _options.lineColor;

+       context.lineWidth = lineWidth;

+ 

+       context.beginPath();

+       context.arc(centerX, centerY, radius, 0, Math.PI * 2, false);

+       context.closePath();

+       context.fill();

+       context.stroke();

+ 

+       changeFavicon(canvas)

+     }

+   };

+ 

+   var imgToCanvas = function imgToCanvas(img) {

+     var canvas = document.createElement("canvas");

+     canvas.width = img.width;

+     canvas.height = img.height;

+     var context = canvas.getContext("2d");

+     context.drawImage(img, 0, 0);

+     return canvas;

+   };

+ 

+   var createNotificon = function createNotificon(color, favicon) {

+     if (!checkSupport()) {

+         return false;

+     }

+     if (!favicon) {

+       favicon = getExistingFavicon();

+     }

+     var img = document.createElement("img");

+     img.src = favicon;

+     img.onload = function() {

+       var canvas = imgToCanvas(img);

+       if (color) {

+         drawLabel(canvas, color, favicon);

+       }

+       try {

+         changeFavicon(canvas);

+       } catch(e) {

+         if (console) {

+           console.log(e)

+           console.log('Notificon: cannot use icons located on a different domain (' + favicon + ')');

+         }

+       }

+ 

+     };

+     img.onerror = function() {

+       if (console) {

+         console.log('Notificon: image not found (' + favicon + ')');

+       }

+     };

+   };

+ 

+   this.Notificon = function(color, favicon, options) {

+     _setOptions(options);

+     createNotificon(color, favicon);

+   };

+ })();

file modified
+10
@@ -307,5 +307,15 @@ 

  

  setup_widgets();

  

+ /* This is how to activate and remove (here after 13 sec) the favicon

+ notification */

+ console.log('Show notification');

+ Notificon('#33ff00');

+ setTimeout(function(){console.log('Hide notification'); Notificon()}, 13000)

+ setTimeout(function(){

+     console.log('Show notification'); Notificon('#eb361e')

+   }, 15000)

+ setTimeout(function(){console.log('Hide notification'); Notificon()}, 18000)

+ 

  </script>

  {% endblock %}

file modified
+4 -1
@@ -6,10 +6,13 @@ 

    <link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet" />

    <link href="{{ url_for('static', filename='css/pace-theme-minimal.css') }}" rel="stylesheet" />

    <script type="text/javascript"  src="{{ url_for('static', filename='js/pace.min.js') }}"></script>

+   <script type="text/javascript"  src="{{ url_for('static', filename='notificon.js') }}"></script>

    <link href="{{ url_for('static', filename='open_iconic_1.1.0/css/open-iconic.min.css') }}"

          type="text/css" rel="stylesheet" />

    <link href="{{ url_for('static', filename='badges/b.css') }}"

          type="text/css" rel="stylesheet" />

+   <link rel="icon" type="image/png"

+       href="{{ url_for('static', filename='img/favicon.png') }}">

  </head>

  <body>

  <div class="masthead">
@@ -42,7 +45,7 @@ 

        <div class="input-group">

          <input type="search" class="form-control" placeholder="Search across all hubs ..." aria-describedby="searchform-addon"></input>

          <span class="input-group-addon" id="searchform-addon">

-           <span class="oi" data-glyph="magnifying-glass" / >

+           <span class="oi" data-glyph="magnifying-glass"></span>

          </span>

      </div>

      </div>

file modified
-8
@@ -96,11 +96,3 @@ 

          subsequent.widget_arguments = getattr(original, 'widget_arguments', [])

          return subsequent

      return decorator

- 

- 

- def avatar(username, size=32):

-     openid = 'http://%s.id.fedoraproject.org/' % username

-     query = six.moves.urllib_parse.urlencode({'s': size, 'd': 'retro'})

-     hash = hashlib.sha256(openid.encode('utf-8')).hexdigest()

-     template = "https://seccdn.libravatar.org/avatar/%s?%s"

-     return template % (hash, query)

file modified
+5 -2
@@ -2,8 +2,9 @@ 

  

  from hubs.hinting import hint, prefixed as _

  from hubs.widgets.chrome import panel

- from hubs.widgets.base import argument, avatar

+ from hubs.widgets.base import argument

  from hubs.widgets import templating

+ from hubs.utils import username2avatar

  from hubs import validators

  

  chrome = panel()
@@ -25,7 +26,9 @@ 

            help="Link to meeting minutes from past meetings..")

  def data(session, widget, link, schedule_text, schedule_link, minutes_link):

      owners = widget.hub.owners

-     owners = ordereddict([(o.username, avatar(o.username)) for o in owners])

+     owners = ordereddict([

+         (o.username, username2avatar(o.username)) for o in owners

+     ])

      return dict(owners=owners, link=link,

                  schedule_text=schedule_text,

                  schedule_link=schedule_link,

no initial comment

3 new commits added

  • Show logic to toggle notification on and off
  • Add a hubs favicon and make it present on all hubs
  • Drop the change for the avatar
7 years ago

1 new commit added

  • Hide the notification at the end
7 years ago

Wouldn't this username throw an UndefinedError?

1 new commit added

7 years ago

Looks good to me :thumbsup:

Pull-Request has been merged by pingou

7 years ago