From af1c14939e443cf37ca981756bdbbc804d118c40 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Fri, 7 Jun 2013 17:15:49 -0700 Subject: [PATCH] Add 'dynamic favicon' setting --- app/assets/images/default-favicon.ico | Bin 0 -> 1342 bytes app/assets/javascripts/discourse.js | 8 + .../external/jquery.faviconNotify.js | 224 ++++++++++++++++++ app/models/site_setting.rb | 3 +- config/locales/server.en.yml | 1 + 5 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 app/assets/images/default-favicon.ico create mode 100644 app/assets/javascripts/external/jquery.faviconNotify.js diff --git a/app/assets/images/default-favicon.ico b/app/assets/images/default-favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..d20ae8eeded413f3de968472303a4dbc2a63409c GIT binary patch literal 1342 zcmd^8ZBJ5R7=98VA)LGk2*<-opa2sX2uMIXK_&%QCI}&FTf`hq#7eUjAtPGNm+C_s zt@_lL-1=5Ou*sV)9?3-&<_atZy+oH357zj(AU?u1lbE*1MWkg!~LcH z{(iED2zX(qI|2>S_U`at`h9!TrMY1CX<{>rAmiFp$g7;2s_nAHLiI) zo_W->0hwyGjg5^x4hDlB$VUiy>P#lH5sSqd0|Nt8Ukp9YTP&6*kmG0igT&{1Y?p!DwX;Q`SM}-v8+%i)M%z~o&$WGAnbw9 zU^aR5bU&R=(+p3fdcD4czHKAm24Q5xz6-u6ld)N^*V~0Zb7C?awOVZz>;Z5cciwhg zaJ}g1>7g0;(3f|mQt4T<*`(DyLY+>>5Do`Aa8SRq*v~Bb7v?zb8+5BgBFRlm1U?|Y z-fp+gVt$g}hqPL)P^D6-LB9o1k7}6R!K@}HCtGs4{3UEk^t6io>8`A-v~gcyXXkYu zd~13-^B(>JUsTP4N&YApbFd_92}go*=(mFA4|b-IBU1tx6qemnM_7+q}`@| Ng)w*j*rfm1_!9uNhV}pe literal 0 HcmV?d00001 diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js index 954d8ad1b37..33e1627ce39 100644 --- a/app/assets/javascripts/discourse.js +++ b/app/assets/javascripts/discourse.js @@ -85,6 +85,14 @@ Discourse = Ember.Application.createWithMixins({ }, 200); }.observes('title', 'hasFocus', 'notifyCount'), + faviconChanged: function() { + if(Discourse.SiteSettings.dynamic_favicon) { + $.faviconNotify( + Discourse.SiteSettings.favicon_url, this.get('notifyCount') + ); + } + }.observes('notifyCount'), + // The classes of buttons to show on a post postButtons: function() { return Discourse.SiteSettings.post_menu.split("|").map(function(i) { diff --git a/app/assets/javascripts/external/jquery.faviconNotify.js b/app/assets/javascripts/external/jquery.faviconNotify.js new file mode 100644 index 00000000000..2b071e30e7c --- /dev/null +++ b/app/assets/javascripts/external/jquery.faviconNotify.js @@ -0,0 +1,224 @@ +/** + * jQuery Favicon Notify + * + * Updates the favicon to notify the user of changes. In the original tests I + * had an embedded font collection to allow any charachers - I decided that the + * ~130Kb and added complexity was overkill. As such it now uses a manual glyph + * set meaning that only numerical notifications are possible. + * + * Dual licensed under the MIT and GPL licenses: + * + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * @author David King + * @copyright Copyright (c) 2011 + + * @url oodavid.com + */ +(function($){ + var canvas; + var bg = '#000000'; + var fg = '#FFFFFF'; + var pos = 'br'; + $.faviconNotify = function(icon, num, myPos, myBg, myFg){ + // Default the positions + myPos = myPos || pos; + myFg = myFg || fg; + myBg = myBg || bg; + // Create a canvas if we need one + canvas = canvas || $('')[0]; + if(canvas.getContext){ + // Load the icon + $('').load(function(e){ + // Load the icon into the canvas + canvas.height = canvas.width = 16; + var ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.drawImage(this, 0, 0); + // We gots num? + if(num !== undefined){ + num = parseFloat(num, 10); + // Convert the num into a glyphs array + var myGlyphs = []; + if(num > 99){ + myGlyphs.push(glyphs['LOTS']); + } else { + num = num.toString().split(''); + $.each(num, function(k,v){ + myGlyphs.push(glyphs[v]); + }); + } + // Merge the glyphs together + var combined = []; + var glyphHeight = myGlyphs[0].length; + $.each(myGlyphs, function(k,v){ + for(y=0; y').attr('href', canvas.toDataURL('image/png'))); + }).attr('src', icon) + } + }; + var glyphs = { + '0': [ + ' --- ', + ' -@@@- ', + '-@---@-', + '-@- -@-', + '-@- -@-', + '-@- -@-', + '-@---@-', + ' -@@@- ', + ' --- ' ], + '1': [ + ' - ', + ' -@- ', + '-@@- ', + ' -@- ', + ' -@- ', + ' -@- ', + ' -@- ', + '-@@@-', + ' --- ' ], + '2': [ + ' --- ', + ' -@@@- ', + '-@---@-', + ' - --@-', + ' -@@- ', + ' -@-- ', + '-@---- ', + '-@@@@@-', + ' ----- ' ], + '3': [ + ' --- ', + ' -@@@- ', + '-@---@-', + ' - --@-', + ' -@@- ', + ' - --@-', + '-@---@-', + ' -@@@- ', + ' --- ' ], + '4': [ + ' -- ', + ' -@@-', + ' -@-@-', + ' -@--@-', + '-@---@-', + '-@@@@@-', + ' ----@-', + ' -@-', + ' - ' ], + '5': [ + ' ----- ', + '-@@@@@-', + '-@---- ', + '-@--- ', + '-@@@@- ', + ' ----@-', + '-@---@-', + ' -@@@- ', + ' --- ' ], + '6': [ + ' --- ', + ' -@@@- ', + '-@---@-', + '-@---- ', + '-@@@@- ', + '-@---@-', + '-@---@-', + ' -@@@- ', + ' --- ' ], + '7': [ + ' ----- ', + '-@@@@@-', + ' ----@-', + ' -@- ', + ' -@- ', + ' -@- ', + ' -@- ', + ' -@- ', + ' - ' ], + '8': [ + ' --- ', + ' -@@@- ', + '-@---@-', + '-@---@-', + ' -@@@- ', + '-@---@-', + '-@---@-', + ' -@@@- ', + ' --- ' ], + '9': [ + ' --- ', + ' -@@@- ', + '-@---@-', + '-@---@-', + ' -@@@@-', + ' ----@-', + '-@---@-', + ' -@@@- ', + ' --- ' ], + '!': [ + ' - ', + '-@-', + '-@-', + '-@-', + '-@-', + '-@-', + ' - ', + '-@-', + ' - ' ], + '.': [ + ' ', + ' ', + ' ', + ' ', + ' ', + ' ', + ' - ', + '-@-', + ' - ' ], + 'LOTS': [ + ' - -- --- -- ', + '-@- -@@-@@@--@@-', + '-@--@--@-@--@- ', + '-@--@--@-@--@- ', + '-@--@--@-@- -@- ', + '-@--@--@-@- -@-', + '-@--@--@-@----@-', + '-@@@-@@--@-@@@- ', + ' --- -- - --- ' + ] + }; +})(jQuery); diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index e5b99a92260..93fee5b34ba 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -79,7 +79,8 @@ class SiteSetting < ActiveRecord::Base setting(:invite_expiry_days, 14) setting(:active_user_rate_limit_secs, 60) setting(:previous_visit_timeout_hours, 1) - setting(:favicon_url, '/assets/default-favicon.png') + client_setting(:favicon_url, '/assets/default-favicon.ico') + client_setting(:dynamic_favicon, false) setting(:apple_touch_icon_url, '/assets/default-apple-touch-icon.png') setting(:ninja_edit_window, 5.minutes.to_i) diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 47f225f6e61..9e689872a53 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -460,6 +460,7 @@ en: logo_url: "The logo for your site eg: http://example.com/logo.png" logo_small_url: "The small logo for your site used when scrolling down on topics eg: http://example.com/logo-small.png" favicon_url: "A favicon for your site, see http://en.wikipedia.org/wiki/Favicon" + dynamic_favicon: "Show incoming message notifications on favicon" apple_touch_icon_url: "Icon used for Apple touch devices. Recommended size is 144px by 144px." notification_email: "The return email address used when sending system emails such as notifying users of lost passwords, new accounts etc"