commit
4014a4a696
|
@ -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,7 +98,6 @@ input#sendMessage {
|
|||
height: 100%;
|
||||
min-width: 130px;
|
||||
overflow: auto;
|
||||
background: #282828;
|
||||
}
|
||||
.content {
|
||||
height: 100%;
|
||||
|
|
61
index.html
61
index.html
|
@ -16,6 +16,7 @@
|
|||
<script type="text/javascript" src="js/websockets.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/favico-0.3.0.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>
|
||||
</head>
|
||||
|
@ -28,10 +29,20 @@
|
|||
WeeChat web frontend
|
||||
</small>
|
||||
</h2>
|
||||
<div class="alert alert-info">WeeChat 0.4.2 or later is required</div>
|
||||
<div class="alert alert-danger" ng-show="errorMessage">
|
||||
<strong>Oh no!</strong> We cannot connect!
|
||||
</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">
|
||||
<div class="form-group">
|
||||
<label class="control-label" for="host">WeeChat hostname</label>
|
||||
|
@ -51,7 +62,7 @@
|
|||
<div class="form-group">
|
||||
<label class="control-label" for="proto">Encryption</label>
|
||||
<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 class="form-group">
|
||||
<label class="control-label" for="port">Lines</label>
|
||||
|
@ -60,16 +71,42 @@
|
|||
</div>
|
||||
<button class="btn btn-lg btn-primary" ng-click="connect()">Connect!</button>
|
||||
</form>
|
||||
|
||||
<h3>Instructions</h3>
|
||||
</div>
|
||||
</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:
|
||||
<pre>
|
||||
/set relay.network.password yourpassword
|
||||
/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.
|
||||
<h4>Encryption</h4>
|
||||
If you want to use encrypted session you first have to set up the relay using SSL
|
||||
</div>
|
||||
</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>
|
||||
$ mkdir -p ~/.weechat/ssl
|
||||
$ cd ~/.weechat/ssl
|
||||
|
@ -82,6 +119,11 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel
|
|||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content" ng-show="connected">
|
||||
<div id="sidebar">
|
||||
<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 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 }}">
|
||||
<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>
|
||||
</a>
|
||||
</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>
|
||||
</td>
|
||||
<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-show="metadata.visible">
|
||||
|
|
File diff suppressed because one or more lines are too long
17
js/models.js
17
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 = false;
|
||||
var unread = '';
|
||||
var lastSeen = -2;
|
||||
var active = false
|
||||
var notification = 0
|
||||
var unread = 0
|
||||
var lastSeen = -2
|
||||
|
||||
/*
|
||||
* Adds a line to this buffer
|
||||
|
@ -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': {} }
|
||||
|
||||
|
@ -161,11 +165,12 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) {
|
|||
}
|
||||
});
|
||||
|
||||
activeBuffer.notification = false;
|
||||
activeBuffer.active = true;
|
||||
activeBuffer.unread = '';
|
||||
activeBuffer.unread = 0;
|
||||
activeBuffer.notification = 0;
|
||||
|
||||
$rootScope.$emit('activeBufferChanged');
|
||||
$rootScope.$emit('notificationChanged');
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -55,31 +55,46 @@ plugins.service('plugins', ['userPlugins', '$sce', function(userPlugins, $sce)
|
|||
*/
|
||||
var contentForMessage = function(message) {
|
||||
|
||||
var content = [];
|
||||
message.metadata = [];
|
||||
for (var i = 0; i < plugins.length; i++) {
|
||||
|
||||
var nsfw = false;
|
||||
var visible = true;
|
||||
if (message.match(nsfwRegexp)) {
|
||||
if (message.text.match(nsfwRegexp)) {
|
||||
var nsfw = true;
|
||||
var visible = false;
|
||||
}
|
||||
|
||||
var pluginContent = plugins[i].contentForMessage(message);
|
||||
var pluginContent = plugins[i].contentForMessage(message.text);
|
||||
if (pluginContent) {
|
||||
var pluginContent = {'visible': visible,
|
||||
'content': $sce.trustAsHtml(pluginContent),
|
||||
'nsfw': nsfw,
|
||||
'name': plugins[i].name }
|
||||
|
||||
content.push(pluginContent);
|
||||
message.metadata.push(pluginContent);
|
||||
|
||||
|
||||
if (plugins[i].exclusive) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return content;
|
||||
|
||||
/* Replace all URLs with hyperlinks */
|
||||
|
||||
var urlRegexp = RegExp(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/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 {
|
||||
|
@ -124,16 +139,6 @@ plugins.factory('userPlugins', function() {
|
|||
});
|
||||
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 url = message.match(urlRegexp);
|
||||
|
@ -149,6 +154,6 @@ plugins.factory('userPlugins', function() {
|
|||
imagePlugin.name = 'image';
|
||||
|
||||
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
|
||||
if(message.displayed) {
|
||||
var buffer = models.getBuffer(message.buffer);
|
||||
message.metadata = plugins.PluginManager.contentForMessage(message.text);
|
||||
message = plugins.PluginManager.contentForMessage(message);
|
||||
buffer.addLine(message);
|
||||
|
||||
if (buffer.active) {
|
||||
|
@ -200,16 +200,14 @@ 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++;
|
||||
}
|
||||
$rootScope.$emit('notificationChanged');
|
||||
}
|
||||
|
||||
if(message.highlight || _.contains(message.tags, 'notify_private') ) {
|
||||
buffer.notification++;
|
||||
$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'];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
|
@ -276,7 +262,6 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi
|
|||
}
|
||||
|
||||
var eventHandlers = {
|
||||
bufinfo: handleBufferInfo,
|
||||
lineinfo: handleLineInfo,
|
||||
_buffer_closing: handleBufferClosing,
|
||||
_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();
|
||||
var websocket = null;
|
||||
|
||||
|
@ -329,6 +314,7 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', 'handlers', 'colors',
|
|||
websocket.binaryType = "arraybuffer"
|
||||
|
||||
websocket.onopen = function (evt) {
|
||||
$log.info("Connected to relay");
|
||||
doSend(WeeChatProtocol.formatInit({
|
||||
password: passwd,
|
||||
compression: 'off'
|
||||
|
@ -336,7 +322,8 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', 'handlers', 'colors',
|
|||
doSendWithCallback(WeeChatProtocol.formatHdata({
|
||||
path: 'buffer:gui_buffers(*)',
|
||||
keys: ['number,full_name,short_name,title']
|
||||
})).then(function(hdata) {
|
||||
})).then(function(message) {
|
||||
$log.info("Parsing bufinfo");
|
||||
var bufferInfos = message['objects'][0]['content'];
|
||||
// buffers objects
|
||||
for (var i = 0; i < bufferInfos.length ; i++) {
|
||||
|
@ -347,16 +334,19 @@ weechat.factory('connection', ['$q', '$rootScope', '$log', 'handlers', 'colors',
|
|||
models.setActiveBuffer(buffer.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Request latest buffer lines for each buffer
|
||||
$rootScope.getLines();
|
||||
|
||||
});
|
||||
doSend(WeeChatProtocol.formatSync({}));
|
||||
|
||||
$log.info("Connected to relay");
|
||||
$rootScope.connected = true;
|
||||
$rootScope.$apply();
|
||||
}).then(function() {
|
||||
$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({}));
|
||||
$log.info("Synced");
|
||||
});
|
||||
}
|
||||
|
||||
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 {
|
||||
send: doSend,
|
||||
getLines: getLines,
|
||||
connect: connect,
|
||||
sendMessage: sendMessage
|
||||
}
|
||||
|
@ -428,13 +409,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 (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.activeBuffer = models.getActiveBuffer
|
||||
|
@ -480,9 +477,6 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
|
|||
$scope.connect = function() {
|
||||
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 */
|
||||
$rootScope.createHighlight = function(buffer, message) {
|
||||
|
@ -510,7 +504,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;
|
||||
};
|
||||
|
@ -519,10 +513,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(buffer.notification) {
|
||||
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;
|
||||
}
|
||||
|
@ -560,5 +554,6 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout',
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}]
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue