diff --git a/background.html b/background.html index 0400c8e26..273eb0842 100644 --- a/background.html +++ b/background.html @@ -87,9 +87,17 @@
+ @@ -286,6 +294,7 @@ + diff --git a/js/models/conversations.js b/js/models/conversations.js index 47f54290e..e6c3663d0 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -7,6 +7,24 @@ // TODO: Factor out private and group subclasses of Conversation + var COLORS = [ + "#EF5350", // red + "#EC407A", // pink + "#AB47BC", // purple + "#7E57C2", // deep purple + "#5C6BC0", // indigo + "#2196F3", // blue + "#03A9F4", // light blue + "#00BCD4", // cyan + "#009688", // teal + "#4CAF50", // green + "#7CB342", // light green + "#FF9800", // orange + "#FF5722", // deep orange + "#FFB300", // amber + "#607D8B", // blue grey + ]; + Whisper.Conversation = Backbone.Model.extend({ database: Whisper.Database, storeName: 'conversations', @@ -219,6 +237,17 @@ } }, + getNotificationIcon: function() { + return new Promise(function(resolve) { + var avatar = this.getAvatar(); + if (avatar.url) { + resolve(avatar.url); + } else { + resolve(new Whisper.IdenticonSVGView(avatar).getDataUrl()); + } + }.bind(this)); + }, + updateAvatarUrl: function(silent) { this.revokeAvatarUrl(); var avatar = this.get('avatar'); @@ -243,11 +272,11 @@ } else if (this.isPrivate()) { var title = this.get('name'); if (!title) { - return { content: '#', color: 'gray' }; + return { content: '#', color: '#999999' }; } var initials = title.trim()[0]; return { - color: 1 + (Math.abs(this.hashCode()) % 15), + color: COLORS[Math.abs(this.hashCode()) % 15], content: initials }; } else { diff --git a/js/panel_controller.js b/js/panel_controller.js index 3dce63cd3..e9f245fb2 100644 --- a/js/panel_controller.js +++ b/js/panel_controller.js @@ -93,14 +93,16 @@ var sender = ConversationController.create({id: message.get('source')}); conversation.fetch().then(function() { sender.fetch().then(function() { - var notification = new Notification(sender.getTitle(), { - body: message.getDescription(), - icon: sender.getAvatar().url, - tag: conversation.id + sender.getNotificationIcon().then(function(icon) { + var notification = new Notification(sender.getTitle(), { + body: message.getDescription(), + icon: icon, + tag: conversation.id + }); + notification.onclick = function() { + openConversation(conversation); + }; }); - notification.onclick = function() { - openConversation(conversation); - }; }); }); } else { diff --git a/js/views/identicon_svg_view.js b/js/views/identicon_svg_view.js new file mode 100644 index 000000000..411bf6175 --- /dev/null +++ b/js/views/identicon_svg_view.js @@ -0,0 +1,39 @@ +/* + * vim: ts=4:sw=4:expandtab + */ +(function () { + 'use strict'; + window.Whisper = window.Whisper || {}; + + /* + * Render an avatar identicon to an svg for use in a notification. + */ + Whisper.IdenticonSVGView = Whisper.View.extend({ + templateName: 'identicon-svg', + initialize: function(options) { + this.render_attributes = options; + }, + getSVGUrl: function() { + var html = this.render().$el.html(); + var svg = new Blob([html], {type: 'image/svg+xml;charset=utf-8'}); + return URL.createObjectURL(svg); + }, + getDataUrl: function() { + var svgurl = this.getSVGUrl(); + return new Promise(function(resolve) { + var img = document.createElement('img'); + img.onload = function () { + var canvas = loadImage.scale(img, { + canvas: true, maxWidth: 44, maxHeight: 44 + }); + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + URL.revokeObjectURL(svgurl); + resolve(canvas.toDataURL("image/png")); + }; + + img.src = svgurl; + }); + } + }); +})();