diff --git a/clientapp/helpers/xmppEventHandlers.js b/clientapp/helpers/xmppEventHandlers.js
index 78a4a39..cbdec08 100644
--- a/clientapp/helpers/xmppEventHandlers.js
+++ b/clientapp/helpers/xmppEventHandlers.js
@@ -4,7 +4,7 @@
var _ = require('underscore');
var async = require('async');
var crypto = require('crypto');
-var log = require('andlog');
+var bows = require('bows');
var uuid = require('node-uuid');
var HumanModel = require('human-model');
var Contact = require('../models/contact');
@@ -13,11 +13,16 @@ var Message = require('../models/message');
var Call = require('../models/call');
+var log = bows('Otalk');
+var ioLogIn = bows('<< in');
+var ioLogOut = bows('>> out');
+
+
var discoCapsQueue = async.queue(function (pres, cb) {
var jid = pres.from;
var caps = pres.caps;
- log.debug('Checking storage for ' + caps.ver);
+ log.info('Checking storage for ' + caps.ver);
var contact = me.getContact(jid);
var resource = null;
@@ -26,28 +31,26 @@ var discoCapsQueue = async.queue(function (pres, cb) {
}
app.storage.disco.get(caps.ver, function (err, existing) {
- log.debug(err, existing);
if (existing) {
- log.debug('Already found info for ' + caps.ver);
+ log.info('Already found info for ' + caps.ver);
if (resource) resource.discoInfo = existing;
return cb();
}
- log.debug('getting info for ' + caps.ver + ' from ' + jid);
+ log.info('getting info for ' + caps.ver + ' from ' + jid);
client.getDiscoInfo(jid, caps.node + '#' + caps.ver, function (err, result) {
- log.debug(caps.ver, err, result);
if (err) {
- log.debug('Couldnt get info for ' + caps.ver);
+ log.error('Couldnt get info for ' + caps.ver);
return cb();
}
if (client.verifyVerString(result.discoInfo, caps.hash, caps.ver)) {
- log.debug('Saving info for ' + caps.ver);
+ log.info('Saving info for ' + caps.ver);
var data = result.discoInfo.toJSON();
app.storage.disco.add(caps.ver, data, function () {
if (resource) resource.discoInfo = existing;
cb();
});
} else {
- log.debug('Couldnt verify info for ' + caps.ver + ' from ' + jid);
+ log.info('Couldnt verify info for ' + caps.ver + ' from ' + jid);
cb();
}
});
@@ -58,9 +61,10 @@ var discoCapsQueue = async.queue(function (pres, cb) {
module.exports = function (client, app) {
client.on('*', function (name, data) {
- log.debug(name, data);
- if (name === 'raw:outgoing') {
- log.debug(data.toString());
+ if (name === 'raw:incoming') {
+ ioLogIn.debug(data.toString());
+ } else if (name === 'raw:outgoing') {
+ ioLogOut.debug(data.toString());
}
});
@@ -93,7 +97,7 @@ module.exports = function (client, app) {
});
client.on('auth:failed', function () {
- log.debug('auth failed');
+ log.warning('auth failed');
window.location = '/login';
});
@@ -287,6 +291,13 @@ module.exports = function (client, app) {
}
});
+ client.on('groupchat:subject', function (msg) {
+ var contact = me.getContact(msg.from, msg.to);
+ if (contact) {
+ contact.subject = msg.subject;
+ }
+ });
+
client.on('replace', function (msg) {
msg = msg.toJSON();
msg.mid = msg.id;
@@ -336,7 +347,7 @@ module.exports = function (client, app) {
client.on('disco:caps', function (pres) {
if (pres.caps.hash) {
- log.debug('Caps from ' + pres.from + ' ver: ' + pres.caps.ver);
+ log.info('Caps from ' + pres.from + ' ver: ' + pres.caps.ver);
discoCapsQueue.push(pres);
}
});
diff --git a/clientapp/models/muc.js b/clientapp/models/muc.js
index 8c34e90..408a417 100644
--- a/clientapp/models/muc.js
+++ b/clientapp/models/muc.js
@@ -4,6 +4,7 @@
var _ = require('underscore');
var async = require('async');
var uuid = require('node-uuid');
+var htmlify = require('../helpers/htmlify');
var HumanModel = require('human-model');
var Resources = require('./resources');
var Messages = require('./messages');
@@ -25,6 +26,7 @@ module.exports = HumanModel.define({
jid: 'object'
},
session: {
+ subject: 'string',
activeContact: ['bool', true, false],
lastInteraction: 'data',
lastSentMessage: 'object',
@@ -47,6 +49,12 @@ module.exports = HumanModel.define({
return '';
}
},
+ displaySubject: {
+ deps: ['subject'],
+ fn: function () {
+ return htmlify.toHTML(this.subject);
+ }
+ },
hasUnread: {
deps: ['unreadCount'],
fn: function () {
diff --git a/clientapp/pages/chat.js b/clientapp/pages/chat.js
index 5031d8f..45f5979 100644
--- a/clientapp/pages/chat.js
+++ b/clientapp/pages/chat.js
@@ -36,10 +36,14 @@ module.exports = BasePage.extend(chatHelpers).extend({
},
textBindings: {
displayName: 'header .name',
- formattedTZO: 'header .tzo'
+ formattedTZO: 'header .tzo',
+ status: 'header .status'
},
classBindings: {
- onCall: '.messages'
+ chatState: 'header',
+ idle: 'header',
+ show: 'header',
+ onCall: '.conversation'
},
show: function (animation) {
BasePage.prototype.show.apply(this, [animation]);
@@ -104,10 +108,10 @@ module.exports = BasePage.extend(chatHelpers).extend({
});
this.scrollIfPinned();
},
- handleWindowResize: function () {
+ handleWindowResize: _.debounce(function () {
this.scrollIfPinned();
this.resizeInput();
- },
+ }),
handleKeyDown: function (e) {
if (e.which === 13 && !e.shiftKey) {
this.sendChat();
diff --git a/clientapp/pages/groupchat.js b/clientapp/pages/groupchat.js
index 81bd2d6..9de3db4 100644
--- a/clientapp/pages/groupchat.js
+++ b/clientapp/pages/groupchat.js
@@ -31,7 +31,8 @@ module.exports = BasePage.extend(chatHelpers).extend({
joined: '.controls'
},
textBindings: {
- displayName: 'header .name'
+ displayName: 'header .name',
+ subject: 'header .status'
},
show: function (animation) {
BasePage.prototype.show.apply(this, [animation]);
diff --git a/clientapp/templates.js b/clientapp/templates.js
index f282edf..c8ed69f 100644
--- a/clientapp/templates.js
+++ b/clientapp/templates.js
@@ -194,7 +194,7 @@ exports.misc.growlMessage = function anonymous(locals) {
exports.pages.chat = function anonymous(locals) {
var buf = [];
with (locals || {}) {
- buf.push('');
+ buf.push('');
}
return buf.join("");
};
@@ -203,7 +203,7 @@ exports.pages.chat = function anonymous(locals) {
exports.pages.groupchat = function anonymous(locals) {
var buf = [];
with (locals || {}) {
- buf.push('');
+ buf.push('');
}
return buf.join("");
};
diff --git a/clientapp/templates/pages/chat.jade b/clientapp/templates/pages/chat.jade
index 52ee2fe..e5bb7ab 100644
--- a/clientapp/templates/pages/chat.jade
+++ b/clientapp/templates/pages/chat.jade
@@ -1,8 +1,9 @@
section.page.chat
section.conversation
header
- img.avatar
h1.name
+ .status
+ .idleTime
.tzo
button.primary.small.call call
.activeCall
diff --git a/clientapp/templates/pages/groupchat.jade b/clientapp/templates/pages/groupchat.jade
index c38440c..be81614 100644
--- a/clientapp/templates/pages/groupchat.jade
+++ b/clientapp/templates/pages/groupchat.jade
@@ -1,10 +1,11 @@
section.page.chat
section.conversation
- header
+ header.online
h1.name
+ .status
.controls
- button.primary.joinRoom Join
- button.secondary.leaveRoom Leave
+ button.primary.small.joinRoom Join
+ button.secondary.small.leaveRoom Leave
ul.messages
.chatBox
form
diff --git a/package.json b/package.json
index afa925a..352acf3 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"url": "git@github.com:andyet/otalk.git"
},
"dependencies": {
- "andlog": "0.0.4",
+ "bows": "",
"async": "0.2.9",
"backbone": "1.0.0",
"express": "3.3.7",
@@ -22,7 +22,7 @@
"human-view": "1.2.0",
"templatizer": "0.1.2",
"underscore": "1.5.1",
- "stanza.io": "2.9.3",
+ "stanza.io": "2.9.4",
"notify.js": "0.0.3",
"wildemitter": "0.0.5",
"attachmediastream": "1.0.1",
diff --git a/public/css/otalk.css b/public/css/otalk.css
index 110d894..ac7626f 100644
--- a/public/css/otalk.css
+++ b/public/css/otalk.css
@@ -878,7 +878,8 @@ button.secondary:hover:not(:disabled) {
box-sizing: border-box;
}
.conversation header {
- padding: 5px;
+ padding: 0px;
+ padding-left: 8px;
border-bottom: 2px solid #eee;
position: fixed;
right: 0px;
@@ -889,6 +890,59 @@ button.secondary:hover:not(:disabled) {
box-sizing: border-box;
background: #f7f7f7;
}
+.conversation header.online:not(.idle):before,
+.conversation header.chat:before,
+.conversation header.dnd:before,
+.conversation header.away:before,
+.conversation header.xa:before {
+ content: '';
+ position: absolute;
+ top: 50%;
+ height: 8px;
+ width: 8px;
+ margin-top: -4px;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ -khtml-border-radius: 10px;
+ -o-border-radius: 10px;
+ -border-radius: 10px;
+ border-radius: 10px;
+}
+.conversation header.online:before,
+.conversation header.chat:before {
+ background: #43bb6e;
+}
+.conversation header.dnd:before {
+ background: #de0a32;
+}
+.conversation header.away:before,
+.conversation header.xa:before {
+ background: #f18902;
+}
+.conversation header.offline:not(:hover) .name {
+ color: #515151;
+}
+.conversation header.offline:not(:hover) .status {
+ color: #2f2f2f;
+}
+.conversation header.offline:not(:hover) .avatar {
+ opacity: 0.25;
+}
+.conversation header.composing:before {
+ animation: pulsate 1.5s infinite ease-in;
+ -webkit-animation: pulsate 1.5s infinite ease-in;
+ -moz-animation: pulsate 1.5s infinite ease-in;
+}
+.conversation header.paused:before {
+ background: #878787;
+}
+.conversation header.idle {
+ padding-right: 15px;
+}
+.conversation header.idle .name {
+ color: #878787;
+ max-width: 60%;
+}
.conversation header .controls {
float: right;
}
@@ -898,10 +952,13 @@ button.secondary:hover:not(:disabled) {
.conversation header .controls .joinRoom {
display: block;
}
-.conversation header .joined .joinRoom {
+.conversation header .controls button {
+ margin-top: 4px;
+}
+.conversation header .controls.joined .joinRoom {
display: none;
}
-.conversation header .joined .leaveRoom {
+.conversation header .controls.joined .leaveRoom {
display: block;
}
.conversation header .avatar {
@@ -924,17 +981,33 @@ button.secondary:hover:not(:disabled) {
float: left;
}
.conversation header .name {
- margin: 15px;
+ margin: 10px;
+ margin-left: 15px;
+ margin-right: 5px;
padding: 0px;
- margin-left: 45px;
font-size: 14px;
line-height: 14px;
max-width: 50%;
}
+.conversation header .status {
+ margin: 10px;
+ margin-left: 0px;
+ padding: 0px;
+ font-size: 14px;
+ line-height: 14px;
+ max-width: 75%;
+ float: left;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.conversation header .status:not(:empty):before {
+ content: '- ';
+}
.conversation header .tzo:not(:empty) {
position: absolute;
right: 15px;
- top: 28px;
+ top: 18px;
height: 20px;
margin-top: -10px;
padding: 0 5px;
@@ -944,15 +1017,18 @@ button.secondary:hover:not(:disabled) {
-o-border-radius: 3px;
-border-radius: 3px;
border-radius: 3px;
- text-transform: uppercase;
font-size: 12px;
font-weight: 800;
line-height: 20px;
color: #898989;
background: #eee;
}
+.conversation header .tzo:not(:empty):before {
+ content: 'Current Time: ';
+ font-weight: bold;
+}
.conversation header .call {
- margin-top: 9px;
+ margin-top: 4px;
text-transform: capitalize;
}
.conversation header .activeCall {
@@ -996,7 +1072,7 @@ button.secondary:hover:not(:disabled) {
position: absolute;
top: 0px;
bottom: 0px;
- padding-top: 55px;
+ padding-top: 35px;
padding-bottom: 55px;
width: 100%;
-moz-box-sizing: border-box;
diff --git a/public/css/pages/chat.styl b/public/css/pages/chat.styl
index b884c7e..3625fa9 100644
--- a/public/css/pages/chat.styl
+++ b/public/css/pages/chat.styl
@@ -16,7 +16,8 @@
borderbox()
header
- padding: 5px
+ padding: 0px
+ padding-left: 8px
border-bottom: 2px solid $gray-lighter
position: fixed
right: 0px
@@ -25,6 +26,56 @@
borderbox()
background: lighten($gray-light, 93%)
+ &.online:not(.idle), &.chat, &.dnd, &.away, &.xa
+ &:before
+ content: ''
+ position: absolute
+ top: 50%
+ height: 8px
+ width: 8px
+ margin-top: -4px
+ roundall(10px)
+
+ &.online,
+ &.chat
+ &:before
+ background: $green
+
+ &.dnd
+ &:before
+ background: $red
+
+ &.away,
+ &.xa
+ &:before
+ background: $orange
+
+ &.offline:not(:hover)
+ .name
+ color: darken($gray-light, 40%)
+
+ .status
+ color: darken($gray-light, 65%)
+
+ .avatar
+ opacity: .25
+
+ &.composing
+ &:before
+ animation: pulsate 1.5s infinite ease-in
+ -webkit-animation: pulsate 1.5s infinite ease-in
+ -moz-animation: pulsate 1.5s infinite ease-in
+
+ &.paused
+ &:before
+ background: $gray-light
+
+ &.idle
+ padding-right: 15px
+ .name
+ color: $gray-light
+ max-width: 60%
+
.controls
float: right
@@ -34,12 +85,15 @@
.joinRoom
display: block
- .joined
- .joinRoom
- display: none
+ button
+ margin-top: 4px
- .leaveRoom
- display: block
+ &.joined
+ .joinRoom
+ display: none
+
+ .leaveRoom
+ display: block
.avatar
margin-right: 5px
@@ -53,30 +107,49 @@
float: left
.name
- margin: 15px
+ margin: 10px
+ margin-left: 15px
+ margin-right: 5px
padding: 0px
- margin-left: 45px
font-size: $font-size-base
line-height: 14px
max-width: 50%
+ .status
+ margin: 10px
+ margin-left: 0px
+ padding: 0px
+ font-size: $font-size-base
+ line-height: 14px
+ max-width: 75%
+ float: left
+ overflow: hidden
+ text-overflow: ellipsis
+ white-space: nowrap
+
+ &:not(:empty):before
+ content: '- '
+
.tzo:not(:empty)
position: absolute
right: 15px
- top: 28px
+ top: 18px
height: 20px
margin-top: -10px
padding: 0 5px
roundall(3px)
- text-transform: uppercase
font-size: $font-size-small
font-weight: $font-weight-bold
line-height: 20px
color: lighten($gray, 30%)
background: $gray-lighter
+ &:before
+ content: 'Current Time: '
+ font-weight: bold
+
.call
- margin-top: 9px
+ margin-top: 4px
text-transform: capitalize
.activeCall
@@ -84,7 +157,7 @@
height: 0px
position: relative
top: 0px
-
+
.remote
position: absolute
top: 60px
@@ -121,7 +194,7 @@
position: absolute
top: 0px
bottom: 0px
- padding-top: 55px
+ padding-top: 35px
padding-bottom: 55px
width: 100%
borderbox()
diff --git a/public/x-manifest.cache b/public/x-manifest.cache
index 0cfff05..dcc967c 100644
--- a/public/x-manifest.cache
+++ b/public/x-manifest.cache
@@ -1,5 +1,5 @@
CACHE MANIFEST
-# 0.0.1 1387497051758
+# 0.0.1 1387522881010
CACHE:
/app.js