Merge pull request #46 from torhve/master

Changes
with-route-provider
David Cormier 12 years ago
commit 4014a4a696
  1. 21
      css/glowingbear.css
  2. 61
      index.html
  3. 7
      js/favico-0.3.0.min.js
  4. 17
      js/models.js
  5. 37
      js/plugins.js
  6. 85
      js/websockets.js

@ -71,6 +71,26 @@ input#sendMessage {
border: 0; border: 0;
width: 100%; 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 { #sidebar {
position: fixed; position: fixed;
width: 12%; width: 12%;
@ -78,7 +98,6 @@ input#sendMessage {
height: 100%; height: 100%;
min-width: 130px; min-width: 130px;
overflow: auto; overflow: auto;
background: #282828;
} }
.content { .content {
height: 100%; height: 100%;

@ -16,6 +16,7 @@
<script type="text/javascript" src="js/websockets.js"></script> <script type="text/javascript" src="js/websockets.js"></script>
<script type="text/javascript" src="js/models.js"></script> <script type="text/javascript" src="js/models.js"></script>
<script type="text/javascript" src="js/plugins.js"></script> <script type="text/javascript" src="js/plugins.js"></script>
<script type="text/javascript" src="js/favico-0.3.0.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
</head> </head>
@ -28,10 +29,20 @@
WeeChat web frontend WeeChat web frontend
</small> </small>
</h2> </h2>
<div class="alert alert-info">WeeChat 0.4.2 or later is required</div>
<div class="alert alert-danger" ng-show="errorMessage"> <div class="alert alert-danger" ng-show="errorMessage">
<strong>Oh no!</strong> We cannot connect! <strong>Oh no!</strong> We cannot connect!
</div> </div>
<div class="panel-group" id="accordion">
<div class="panel ">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
Connection settings
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
<form class="form-signin" role="form"> <form class="form-signin" role="form">
<div class="form-group"> <div class="form-group">
<label class="control-label" for="host">WeeChat hostname</label> <label class="control-label" for="host">WeeChat hostname</label>
@ -51,7 +62,7 @@
<div class="form-group"> <div class="form-group">
<label class="control-label" for="proto">Encryption</label> <label class="control-label" for="proto">Encryption</label>
<input type="checkbox" class="form-control" id="ssl" ng-model="ssl"> <input type="checkbox" class="form-control" id="ssl" ng-model="ssl">
<p class="help-block">Check the box if you want to encrypt communication between browser and WeeChat. <strong>Note</strong>: Due to a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=594502">bug</a> encryption will not work in Firefox. You must also first visit the URL https://weechathost:relayport/ to accept the certificate</p> <p class="help-block">Read encryption instructions for help</p>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label" for="port">Lines</label> <label class="control-label" for="port">Lines</label>
@ -60,16 +71,42 @@
</div> </div>
<button class="btn btn-lg btn-primary" ng-click="connect()">Connect!</button> <button class="btn btn-lg btn-primary" ng-click="connect()">Connect!</button>
</form> </form>
</div>
<h3>Instructions</h3> </div>
</div>
<div class="panel ">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">
Usage instructions
</a>
</h4>
</div>
<div id="collapseTwo" class="panel-collapse collapse">
<div class="panel-body">
<div>To start using, please enable relay in your WeeChat client: <div>To start using, please enable relay in your WeeChat client:
<pre> <pre>
/set relay.network.password yourpassword /set relay.network.password yourpassword
/relay add weechat 9001</pre> /relay add weechat 9001</pre>
Note: The communication goes directly between your browser and your weechat in clear text. <span class="label label-warning">WeeChat version 0.4.2 or higher is required.</span><br>
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. Connection settings are saved between sessions, including password, in your own browser.
<h4>Encryption</h4> </div>
If you want to use encrypted session you first have to set up the relay using SSL </div>
</div>
<div class="panel ">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapseThree">
Encryption instructions
</a>
</h4>
</div>
<div id="collapseThree" class="panel-collapse collapse">
<div class="panel-body">
If you check the encryption box, communication between browser and WeeChat will be encrypted.<br>
<strong>Note</strong>: Due to a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=594502">bug</a> encryption will not work in Firefox. You must also first visit the URL https://weechathost:relayport/ to accept the certificate</p>
If you want to use encrypted session you first have to set up the relay using SSL like this:
<pre> <pre>
$ mkdir -p ~/.weechat/ssl $ mkdir -p ~/.weechat/ssl
$ cd ~/.weechat/ssl $ cd ~/.weechat/ssl
@ -82,6 +119,11 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel
</pre> </pre>
</div> </div>
</div> </div>
</div>
</div>
</div>
</div>
</div>
<div class="content" ng-show="connected"> <div class="content" ng-show="connected">
<div id="sidebar"> <div id="sidebar">
<ul class="nav nav-pills nav-stacked"> <ul class="nav nav-pills nav-stacked">
@ -100,7 +142,8 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel
</li> </li>
<li class="label" ng-class="{'active': content.active }" ng-repeat="(key, content) in buffers | toArray | filter:search | filter:hasUnread | orderBy:'content.number':true"> <li class="label" ng-class="{'active': content.active }" ng-repeat="(key, content) in buffers | toArray | filter:search | filter:hasUnread | orderBy:'content.number':true">
<a href="#" ng-click="setActiveBuffer(content.id)" title="{{ content.fullName }}"> <a href="#" ng-click="setActiveBuffer(content.id)" title="{{ content.fullName }}">
<span class="badge pull-right" ng-class="{'danger': content.notification }" ng-bind="content.unread"></span> <span class="badge pull-right" ng-hide="content.notification" ng-if="content.unread" ng-bind="content.unread"></span>
<span class="badge pull-right danger" ng-show="content.notification" ng-bind="content.notification"></span>
{{ content.shortName }}<span ng-hide="content.shortName">{{ content.fullName }}</span> {{ content.shortName }}<span ng-hide="content.shortName">{{ content.fullName }}</span>
</a> </a>
</li> </li>
@ -119,7 +162,7 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel
<span ng-repeat="part in bufferline.prefix" class="text" style="{{ part.fg }}">{{ part.text }}</span> <span ng-repeat="part in bufferline.prefix" class="text" style="{{ part.fg }}">{{ part.text }}</span>
</td> </td>
<td class="message"> <td class="message">
<span ng-repeat="part in bufferline.content" class="text" style="{{ part.fg }}">{{ part.text }} </span> <span ng-repeat="part in bufferline.content" class="text" style="{{ part.fg }}" ng-bind-html="part.text"></span>
<div ng-repeat="metadata in bufferline.metadata"> <div ng-repeat="metadata in bufferline.metadata">
<div ng-show="metadata.visible"> <div ng-show="metadata.visible">

File diff suppressed because one or more lines are too long

@ -16,10 +16,10 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) {
var number = message['number'] var number = message['number']
var pointer = message['pointers'][0] var pointer = message['pointers'][0]
var lines = [] var lines = []
var active = false; var active = false
var notification = false; var notification = 0
var unread = ''; var unread = 0
var lastSeen = -2; var lastSeen = -2
/* /*
* Adds a line to this buffer * Adds a line to this buffer
@ -40,6 +40,8 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) {
lines: lines, lines: lines,
addLine: addLine, addLine: addLine,
lastSeen: lastSeen, lastSeen: lastSeen,
unread: unread,
notification: notification,
} }
} }
@ -100,6 +102,8 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) {
var BufferList = [] var BufferList = []
activeBuffer = null; activeBuffer = null;
unreads = 0;
notifications = 0;
this.model = { 'buffers': {} } this.model = { 'buffers': {} }
@ -161,11 +165,12 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) {
} }
}); });
activeBuffer.notification = false;
activeBuffer.active = true; activeBuffer.active = true;
activeBuffer.unread = ''; activeBuffer.unread = 0;
activeBuffer.notification = 0;
$rootScope.$emit('activeBufferChanged'); $rootScope.$emit('activeBufferChanged');
$rootScope.$emit('notificationChanged');
} }
/* /*

@ -55,31 +55,46 @@ plugins.service('plugins', ['userPlugins', '$sce', function(userPlugins, $sce)
*/ */
var contentForMessage = function(message) { var contentForMessage = function(message) {
var content = []; message.metadata = [];
for (var i = 0; i < plugins.length; i++) { for (var i = 0; i < plugins.length; i++) {
var nsfw = false; var nsfw = false;
var visible = true; var visible = true;
if (message.match(nsfwRegexp)) { if (message.text.match(nsfwRegexp)) {
var nsfw = true; var nsfw = true;
var visible = false; var visible = false;
} }
var pluginContent = plugins[i].contentForMessage(message); var pluginContent = plugins[i].contentForMessage(message.text);
if (pluginContent) { if (pluginContent) {
var pluginContent = {'visible': visible, var pluginContent = {'visible': visible,
'content': $sce.trustAsHtml(pluginContent), 'content': $sce.trustAsHtml(pluginContent),
'nsfw': nsfw, 'nsfw': nsfw,
'name': plugins[i].name } 'name': plugins[i].name }
content.push(pluginContent); message.metadata.push(pluginContent);
if (plugins[i].exclusive) { if (plugins[i].exclusive) {
break; break;
} }
} }
} }
return content;
/* Replace all URLs with hyperlinks */
var urlRegexp = RegExp(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?/g);
for(k in message.content) {
var text = message.content[k].text;
var url = text.match(urlRegexp);
for(i in url) {
var u = url[i];
text = text.replace(u, '<a target="_blank" href="' + u + '">' + u + '</a>');
}
message.content[k].text = $sce.trustAsHtml(text);
}
return message;
} }
return { return {
@ -124,16 +139,6 @@ plugins.factory('userPlugins', function() {
}); });
youtubePlugin.name = 'youtube video'; youtubePlugin.name = 'youtube video';
var urlPlugin = new Plugin(function(message) {
var url = message.match(urlRegexp);
if (url) {
return '<a target="_blank" href="' + url[0] + '">' + url[0] + '</a>';
}
return null;
});
urlPlugin.name = 'url';
var imagePlugin = new Plugin(function(message) { var imagePlugin = new Plugin(function(message) {
var url = message.match(urlRegexp); var url = message.match(urlRegexp);
@ -149,6 +154,6 @@ plugins.factory('userPlugins', function() {
imagePlugin.name = 'image'; imagePlugin.name = 'image';
return { return {
plugins: [youtubePlugin, urlPlugin, imagePlugin] plugins: [youtubePlugin, imagePlugin]
} }
}); });

@ -191,7 +191,7 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi
// Only react to line if its displayed // Only react to line if its displayed
if(message.displayed) { if(message.displayed) {
var buffer = models.getBuffer(message.buffer); var buffer = models.getBuffer(message.buffer);
message.metadata = plugins.PluginManager.contentForMessage(message.text); message = plugins.PluginManager.contentForMessage(message);
buffer.addLine(message); buffer.addLine(message);
if (buffer.active) { if (buffer.active) {
@ -200,16 +200,14 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi
if (!initial) { if (!initial) {
if (!buffer.active && _.contains(message.tags, 'notify_message') && !_.contains(message.tags, 'notify_none')) { 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++;
} $rootScope.$emit('notificationChanged');
} }
if(message.highlight || _.contains(message.tags, 'notify_private') ) { if(message.highlight || _.contains(message.tags, 'notify_private') ) {
buffer.notification++;
$rootScope.createHighlight(buffer, message); $rootScope.createHighlight(buffer, message);
buffer.notification = true; $rootScope.$emit('notificationChanged');
} }
} }
} }
@ -243,18 +241,6 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi
old.shortName = obj['short_name']; old.shortName = obj['short_name'];
} }
/*
* Handle answers to (bufinfo) messages
*
* (bufinfo) messages are specified by this client. It is the first
* message that is sent to the relay after connection.
*/
var handleBufferInfo = function(message) {
// buffer info from message
}
/* /*
* Handle answers to (lineinfo) messages * Handle answers to (lineinfo) messages
* *
@ -276,7 +262,6 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi
} }
var eventHandlers = { var eventHandlers = {
bufinfo: handleBufferInfo,
lineinfo: handleLineInfo, lineinfo: handleLineInfo,
_buffer_closing: handleBufferClosing, _buffer_closing: handleBufferClosing,
_buffer_line_added: handleBufferLineAdded, _buffer_line_added: handleBufferLineAdded,
@ -292,7 +277,7 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi
}]); }]);
weechat.factory('connection', ['$q', '$rootScope', '$log', 'handlers', 'colors', 'models', function($q, $rootScope, $log, handlers, colors, models) { weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers', 'colors', 'models', function($q, $rootScope, $log, storage, handlers, colors, models) {
protocol = new WeeChatProtocol(); protocol = new WeeChatProtocol();
var websocket = null; var websocket = null;
@ -329,6 +314,7 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', 'handlers', 'colors',
websocket.binaryType = "arraybuffer" websocket.binaryType = "arraybuffer"
websocket.onopen = function (evt) { websocket.onopen = function (evt) {
$log.info("Connected to relay");
doSend(WeeChatProtocol.formatInit({ doSend(WeeChatProtocol.formatInit({
password: passwd, password: passwd,
compression: 'off' compression: 'off'
@ -336,7 +322,8 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', 'handlers', 'colors',
doSendWithCallback(WeeChatProtocol.formatHdata({ doSendWithCallback(WeeChatProtocol.formatHdata({
path: 'buffer:gui_buffers(*)', path: 'buffer:gui_buffers(*)',
keys: ['number,full_name,short_name,title'] keys: ['number,full_name,short_name,title']
})).then(function(hdata) { })).then(function(message) {
$log.info("Parsing bufinfo");
var bufferInfos = message['objects'][0]['content']; var bufferInfos = message['objects'][0]['content'];
// buffers objects // buffers objects
for (var i = 0; i < bufferInfos.length ; i++) { for (var i = 0; i < bufferInfos.length ; i++) {
@ -347,16 +334,19 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', 'handlers', 'colors',
models.setActiveBuffer(buffer.id); models.setActiveBuffer(buffer.id);
} }
} }
$rootScope.connected = true;
// Request latest buffer lines for each buffer }).then(function() {
$rootScope.getLines(); $log.info("Parsing lineinfo");
doSendWithCallback(WeeChatProtocol.formatHdata({
path: "buffer:gui_buffers(*)/own_lines/last_line(-"+storage.get('lines')+")/data",
keys: []
})).then(function(hdata) {
handlers.handleLineInfo(hdata);
}); });
}).then(function() {
doSend(WeeChatProtocol.formatSync({})); doSend(WeeChatProtocol.formatSync({}));
$log.info("Synced");
$log.info("Connected to relay"); });
$rootScope.connected = true;
$rootScope.$apply();
} }
websocket.onclose = function (evt) { websocket.onclose = function (evt) {
@ -395,18 +385,9 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', 'handlers', 'colors',
})); }));
} }
var getLines = function(count) {
doSendWithCallback(WeeChatProtocol.formatHdata({
path: "buffer:gui_buffers(*)/own_lines/last_line(-"+count+")/data",
keys: []
})).then(function(hdata) {
handlers.handleLineInfo(hdata);
});
}
return { return {
send: doSend, send: doSend,
getLines: getLines,
connect: connect, connect: connect,
sendMessage: sendMessage sendMessage: sendMessage
} }
@ -428,13 +409,29 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
} }
} }
$rootScope.$on('activeBufferChanged', function() { $rootScope.$on('activeBufferChanged', function() {
$rootScope.scrollToBottom(); $rootScope.scrollToBottom();
document.getElementById('sendMessage').focus(); document.getElementById('sendMessage').focus();
var ab = models.getActiveBuffer(); var ab = models.getActiveBuffer();
$rootScope.pageTitle = ab.shortName + ' | ' + ab.title; $rootScope.pageTitle = ab.shortName + ' | ' + ab.title;
}); });
$rootScope.$on('notificationChanged', function() {
var notifications = _.reduce(models.model.buffers, function(memo, num) { return (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 (memo||0) + num.unread;});
$scope.favico = new Favico({
animation:'none',
bgColor : '#5CB85C',
textColor : '#ff0',
});
$scope.favico.badge(unread);
}
});
$scope.buffers = models.model.buffers; $scope.buffers = models.model.buffers;
$scope.activeBuffer = models.getActiveBuffer $scope.activeBuffer = models.getActiveBuffer
@ -480,9 +477,6 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
$scope.connect = function() { $scope.connect = function() {
connection.connect($scope.host, $scope.port, $scope.password, $scope.ssl); connection.connect($scope.host, $scope.port, $scope.password, $scope.ssl);
} }
$rootScope.getLines = function() {
connection.getLines($scope.lines);
}
/* Function gets called from bufferLineAdded code if user should be notified */ /* Function gets called from bufferLineAdded code if user should be notified */
$rootScope.createHighlight = function(buffer, message) { $rootScope.createHighlight = function(buffer, message) {
@ -510,7 +504,7 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
if (models.getActiveBuffer() == buffer) { if (models.getActiveBuffer() == buffer) {
return true; return true;
} }
return (parseInt(buffer.unread) || 0) > 0; return buffer.unread > 0;
} }
return true; return true;
}; };
@ -519,10 +513,10 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
// Find next buffer with activity and switch to it // Find next buffer with activity and switch to it
for(i in $scope.buffers) { for(i in $scope.buffers) {
var buffer = $scope.buffers[i]; var buffer = $scope.buffers[i];
if(buffer.notification) { if(buffer.notification > 0) {
$scope.setActiveBuffer(buffer.id); $scope.setActiveBuffer(buffer.id);
break; break;
}else if((parseInt(buffer.unread) || 0) > 0) { }else if(buffer.unread > 0) {
$scope.setActiveBuffer(buffer.id); $scope.setActiveBuffer(buffer.id);
break; break;
} }
@ -560,5 +554,6 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
return true; return true;
} }
}; };
}] }]
); );

Loading…
Cancel
Save