189:3b3181b49427
Anton Shestakov <av6@dwimlabs.net>, Tue, 24 May 2016 10:58:11 +0800
contacts: show a border on the left for active contacts

next change 193:3144980ad4b8
previous change 187:f8595ced3022

js/index.js

Permissions: -rw-r--r--

Other formats: Feeds:
// Generated by CoffeeScript 1.10.0
(function() {
var $form, _saveCapsCache, _saveSettings, connectfn, enableCSI, enableCarbons, getChat, getClientInfo, getContact, getContactProfile, getServerInfo, getServerVersion, getStamp, getText, loadCapsCache, loadSettings, onChatMessage, onChatState, onConnected, onDisconnected, onGetLast, onGetTime, onGetVersion, onPing, onPresence, onWebRTC, saveCapsCache, saveSettings, sendMessage,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
Strophe.addNamespace('CAPS', 'http://jabber.org/protocol/caps');
Strophe.addNamespace('CARBONS', 'urn:xmpp:carbons:2');
Strophe.addNamespace('CHATSTATES', 'http://jabber.org/protocol/chatstates');
Strophe.addNamespace('CSI', 'urn:xmpp:csi:0');
Strophe.addNamespace('DELAY', 'urn:xmpp:delay');
Strophe.addNamespace('FORWARD', 'urn:xmpp:forward:0');
Strophe.addNamespace('LAST', 'jabber:iq:last');
Strophe.addNamespace('MESSAGE_CORRECT', 'urn:xmpp:message-correct:0');
Strophe.addNamespace('PRIVATE', 'jabber:iq:private');
Strophe.addNamespace('TIME', 'urn:xmpp:time');
window.contacts = new Tram.Contacts();
window.contactsApp = new Tram.ContactsApp({
el: $('[data-app="contacts"]'),
collection: contacts
});
window.calls = new Tram.Calls();
window.callsApp = new Tram.CallsApp({
el: $('[data-app="calls"]'),
collection: calls
});
window.settings = new Tram.ClientSettings();
window.serverInfo = new Tram.ServerInfo();
window.clientState = new Tram.ClientState();
window.faviconApp = new Tram.FaviconApp({
model: clientState
});
window.sidebarApp = new Tram.SidebarApp({
el: $('[data-app="sidebar"]'),
model: clientState
});
window.progressApp = new Tram.ProgressApp({
el: $('[data-app="progress"]'),
model: clientState
});
window.chats = {};
window.capscache = {};
window.vcardcache = {};
contacts.on('change:show', function(model) {
if (model.get('type') === 'self') {
return clientState.set('show', model.get('show'));
}
});
contacts.on('change:chatstate/self', function(model, cs) {
var msg, ref, ref1;
if (settings.get('chatstates') && (ref = Strophe.NS.CHATSTATES, indexOf.call((ref1 = model != null ? model.get('features') : void 0) != null ? ref1 : [], ref) >= 0)) {
msg = $msg({
to: model.get('jid'),
from: X.conn.jid,
type: 'chat'
}).c(cs, {
xmlns: Strophe.NS.CHATSTATES
});
return X.conn.send(msg.tree());
}
});
contacts.on('change:presence', function(model) {
var c, dupes, offline;
dupes = contacts.where({
bjid: model.get('bjid')
});
offline = (function() {
var i, len, results;
results = [];
for (i = 0, len = dupes.length; i < len; i++) {
c = dupes[i];
if (c.get('presence') === 'unavailable') {
results.push(c);
}
}
return results;
})();
if (offline.length === dupes.length) {
offline = (function() {
var i, len, results;
results = [];
for (i = 0, len = offline.length; i < len; i++) {
c = offline[i];
if (c.get('jid') !== model.get('jid')) {
results.push(c);
}
}
return results;
})();
}
return contacts.remove(offline);
});
clientState.on('action/show', function(show, status) {
return X.sendPresence({
show: show,
status: status,
priority: 1
});
});
clientState.on('action/disconnect', function() {
return X.disconnect('Logged out');
});
clientState.on('change:contact', function() {
var $logs, contact, previous;
previous = clientState.previous('contact');
if (previous != null) {
previous.set('chatstate/self', 'inactive');
}
if (previous != null) {
previous.unset('active');
}
contact = clientState.get('contact');
if (contact != null) {
contact.set('chatstate/self', 'active');
}
if (contact != null) {
contact.set('active', true);
}
$logs = $('[data-app="logs"]');
$logs.children().detach();
$logs.append(contact.chat.render().el);
return $('[data-form="send"]').toggleClass('uk-hidden', contact == null);
});
clientState.on('change:csi', function() {
var state;
state = clientState.get('csi');
return X.conn.send($build(state, {
xmlns: Strophe.NS.CSI
}).tree());
});
onConnected = function() {
var dCaps, dCarbons, dInfo, dRoster, dSettings, dVersion;
X.conn.addHandler(onPresence, null, 'presence');
X.conn.addHandler(onChatMessage, null, 'message', 'chat');
X.conn.addHandler(onChatState, Strophe.NS.CHATSTATES, 'message');
X.conn.addHandler(onWebRTC, Tram.NS.WEBRTC, 'message', 'chat');
X.conn.addHandler(onGetLast, Strophe.NS.LAST, 'iq', 'get');
X.conn.addHandler(onGetTime, Strophe.NS.TIME, 'iq', 'get');
X.conn.addHandler(onGetVersion, Strophe.NS.VERSION, 'iq', 'get');
X.conn.ping.addPingHandler(onPing);
X.conn.disco.addIdentity('client', 'web', Tram.info.client);
X.conn.disco.addFeature(Strophe.NS.CAPS);
X.conn.disco.addFeature(Strophe.NS.CARBONS);
X.conn.disco.addFeature(Strophe.NS.CHATSTATES);
X.conn.disco.addFeature(Strophe.NS.CSI);
X.conn.disco.addFeature(Strophe.NS.DISCO_INFO);
X.conn.disco.addFeature(Strophe.NS.LAST);
X.conn.disco.addFeature(Strophe.NS.MESSAGE_CORRECT);
X.conn.disco.addFeature(Strophe.NS.PING);
X.conn.disco.addFeature(Strophe.NS.PRIVATE);
X.conn.disco.addFeature(Strophe.NS.TIME);
X.conn.disco.addFeature(Strophe.NS.VERSION);
X.conn.disco.addFeature(Strophe.NS.XHTML_IM);
X.conn.disco.addFeature(Tram.NS.WEBRTC);
dSettings = $.Deferred();
dCaps = $.Deferred();
dVersion = $.Deferred();
dInfo = $.Deferred();
dCarbons = $.Deferred();
dRoster = $.Deferred();
loadSettings(dSettings.resolve, dSettings.reject);
loadCapsCache(dCaps.resolve, dCaps.reject);
getServerVersion(dVersion.resolve, dVersion.reject);
X.conn.roster.get(dRoster.resolve);
$.when(dCaps).always(function() {
return getServerInfo(dInfo.resolve, dInfo.reject);
});
$.when(dInfo).always(function() {
var failcb, hasCSI, okcb, ref, ref1;
if (ref = Strophe.NS.CARBONS, indexOf.call(serverInfo.get('features'), ref) >= 0) {
okcb = function() {
serverInfo.set('carbons', true);
return dCarbons.resolve();
};
failcb = function(stanza) {
serverInfo.set('carbons', false);
return dCarbons.reject();
};
enableCarbons(okcb, failcb);
} else {
dCarbons.reject();
}
hasCSI = ((ref1 = X.conn.features) != null ? ref1.getElementsByTagNameNS(Strophe.NS.CSI, 'csi')[0] : void 0) != null;
serverInfo.set('csi', hasCSI);
if (hasCSI) {
return enableCSI();
}
});
return $.when(dSettings, dVersion, dInfo, dRoster, dCarbons).always(function() {
return X.sendPresence({
status: 'Online',
priority: 1
});
});
};
onDisconnected = function() {
return location.reload();
};
getStamp = function(stanza) {
var delay, ref;
delay = stanza.getElementsByTagNameNS(Strophe.NS.DELAY, 'delay')[0];
return new Date((ref = delay != null ? delay.getAttribute('stamp') : void 0) != null ? ref : Date.now());
};
getText = function(el) {
var i, len, node, ref, str;
if (!el) {
return null;
}
str = '';
if (el.childNodes.length === 0 && el.nodeType === Strophe.ElementType.TEXT) {
str += el.nodeValue;
}
ref = el.childNodes;
for (i = 0, len = ref.length; i < len; i++) {
node = ref[i];
if (node.nodeType === Strophe.ElementType.TEXT) {
str += node.nodeValue;
}
}
return str;
};
getServerVersion = function(doneCallback, failCallback) {
var failcb, iq, okcb;
iq = $iq({
type: 'get',
id: X.conn.getUniqueId('version'),
to: X.conn.domain
}).c('query', {
xmlns: Strophe.NS.VERSION
});
okcb = function(stanza) {
serverInfo.set({
name: getText(stanza.getElementsByTagName('name')[0]),
version: getText(stanza.getElementsByTagName('version')[0]),
os: getText(stanza.getElementsByTagName('os')[0])
});
return typeof doneCallback === "function" ? doneCallback() : void 0;
};
failcb = function(stanza) {
console.error("couldn't get version", stanza != null ? stanza.innerHTML : void 0);
return typeof failCallback === "function" ? failCallback() : void 0;
};
return X.conn.sendIQ(iq.tree(), okcb, failcb, Tram.config.iqTimeout);
};
enableCarbons = function(doneCallback, failCallback) {
var failcb, iq, okcb;
iq = $iq({
type: 'set',
id: X.conn.getUniqueId('enable')
}).c('enable', {
xmlns: Strophe.NS.CARBONS
});
okcb = function(stanza) {
serverInfo.set('carbons', true);
return typeof doneCallback === "function" ? doneCallback() : void 0;
};
failcb = function(stanza) {
serverInfo.set('carbons', false);
return typeof failCallback === "function" ? failCallback() : void 0;
};
return X.conn.sendIQ(iq.tree(), okcb, failcb, Tram.config.iqTimeout);
};
enableCSI = function() {
var csiTimer;
csiTimer = null;
$(window).on('focus.tram', function() {
if (csiTimer != null) {
window.clearTimeout(csiTimer);
csiTimer = null;
}
return clientState.set('csi', 'active');
});
return $(window).on('blur.tram', function() {
if (csiTimer != null) {
window.clearTimeout(csiTimer);
}
return csiTimer = window.setTimeout(function() {
return clientState.set('csi', 'inactive');
}, Tram.config.inactiveTime);
});
};
loadSettings = function(doneCallback, failCallback) {
var failcb, iq, okcb;
iq = $iq({
type: 'get',
id: X.conn.getUniqueId('settings')
}).c('query', {
xmlns: Strophe.NS.PRIVATE
}).c('settings', {
xmlns: Tram.NS.PRIVATE
});
okcb = function(stanza) {
var data, el, error;
el = stanza.getElementsByTagName('settings')[0];
if ((el != null ? el.firstChild : void 0) != null) {
try {
data = JSON.parse(el.firstChild.nodeValue);
} catch (error) {
if (typeof failCallback === "function") {
failCallback();
}
return;
}
}
if (data != null) {
settings.set(data);
}
return typeof doneCallback === "function" ? doneCallback() : void 0;
};
failcb = function(stanza) {
console.error("couldn't load settings", stanza);
return typeof failCallback === "function" ? failCallback() : void 0;
};
return X.conn.sendIQ(iq.tree(), okcb, failcb, Tram.config.iqTimeout);
};
_saveSettings = function(doneCallback, failCallback) {
var failcb, iq, okcb, payload;
payload = JSON.stringify(settings.toJSON());
iq = $iq({
type: 'set',
id: X.conn.getUniqueId('settings')
}).c('query', {
xmlns: Strophe.NS.PRIVATE
}).c('settings', {
xmlns: Tram.NS.PRIVATE
}).t(payload);
okcb = function(stanza) {
return typeof doneCallback === "function" ? doneCallback() : void 0;
};
failcb = function(stanza) {
console.warn("couldn't save settings", stanza);
return typeof failCallback === "function" ? failCallback() : void 0;
};
return X.conn.sendIQ(iq.tree(), okcb, failcb, Tram.config.iqTimeout);
};
saveSettings = _(_saveSettings).debounce(1000);
loadCapsCache = function(doneCallback, failCallback) {
var failcb, iq, okcb;
iq = $iq({
type: 'get',
id: X.conn.getUniqueId('capscache')
}).c('query', {
xmlns: Strophe.NS.PRIVATE
}).c('capscache', {
xmlns: Tram.NS.PRIVATE
});
okcb = function(stanza) {
var data, el, error;
el = stanza.getElementsByTagName('capscache')[0];
if ((el != null ? el.firstChild : void 0) != null) {
try {
data = JSON.parse(el.firstChild.nodeValue);
} catch (error) {
if (typeof failCallback === "function") {
failCallback();
}
return;
}
}
if (data != null) {
_(capscache).defaults(data);
}
return typeof doneCallback === "function" ? doneCallback() : void 0;
};
failcb = function(stanza) {
console.error("couldn't load caps cache", stanza);
return typeof failCallback === "function" ? failCallback() : void 0;
};
return X.conn.sendIQ(iq.tree(), okcb, failcb, Tram.config.iqTimeout);
};
_saveCapsCache = function(doneCallback, failCallback) {
var failcb, iq, okcb, payload;
payload = JSON.stringify(capscache);
iq = $iq({
type: 'set',
id: X.conn.getUniqueId('capscache')
}).c('query', {
xmlns: Strophe.NS.PRIVATE
}).c('capscache', {
xmlns: Tram.NS.PRIVATE
}).t(payload);
okcb = function(stanza) {
return typeof doneCallback === "function" ? doneCallback() : void 0;
};
failcb = function(stanza) {
console.warn("couldn't save caps cache", stanza);
return typeof failCallback === "function" ? failCallback() : void 0;
};
return X.conn.sendIQ(iq.tree(), okcb, failcb, Tram.config.iqTimeout);
};
saveCapsCache = _(_saveCapsCache).debounce(1000);
onGetLast = function(stanza) {
var from, id, iq;
id = stanza.getAttribute('id');
from = stanza.getAttribute('from');
iq = $iq({
to: from,
type: 'result',
id: id
}).c('query', {
xmlns: Strophe.NS.LAST,
seconds: '0'
});
X.conn.send(iq.tree());
return true;
};
onGetTime = function(stanza) {
var from, id, iq, now;
now = moment();
id = stanza.getAttribute('id');
from = stanza.getAttribute('from');
iq = $iq({
to: from,
type: 'result',
id: id
}).c('time', {
xmlns: Strophe.NS.TIME
}).c('tzo').t(now.format('Z')).up().c('utc').t(now.toISOString());
X.conn.send(iq.tree());
return true;
};
onGetVersion = function(stanza) {
var from, id, iq;
id = stanza.getAttribute('id');
from = stanza.getAttribute('from');
iq = $iq({
to: from,
type: 'result',
id: id
}).c('query', {
xmlns: Strophe.NS.VERSION
}).c('name').t(Tram.info.client).up().c('version').t(Tram.info.version);
X.conn.send(iq.tree());
return true;
};
onPing = function(stanza) {
X.conn.ping.pong(stanza);
return true;
};
getChat = function(jid) {
return chats[jid] != null ? chats[jid] : chats[jid] = new Tram.LogApp({
collection: new Tram.Messages()
});
};
getContact = function(from, node, ver) {
var bjid, contact, self;
contact = contacts.get(from);
if (contact != null) {
return contact;
}
self = from === X.conn.jid;
if (self) {
contacts.each(function(model) {
return model.set('type', 'contact');
});
}
bjid = Strophe.getBareJidFromJid(from);
contact = contacts.add({
jid: from,
bjid: bjid,
type: self ? 'self' : 'contact'
});
contact.chat = getChat(bjid);
contact.on('action/chat', function() {
return clientState.set('contact', contact);
});
contact.on('action/authorize', function() {
return X.conn.roster.authorize(contact.get('bjid'));
});
contact.on('action/unauthorize', function() {
X.conn.roster.unauthorize(contact.get('bjid'));
return contacts.remove(contact);
});
contact.on('action/remove', function() {
if (X.conn.roster.findItem(contact.get('bjid'))) {
return X.conn.roster.remove(contact.get('bjid'), function() {
return contacts.remove(contact);
});
} else {
return contacts.remove(contact);
}
});
contact.w = new Tram.WebRTCInterface(contact);
contact.on('action/call', function(media) {
contact.set('callstate', 'outgoing');
return contact.w.init(true, {
audio: indexOf.call(media, 'a') >= 0,
video: indexOf.call(media, 'v') >= 0
});
});
contact.on('action/accept', function(media) {
return contact.w.init(false, {
audio: indexOf.call(media, 'a') >= 0,
video: indexOf.call(media, 'v') >= 0
});
});
contact.on('action/decline action/hangup', function() {
contact.w.sendIntent('terminate');
contact.w.disconnect();
return contact.unset('callstate');
});
getContactProfile(contact);
if (Strophe.getResourceFromJid(from) != null) {
getClientInfo(contact, node, ver);
}
return contact;
};
getContactProfile = function(contact) {
var bjid, data, failcb, okcb;
bjid = contact.get('bjid');
if (bjid === Strophe.getBareJidFromJid(X.conn.jid)) {
bjid = null;
}
if (vcardcache[bjid] != null) {
data = vcardcache[bjid];
contact.set(data);
if (data.avatar == null) {
contact.unset('avatar');
}
return;
}
okcb = function(stanza) {
var avatar, vcard;
vcard = stanza.getElementsByTagNameNS(Strophe.NS.VCARD, 'vCard')[0];
if (vcard == null) {
console.warn("no vcard in response", stanza);
return;
}
data = {
nickname: getText(vcard.querySelector('NICKNAME')),
fullname: getText(vcard.querySelector('FN')),
firstname: getText(vcard.querySelector('N > GIVEN')),
lastname: getText(vcard.querySelector('N > FAMILY'))
};
avatar = {
mime: getText(vcard.querySelector('PHOTO > TYPE')),
data: getText(vcard.querySelector('PHOTO > BINVAL'))
};
if (avatar.mime && avatar.data) {
data.avatar = avatar;
}
vcardcache[bjid] = data;
contact.set(data);
if (data.avatar == null) {
return contact.unset('avatar');
}
};
failcb = function(stanza) {
return console.warn("couldn't get vcard", stanza);
};
return X.conn.vcard.get(okcb, bjid, failcb);
};
getClientInfo = function(contact, node, ver) {
var clientId, failcb, jid, okcb;
jid = contact.get('jid');
if ((node != null) && (ver != null)) {
clientId = node + "#" + ver;
if (capscache[clientId] != null) {
return contact.set('features', capscache[clientId]);
}
}
okcb = function(stanza) {
var el, features;
features = (function() {
var i, len, ref, results;
ref = stanza.getElementsByTagName('feature');
results = [];
for (i = 0, len = ref.length; i < len; i++) {
el = ref[i];
results.push(el.getAttribute('var'));
}
return results;
})();
contact.set('features', features);
if (clientId != null) {
capscache[clientId] = features;
return saveCapsCache();
}
};
failcb = function(stanza) {
return console.warn("couldn't get client info", stanza);
};
return X.conn.disco.info(jid, clientId, okcb, failcb, Tram.config.iqTimeout);
};
getServerInfo = function(doneCallback, failCallback) {
var caps, failcb, node, okcb, serverId, ver;
caps = X.conn.features.getElementsByTagNameNS(Strophe.NS.CAPS, 'c')[0];
node = caps != null ? caps.getAttribute('node') : void 0;
ver = caps != null ? caps.getAttribute('ver') : void 0;
if ((node != null) && (ver != null)) {
serverId = node + "#" + ver;
if (capscache[serverId] != null) {
serverInfo.set('features', capscache[serverId]);
if (typeof doneCallback === "function") {
doneCallback();
}
return;
}
}
okcb = function(stanza) {
var el, features;
features = (function() {
var i, len, ref, results;
ref = stanza.getElementsByTagName('feature');
results = [];
for (i = 0, len = ref.length; i < len; i++) {
el = ref[i];
results.push(el.getAttribute('var'));
}
return results;
})();
serverInfo.set('features', features);
capscache[serverId] = features;
return typeof doneCallback === "function" ? doneCallback() : void 0;
};
failcb = function(stanza) {
console.warn("couldn't get server info", stanza);
return typeof failCallback === "function" ? failCallback() : void 0;
};
return X.conn.disco.info(X.conn.domain, serverId, okcb, failcb, Tram.config.iqTimeout);
};
onPresence = function(stanza) {
var caps, contact, from, node, priority, ref, show, stamp, status, type, ver;
type = (ref = stanza.getAttribute('type')) != null ? ref : 'available';
from = stanza.getAttribute('from');
switch (type) {
case 'unsubscribe':
X.conn.roster.unauthorize(from);
return true;
case 'subscribed':
X.conn.roster.subscribe(from);
return true;
case 'unsubscribed':
X.conn.roster.unsubscribe(from);
return true;
case 'error':
console.error('got <presence type="error">', stanza);
return true;
}
caps = stanza.getElementsByTagNameNS(Strophe.NS.CAPS, 'c')[0];
ver = caps != null ? caps.getAttribute('ver') : void 0;
node = caps != null ? caps.getAttribute('node') : void 0;
contact = getContact(from, node, ver);
show = getText(stanza.getElementsByTagName('show')[0]);
status = getText(stanza.getElementsByTagName('status')[0]);
priority = getText(stanza.getElementsByTagName('priority')[0]);
switch (type) {
case 'available':
if (show == null) {
show = 'online';
}
if (priority == null) {
priority = '0';
}
break;
case 'unavailable':
show = 'offline';
priority = '0';
}
contact.set({
presence: type,
show: show,
status: status,
priority: priority
});
if (type === 'unavailable') {
contact.w.disconnect();
}
if ((type === 'available' || type === 'unavailable') && contact.get('type') !== 'self') {
stamp = getStamp(stanza);
contact.chat.collection.add({
id: stanza.getAttribute('id'),
type: 'presence',
cls: 'presence',
from: from,
stamp: stamp,
contact: contact,
presence: type,
show: show,
status: status,
priority: priority,
text: status != null ? status : "is now " + show
});
}
return true;
};
onChatMessage = function(stanza) {
var body, carbon, chat, cls, contact, forwarded, from, fromSelf, html, id, message, msg, received, replace, rid, sent, stamp, subject, text, thread, to, type, xhtml;
sent = stanza.getElementsByTagNameNS(Strophe.NS.CARBONS, 'sent')[0];
received = stanza.getElementsByTagNameNS(Strophe.NS.CARBONS, 'received')[0];
carbon = (sent != null) || (received != null);
if (sent != null) {
forwarded = sent.getElementsByTagNameNS(Strophe.NS.FORWARD, 'forwarded')[0];
} else if (received != null) {
forwarded = received.getElementsByTagNameNS(Strophe.NS.FORWARD, 'forwarded')[0];
}
if (forwarded != null) {
message = forwarded.getElementsByTagName('message')[0];
if (carbon) {
onChatState(message);
}
} else {
message = stanza;
}
text = getText(message.getElementsByTagName('body')[0]);
xhtml = message.getElementsByTagNameNS(Strophe.NS.XHTML_IM, 'html')[0];
if (!(text || xhtml)) {
return true;
}
id = message.getAttribute('id');
to = message.getAttribute('to');
from = message.getAttribute('from');
type = message.getAttribute('type');
thread = getText(message.getElementsByTagName('thread')[0]);
subject = getText(message.getElementsByTagName('subject')[0]);
cls = type;
stamp = getStamp(stanza);
contact = getContact(from);
fromSelf = contact.get('bjid') === Strophe.getBareJidFromJid(X.conn.jid);
if ((xhtml != null) && (fromSelf || X.conn.roster.findItem(contact.get('bjid')))) {
body = xhtml.getElementsByTagNameNS(Strophe.NS.XHTML, 'body')[0];
html = Strophe.createHtml(body).innerHTML;
}
if ((forwarded != null) && fromSelf) {
chat = getContact(to).chat;
cls = 'self';
} else {
chat = contact.chat;
}
replace = stanza.getElementsByTagNameNS(Strophe.NS.MESSAGE_CORRECT, 'replace')[0];
rid = replace != null ? replace.getAttribute('id') : void 0;
if (rid != null) {
msg = chat.collection.get(rid);
if ((msg != null) && msg.get('from') === from) {
msg.set({
id: id,
corrected: true,
carbon: carbon,
thread: thread,
subject: subject,
text: text,
html: html
});
return true;
}
}
chat.collection.add({
id: id,
type: type,
cls: cls,
to: to,
from: from,
contact: contact,
stamp: stamp,
carbon: carbon,
thread: thread,
subject: subject,
text: text,
html: html
});
return true;
};
onChatState = function(stanza) {
var contact, delay, elements, from;
delay = stanza.getElementsByTagNameNS(Strophe.NS.DELAY, 'delay')[0];
if (delay != null) {
return true;
}
from = stanza.getAttribute('from');
contact = getContact(from);
elements = stanza.getElementsByTagNameNS(Strophe.NS.CHATSTATES, '*');
if (elements[0] != null) {
contact.set('chatstate', elements[0].tagName.toLowerCase());
}
return true;
};
onWebRTC = function(stanza) {
var contact, from, intent, payload, stamp;
from = stanza.getAttribute('from');
contact = getContact(from);
intent = stanza.getElementsByTagNameNS(Tram.NS.WEBRTC, 'intent')[0];
payload = stanza.getElementsByTagNameNS(Tram.NS.WEBRTC, 'payload')[0];
stamp = getStamp(stanza);
if (intent != null) {
switch (getText(intent)) {
case 'initiate':
contact.set('callstate', 'incoming');
contact.chat.collection.add({
id: stanza.getAttribute('id'),
type: 'call',
cls: 'call',
from: from,
stamp: stamp,
contact: contact,
text: 'incoming call'
});
break;
case 'terminate':
contact.w.disconnect();
contact.unset('callstate');
}
}
if (payload != null) {
contact.w.onPayload(stanza);
}
return true;
};
window.X = new Tram.XMPPInterface();
X.on('connecting', function() {
return connForm.unset('auth-errors');
});
X.on('authfail', function() {
return connForm.set('auth-errors', ['Invalid username or password.']);
});
X.on('disconnected', function() {
$('[data-step="login"]').removeClass('uk-hidden');
$('[data-step="main"]').addClass('uk-hidden');
return onDisconnected();
});
X.on('connected attached', function() {
$('[data-step="login"]').addClass('uk-hidden');
$('[data-step="main"]').removeClass('uk-hidden');
return onConnected();
});
X.on('status', function(status) {
switch (status) {
case Strophe.Status.CONNECTING:
return clientState.set('progress', 0);
case Strophe.Status.CONNECTED:
return clientState.set('progress', 100);
default:
return clientState.unset('progress');
}
});
$(window).on('beforeunload unload', function() {
return X.disconnect('Window closed');
});
window.connForm = new Tram.ConnectionForm();
connectfn = function() {
if (connForm.isValid()) {
return X.connect(connForm.get('username').trim(), connForm.get('password'));
}
};
$form = $('[data-form="connect"]');
$form.streamline();
window.connRivet = rivets.bind($form, {
form: connForm,
connect: connectfn
});
sendMessage = function() {
var contact, msg, ref, ref1, text;
text = $('#msg').val();
if (text !== '' && clientState.has('contact')) {
contact = clientState.get('contact');
msg = $msg({
to: contact.get('jid'),
from: X.conn.jid,
type: 'chat'
}).c('body').t(text).up();
if (settings.get('chatstates') && (ref = Strophe.NS.CHATSTATES, indexOf.call((ref1 = contact.get('features')) != null ? ref1 : [], ref) >= 0)) {
msg.c('active', {
xmlns: Strophe.NS.CHATSTATES
});
contact.set('chatstate/self', 'active', {
silent: true
});
}
X.conn.send(msg.tree());
contact.chat.collection.add({
type: 'chat',
cls: 'self',
from: X.conn.jid,
to: contact.get('jid'),
stamp: new Date(),
contact: contacts.findWhere({
type: 'self'
}),
text: text
});
return $('#msg').val('');
}
};
$('body').on('dragover dragenter', function(event) {
event.stopPropagation();
return event.preventDefault();
});
$('body').on('drop', function(event) {
event.stopPropagation();
return event.preventDefault();
});
$('[data-send-button]').on('click', sendMessage);
$('#msg').on('keypress', function(e) {
var ref;
if (e.keyCode === 13) {
return sendMessage();
} else {
return (ref = clientState.get('contact')) != null ? ref.set('chatstate/self', 'composing') : void 0;
}
});
$('#msg').on('blur', function() {
var ref, ref1;
if (((ref = clientState.get('contact')) != null ? ref.get('chatstate/self') : void 0) === 'composing') {
return (ref1 = clientState.get('contact')) != null ? ref1.set('chatstate/self', 'paused') : void 0;
}
});
$('[data-add-button]').on('click', function() {
var jid;
jid = $('#new-contact').val().trim();
if (jid === '') {
return;
}
if (indexOf.call(jid, '@') < 0) {
jid = jid + "@" + Tram.config.domain;
}
$('#new-contact').val('');
return X.conn.roster.add(jid, null, [], function() {
return X.conn.roster.subscribe(jid, 'I want to chat', null);
});
});
$('#new-contact').on('keypress', function(e) {
if (e.keyCode === 13) {
return $('[data-add-button]').trigger('click');
}
});
$('[data-unregister-button]').on('click', function() {
return X.unregister();
});
$('#settings-modal').one('show.uk.modal', function() {
window.settingsRivet = rivets.bind($('[data-app="settings"]'), {
settings: settings
});
return window.serverRivet = rivets.bind($('[data-app="server-info"]'), {
server: serverInfo
});
});
settings.on('change', saveSettings);
$('#profile-modal').one('show.uk.modal', function() {
return window.profileRivet = rivets.bind($('[data-app="profile"]'), {
contact: contacts.get(X.conn.jid)
});
});
window.setInterval(function() {
return $('time[datetime]').each(function() {
var $this;
$this = $(this);
return $this.text(moment($this.attr('datetime')).fromNow());
});
}, 15 * 1000);
}).call(this);
//# sourceMappingURL=index.js.map