From a9dcc68af27ad86bc25bfa050698db6f1dbe1f4e Mon Sep 17 00:00:00 2001 From: Tor Hveem Date: Tue, 15 Oct 2013 14:31:41 +0200 Subject: [PATCH 1/9] Instead of using buffer.notification as a boolean, save number of notifications into the variable. And when displaying unread messages display unread notifications if any and if not then display number of unreads. --- index.html | 3 ++- js/models.js | 4 ++-- js/websockets.js | 8 ++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index c9a0301..578651b 100644 --- a/index.html +++ b/index.html @@ -100,7 +100,8 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel
  • - + + {{ content.shortName }}{{ content.fullName }}
  • diff --git a/js/models.js b/js/models.js index a505b81..bbac9e6 100644 --- a/js/models.js +++ b/js/models.js @@ -17,7 +17,7 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { var pointer = message['pointers'][0] var lines = [] var active = false; - var notification = false; + var notification = ''; var unread = ''; var lastSeen = -2; @@ -161,9 +161,9 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { } }); - activeBuffer.notification = false; activeBuffer.active = true; activeBuffer.unread = ''; + activeBuffer.notification = ''; $rootScope.$emit('activeBufferChanged'); } diff --git a/js/websockets.js b/js/websockets.js index 70965de..ec10555 100644 --- a/js/websockets.js +++ b/js/websockets.js @@ -209,7 +209,11 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi if(message.highlight || _.contains(message.tags, 'notify_private') ) { $rootScope.createHighlight(buffer, message); - buffer.notification = true; + if (buffer.notification == '' || buffer.notification == undefined) { + buffer.notification = 1; + }else { + buffer.notification++; + } } } } @@ -519,7 +523,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', // Find next buffer with activity and switch to it for(i in $scope.buffers) { var buffer = $scope.buffers[i]; - if(buffer.notification) { + if((parseInt(buffer.notification) || 0) > 0) { $scope.setActiveBuffer(buffer.id); break; }else if((parseInt(buffer.unread) || 0) > 0) { From 2617dadb65ee1e3a5c36f9977e4f52dc85524c22 Mon Sep 17 00:00:00 2001 From: Tor Hveem Date: Tue, 15 Oct 2013 14:59:06 +0200 Subject: [PATCH 2/9] Simplify/clean up the unread and notification code --- index.html | 2 +- js/models.js | 14 +++++++++----- js/websockets.js | 16 ++++------------ 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/index.html b/index.html index 578651b..bdb9efe 100644 --- a/index.html +++ b/index.html @@ -100,7 +100,7 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel
  • - + {{ content.shortName }}{{ content.fullName }} diff --git a/js/models.js b/js/models.js index bbac9e6..42e46fa 100644 --- a/js/models.js +++ b/js/models.js @@ -16,10 +16,10 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { var number = message['number'] var pointer = message['pointers'][0] var lines = [] - var active = false; - var notification = ''; - var unread = ''; - var lastSeen = -2; + var active = false + var notification = 0 + var unread = 0 + var lastSeen = -2 /* * Adds a line to this buffer @@ -30,7 +30,7 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { var addLine = function(line) { lines.push(line); } - + return { id: pointer, fullName: fullName, @@ -40,6 +40,8 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { lines: lines, addLine: addLine, lastSeen: lastSeen, + unread: unread, + notification: notification, } } @@ -100,6 +102,8 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { var BufferList = [] activeBuffer = null; + unreads = 0; + notifications = 0; this.model = { 'buffers': {} } diff --git a/js/websockets.js b/js/websockets.js index ec10555..3bb68cd 100644 --- a/js/websockets.js +++ b/js/websockets.js @@ -200,20 +200,12 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi if (!initial) { if (!buffer.active && _.contains(message.tags, 'notify_message') && !_.contains(message.tags, 'notify_none')) { - if (buffer.unread == '' || buffer.unread == undefined) { - buffer.unread = 1; - }else { - buffer.unread++; - } + buffer.unread++; } if(message.highlight || _.contains(message.tags, 'notify_private') ) { + buffer.notification++; $rootScope.createHighlight(buffer, message); - if (buffer.notification == '' || buffer.notification == undefined) { - buffer.notification = 1; - }else { - buffer.notification++; - } } } } @@ -523,10 +515,10 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', // Find next buffer with activity and switch to it for(i in $scope.buffers) { var buffer = $scope.buffers[i]; - if((parseInt(buffer.notification) || 0) > 0) { + if(buffer.notification > 0) { $scope.setActiveBuffer(buffer.id); break; - }else if((parseInt(buffer.unread) || 0) > 0) { + }else if(buffer.unread > 0) { $scope.setActiveBuffer(buffer.id); break; } From a9d469867a4e8c20479b614c7cf4f51a3cf5c637 Mon Sep 17 00:00:00 2001 From: Tor Hveem Date: Tue, 15 Oct 2013 15:21:13 +0200 Subject: [PATCH 3/9] Add Favio.js support. Fixes #28 --- index.html | 1 + js/favico-0.3.0.min.js | 7 +++++++ js/models.js | 5 +++-- js/websockets.js | 23 +++++++++++++++++++++-- 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 js/favico-0.3.0.min.js diff --git a/index.html b/index.html index bdb9efe..8b46381 100644 --- a/index.html +++ b/index.html @@ -16,6 +16,7 @@ + diff --git a/js/favico-0.3.0.min.js b/js/favico-0.3.0.min.js new file mode 100644 index 0000000..0ebcc24 --- /dev/null +++ b/js/favico-0.3.0.min.js @@ -0,0 +1,7 @@ +/** + * @license MIT + * @fileOverview Favico animations + * @author Miroslav Magda, http://blog.ejci.net + * @version 0.3.0 + */ +!function(){var t=function(t){"use strict";function e(t){if(t.paused||t.ended||g)return!1;try{s.clearRect(0,0,h,a),s.drawImage(t,0,0,h,a)}catch(o){}setTimeout(e,L.duration,t),E.setIcon(c)}function o(t){var e=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;t=t.replace(e,function(t,e,o,n){return e+e+o+o+n+n});var o=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return o?{r:parseInt(o[1],16),g:parseInt(o[2],16),b:parseInt(o[3],16)}:!1}function n(t,e){var o,n={};for(o in t)n[o]=t[o];for(o in e)n[o]=e[o];return n}t=t?t:{};var r,i,a,h,c,s,l,f,u,d,y,g,w,x={bgColor:"#d00",textColor:"#fff",fontFamily:"sans-serif",fontStyle:"bold",type:"circle",position:"down",animation:"slide",elementId:!1},m=[];y=function(){},f=g=!1;var p=function(){if(r=n(x,t),r.bgColor=o(r.bgColor),r.textColor=o(r.textColor),r.position=r.position.toLowerCase(),r.animation=L.types[""+r.animation]?r.animation:x.animation,"up"===r.position)for(var e=0;e0?l.height:32,h=l.width>0?l.width:32,c.height=a,c.width=h,s=c.getContext("2d"),v.ready()},w={},w.ff=/firefox/i.test(navigator.userAgent.toLowerCase()),w.chrome=/chrome/i.test(navigator.userAgent.toLowerCase()),w.opera=/opera/i.test(navigator.userAgent.toLowerCase()),w.ie=/msie/i.test(navigator.userAgent.toLowerCase())||/trident/i.test(navigator.userAgent.toLowerCase()),w.supported=w.chrome||w.ff||w.opera}catch(u){throw"Error initializing favico..."}},v={};v.ready=function(){f=!0,v.reset(),y()},v.reset=function(){m=[],u=!1,s.clearRect(0,0,h,a),s.drawImage(l,0,0,h,a),E.setIcon(c)},v.start=function(){if(f&&!d){var t=function(){u=m[0],d=!1,m.length>0&&(m.shift(),v.start())};m.length>0&&(d=!0,u?L.run(u.options,function(){L.run(m[0].options,function(){t()},!1)},!0):L.run(m[0].options,function(){t()},!1))}};var b={},C=function(t){return t.n=Math.abs(t.n),t.x=h*t.x,t.y=a*t.y,t.w=h*t.w,t.h=a*t.h,t};b.circle=function(t){t=C(t);var e=t.n>9&&t.n<100;e&&(t.x=t.x-.4*t.w,t.w=1.4*t.w),s.clearRect(0,0,h,a),s.drawImage(l,0,0,h,a),s.beginPath(),s.font=r.fontStyle+" "+Math.floor(t.h)+"px "+r.fontFamily,s.textAlign="center",e?(s.moveTo(t.x+t.w/2,t.y),s.lineTo(t.x+t.w-t.h/2,t.y),s.quadraticCurveTo(t.x+t.w,t.y,t.x+t.w,t.y+t.h/2),s.lineTo(t.x+t.w,t.y+t.h-t.h/2),s.quadraticCurveTo(t.x+t.w,t.y+t.h,t.x+t.w-t.h/2,t.y+t.h),s.lineTo(t.x+t.h/2,t.y+t.h),s.quadraticCurveTo(t.x,t.y+t.h,t.x,t.y+t.h-t.h/2),s.lineTo(t.x,t.y+t.h/2),s.quadraticCurveTo(t.x,t.y,t.x+t.h/2,t.y)):s.arc(t.x+t.w/2,t.y+t.h/2,t.h/2,0,2*Math.PI),s.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+t.o+")",s.fill(),s.closePath(),s.beginPath(),s.stroke(),s.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+t.o+")",t.n>99?s.fillText("∞",Math.floor(t.x+t.w/2),Math.floor(t.y+t.h-.15*t.h)):s.fillText(t.n,Math.floor(t.x+t.w/2),Math.floor(t.y+t.h-.15*t.h)),s.closePath()},b.rectangle=function(t){t=C(t);var e=t.n>9&&t.n<100;e&&(t.x=Math.floor(t.x-.4*t.w),t.w=Math.floor(1.4*t.w)),s.clearRect(0,0,h,a),s.drawImage(l,0,0,h,a),s.beginPath(),s.font="bold "+Math.floor(t.h)+"px sans-serif",s.textAlign="center",s.fillStyle="rgba("+r.bgColor.r+","+r.bgColor.g+","+r.bgColor.b+","+t.o+")",s.fillRect(t.x,t.y,t.w,t.h),s.fillStyle="rgba("+r.textColor.r+","+r.textColor.g+","+r.textColor.b+","+t.o+")",t.n>99?s.fillText("∞",Math.floor(t.x+t.w/2),Math.floor(t.y+t.h-.15*t.h)):s.fillText(t.n,Math.floor(t.x+t.w/2),Math.floor(t.y+t.h-.15*t.h)),s.closePath()};var I=function(t,e){y=function(){try{if(t>0){if(L.types[""+e]&&(r.animation=e),m.push({type:"badge",options:{n:t}}),m.length>100)throw"Too many badges requests in queue...";v.start()}else v.reset()}catch(o){throw"Error setting badge..."}},f&&y()},A=function(t){y=function(){try{var e=t.width,o=t.height,n=document.createElement("img"),r=o/a>e/h?e/h:o/a;n.setAttribute("src",t.getAttribute("src")),n.height=o/r,n.width=e/r,s.clearRect(0,0,h,a),s.drawImage(n,0,0,h,a),E.setIcon(c)}catch(i){throw"Error setting image..."}},f&&y()},M=function(t){y=function(){try{if("stop"===t)return g=!0,v.reset(),g=!1,void 0;t.addEventListener("play",function(){e(this)},!1)}catch(o){throw"Error setting video..."}},f&&y()},T=function(t){if(window.URL&&window.URL.createObjectURL||(window.URL=window.URL||{},window.URL.createObjectURL=function(t){return t}),w.supported){var o=!1;navigator.getUserMedia=navigator.getUserMedia||navigator.oGetUserMedia||navigator.msGetUserMedia||navigator.mozGetUserMedia||navigator.webkitGetUserMedia,y=function(){try{if("stop"===t)return g=!0,v.reset(),g=!1,void 0;o=document.createElement("video"),o.width=h,o.height=a,navigator.getUserMedia({video:!0,audio:!1},function(t){o.src=URL.createObjectURL(t),o.play(),e(o)},function(){})}catch(n){throw"Error setting webcam..."}},f&&y()}},E={};E.getIcon=function(){var t=!1,e=function(){for(var t=document.getElementsByTagName("head")[0].getElementsByTagName("link"),e=t.length,o=e-1;o>=0;o--)if(/icon/i.test(t[o].getAttribute("rel")))return t[o];return!1};return r.elementId?(t=document.getElementById(r.elementId),t.setAttribute("href",t.getAttribute("src"))):(t=e(),t===!1&&(t=document.createElement("link"),t.setAttribute("rel","icon"),document.getElementsByTagName("head")[0].appendChild(t))),t.setAttribute("type","image/png"),t},E.setIcon=function(t){var e=t.toDataURL("image/png");if(r.elementId)document.getElementById(r.elementId).setAttribute("src",e);else if(w.ff||w.opera){var o=i;i=document.createElement("link"),w.opera&&i.setAttribute("rel","icon"),i.setAttribute("rel","icon"),i.setAttribute("type","image/png"),document.getElementsByTagName("head")[0].appendChild(i),i.setAttribute("href",e),o.parentNode&&o.parentNode.removeChild(o)}else i.setAttribute("href",e)};var L={};return L.duration=40,L.types={},L.types.fade=[{x:.4,y:.4,w:.6,h:.6,o:0},{x:.4,y:.4,w:.6,h:.6,o:.1},{x:.4,y:.4,w:.6,h:.6,o:.2},{x:.4,y:.4,w:.6,h:.6,o:.3},{x:.4,y:.4,w:.6,h:.6,o:.4},{x:.4,y:.4,w:.6,h:.6,o:.5},{x:.4,y:.4,w:.6,h:.6,o:.6},{x:.4,y:.4,w:.6,h:.6,o:.7},{x:.4,y:.4,w:.6,h:.6,o:.8},{x:.4,y:.4,w:.6,h:.6,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],L.types.none=[{x:.4,y:.4,w:.6,h:.6,o:1}],L.types.pop=[{x:1,y:1,w:0,h:0,o:1},{x:.9,y:.9,w:.1,h:.1,o:1},{x:.8,y:.8,w:.2,h:.2,o:1},{x:.7,y:.7,w:.3,h:.3,o:1},{x:.6,y:.6,w:.4,h:.4,o:1},{x:.5,y:.5,w:.5,h:.5,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],L.types.popFade=[{x:.75,y:.75,w:0,h:0,o:0},{x:.65,y:.65,w:.1,h:.1,o:.2},{x:.6,y:.6,w:.2,h:.2,o:.4},{x:.55,y:.55,w:.3,h:.3,o:.6},{x:.5,y:.5,w:.4,h:.4,o:.8},{x:.45,y:.45,w:.5,h:.5,o:.9},{x:.4,y:.4,w:.6,h:.6,o:1}],L.types.slide=[{x:.4,y:1,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.9,w:.6,h:.6,o:1},{x:.4,y:.8,w:.6,h:.6,o:1},{x:.4,y:.7,w:.6,h:.6,o:1},{x:.4,y:.6,w:.6,h:.6,o:1},{x:.4,y:.5,w:.6,h:.6,o:1},{x:.4,y:.4,w:.6,h:.6,o:1}],L.run=function(t,e,o,i){var a=L.types[r.animation];return i=o===!0?"undefined"!=typeof i?i:a.length-1:"undefined"!=typeof i?i:0,e=e?e:function(){},i=0?(b[r.type](n(t,a[i])),setTimeout(function(){o?i-=1:i+=1,L.run(t,e,o,i)},L.duration),E.setIcon(c),void 0):(e(),void 0)},p(),{badge:I,video:M,image:A,webcam:T,reset:v.reset}};"undefined"!=typeof define&&define.amd?define([],function(){return t}):"undefined"!=typeof module&&module.exports?module.exports=t:this.Favico=t}(); \ No newline at end of file diff --git a/js/models.js b/js/models.js index 42e46fa..5afdcb2 100644 --- a/js/models.js +++ b/js/models.js @@ -166,10 +166,11 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { }); activeBuffer.active = true; - activeBuffer.unread = ''; - activeBuffer.notification = ''; + activeBuffer.unread = 0; + activeBuffer.notification = 0; $rootScope.$emit('activeBufferChanged'); + $rootScope.$emit('notificationChanged'); } /* diff --git a/js/websockets.js b/js/websockets.js index 3bb68cd..a39b86d 100644 --- a/js/websockets.js +++ b/js/websockets.js @@ -201,11 +201,13 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi if (!initial) { if (!buffer.active && _.contains(message.tags, 'notify_message') && !_.contains(message.tags, 'notify_none')) { buffer.unread++; + $rootScope.$emit('notificationChanged'); } if(message.highlight || _.contains(message.tags, 'notify_private') ) { buffer.notification++; $rootScope.createHighlight(buffer, message); + $rootScope.$emit('notificationChanged'); } } } @@ -424,13 +426,29 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', } } - $rootScope.$on('activeBufferChanged', function() { $rootScope.scrollToBottom(); document.getElementById('sendMessage').focus(); var ab = models.getActiveBuffer(); $rootScope.pageTitle = ab.shortName + ' | ' + ab.title; }); + $rootScope.$on('notificationChanged', function() { + var notifications = _.reduce(models.model.buffers, function(memo, num) { return parseInt(memo||0) + num.notification;}); + if (notifications > 0 ) { + $scope.favico = new Favico({ + animation:'none' + }); + $scope.favico.badge(notifications); + }else { + var unread = _.reduce(models.model.buffers, function(memo, num) { return parseInt(memo||0) + num.unread;}); + $scope.favico = new Favico({ + animation:'none', + bgColor : '#5CB85C', + textColor : '#ff0', + }); + $scope.favico.badge(unread); + } + }); $scope.buffers = models.model.buffers; $scope.activeBuffer = models.getActiveBuffer @@ -506,7 +524,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', if (models.getActiveBuffer() == buffer) { return true; } - return (parseInt(buffer.unread) || 0) > 0; + return buffer.unread > 0; } return true; }; @@ -556,5 +574,6 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', return true; } }; + }] ); From d1ab293b4b32fa6244fb6683bb73419681d0a873 Mon Sep 17 00:00:00 2001 From: Tor Hveem Date: Tue, 15 Oct 2013 15:41:13 +0200 Subject: [PATCH 4/9] Attempt at tidying up the landing page slightly --- index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 8b46381..581dde5 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,6 @@ WeeChat web frontend -
    WeeChat 0.4.2 or later is required
    Oh no! We cannot connect!
    @@ -67,7 +66,8 @@
     /set relay.network.password yourpassword
     /relay add weechat 9001
    - Note: The communication goes directly between your browser and your weechat in clear text. + WeeChat version 0.4.2 or higher is required.
    + The communication goes directly between your browser and your weechat in clear text. Connection settings are saved between sessions, including password, in your own browser.

    Encryption

    If you want to use encrypted session you first have to set up the relay using SSL From 001024db7d4206f415f3a64c37eaef7abc176bee Mon Sep 17 00:00:00 2001 From: Tor Hveem Date: Tue, 15 Oct 2013 16:09:08 +0200 Subject: [PATCH 5/9] Collapse for frontpage, and style inputs --- css/glowingbear.css | 23 +++++++- index.html | 135 +++++++++++++++++++++++++++++--------------- 2 files changed, 109 insertions(+), 49 deletions(-) diff --git a/css/glowingbear.css b/css/glowingbear.css index 46e4b13..71c3692 100644 --- a/css/glowingbear.css +++ b/css/glowingbear.css @@ -71,6 +71,26 @@ input#sendMessage { border: 0; width: 100%; } +.panel input { + max-width: 300px; +} +input[type=text], input[type=password] { + color: black; + border: 0; + -webkit-box-shadow: + inset 0 0 8px rgba(0,0,0,0.4), + 0 0 16px rgba(0,0,0,0.4); + -moz-box-shadow: + inset 0 0 8px rgba(0,0,0,0.4), + 0 0 16px rgba(0,0,0,0.4); + box-shadow: + inset 0 0 8px rgba(0,0,0,0.4), + 0 0 16px rgba(0,0,0,0.4); + background: rgba(255,255,255,0.5); +} +#sidebar, .panel { + background: #282828; +} #sidebar { position: fixed; width: 12%; @@ -78,8 +98,7 @@ input#sendMessage { height: 100%; min-width: 130px; overflow: auto; - background: #282828; -} + } .content { height: 100%; min-height: 100%; diff --git a/index.html b/index.html index 581dde5..e56cb12 100644 --- a/index.html +++ b/index.html @@ -32,55 +32,96 @@
    Oh no! We cannot connect!
    -