Anton Shestakov <av6@dwimlabs.net>, Sat, 02 Apr 2016 22:15:35 +0800
index: ClientState is a better name
js/index.js
Permissions: -rw-r--r--
// Generated by CoffeeScript 1.10.0 var $form, ConnectionData, connectfn, getContact, getContactProfile, getText, getVersion, onConnected, onDisconnected, onGetLast, onGetTime, onGetVersion, onPing, onPresence, onProfileUpdate, onWebRTC, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty, 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('LAST', 'jabber:iq:last'); Strophe.addNamespace('TIME', 'urn:xmpp:time'); Strophe.addNamespace('VCARD_UPDATE', 'vcard-temp:x:update'); window.Tram.ClientState = (function(superClass) { extend(ClientState, superClass); return ClientState.__super__.constructor.apply(this, arguments); ClientState.prototype.defaults = { if (window.contacts == null) { window.contacts = new Tram.Contacts(); if (window.contactsApp == null) { window.contactsApp = new Tram.ContactsApp({ el: $('[data-app="contacts"]'), if (window.messages == null) { window.messages = new Tram.Messages(); if (window.logApp == null) { window.logApp = new Tram.LogApp({ el: $('[data-app="log"]'), if (window.calls == null) { window.calls = new Tram.Calls(); if (window.callsApp == null) { window.callsApp = new Tram.CallsApp({ el: $('[data-app="calls"]'), if (window.clientState == null) { window.clientState = new Tram.ClientState(); if (window.faviconApp == null) { window.faviconApp = new Tram.FaviconApp({ if (window.sidebarApp == null) { window.sidebarApp = new Tram.SidebarApp({ el: $('[data-app="sidebar"]'), contacts.on('change:show', function(model) { if (model.get('type') === 'self') { return clientState.set('show', model.get('show')); clientState.on('show', function(show, status) { return X.conn.send($pres().c('priority').t('1').up().c('show').t(show).up().c('status').t(status).tree()); clientState.on('disconnect', function() { return X.disconnect('Logged out'); onConnected = function() { X.conn.addHandler(onPresence, null, 'presence'); X.conn.addHandler(onProfileUpdate, Strophe.NS.VCARD_UPDATE, 'presence'); 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.DISCO_INFO); X.conn.disco.addFeature(Strophe.NS.LAST); X.conn.disco.addFeature(Strophe.NS.PING); X.conn.disco.addFeature(Strophe.NS.TIME); X.conn.disco.addFeature(Strophe.NS.VERSION); X.conn.disco.addFeature(Tram.NS.WEBRTC); X.conn.send($pres().c('priority').t('1').up().c('status').t('Online').tree()); return X.conn.roster.get(); onDisconnected = function() { return clientState.set('show', 'offline'); var i, len, node, ref, str; if (el.childNodes.length === 0 && el.nodeType === Strophe.ElementType.TEXT) { for (i = 0, len = ref.length; i < len; i++) { if (node.nodeType === Strophe.ElementType.TEXT) { getVersion = function() { id: X.conn.getUniqueId('version'), xmlns: Strophe.NS.VERSION okcb = function(stanza) { var delay, name, os, stamp, version; name = getText(stanza.getElementsByTagName('name')[0]); version = getText(stanza.getElementsByTagName('version')[0]); os = getText(stanza.getElementsByTagName('os')[0]); delay = stanza.getElementsByTagName('delay')[0]; stamp = delay != null ? new Date(delay.getAttribute('stamp')) : new Date(); id: stanza.getAttribute('id'), type: stanza.getAttribute('type'), from: stanza.getAttribute('from'), text: "connected to " + name + " " + version + " on " + os failcb = function(stanza) { return console.error("couldn't get version", stanza != null ? stanza.innerHTML : void 0); return X.conn.sendIQ(iq.tree(), okcb, failcb, 5000); onGetLast = function(stanza) { id = stanza.getAttribute('id'); from = stanza.getAttribute('from'); xmlns: Strophe.NS.VERSION, onGetTime = function(stanza) { id = stanza.getAttribute('id'); from = stanza.getAttribute('from'); }).c('tzo').t(now.format('Z')).up().c('utc').t(now.toISOString()); onGetVersion = function(stanza) { id = stanza.getAttribute('id'); from = stanza.getAttribute('from'); xmlns: Strophe.NS.VERSION }).c('name').t(Tram.info.client).up().c('version').t(Tram.info.version); onPing = function(stanza) { X.conn.ping.pong(stanza); getContact = function(from) { contact = contacts.get(from); self = from === X.conn.jid; contacts.each(function(model) { return model.set('type', 'contact'); bjid: Strophe.getBareJidFromJid(from), type: self ? 'self' : 'contact' contact.on('authorize', function() { return X.conn.roster.authorize(contact.get('bjid')); contact.on('unauthorize', function() { X.conn.roster.unauthorize(contact.get('bjid')); return contacts.remove(contact); contact.on('remove', function() { return X.conn.roster.remove(contact.get('bjid'), function() { return contacts.remove(contact); contact.w = new Tram.WebRTCInterface(contact); contact.on('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('accept', function(media) { return contact.w.init(false, { audio: indexOf.call(media, 'a') >= 0, video: indexOf.call(media, 'v') >= 0 contact.on('decline hangup', function() { contact.w.sendIntent('terminate'); return contact.unset('callstate'); getContactProfile(contact); getContactProfile = function(contact) { okcb = function(stanza) { vcard = stanza.getElementsByTagName('vCard')[0]; console.warn("no vcard in response", stanza); nickname: getText(vcard.querySelector('NICKNAME')), fullname: getText(vcard.querySelector('FN')), firstname: getText(vcard.querySelector('N > GIVEN')), lastname: getText(vcard.querySelector('N > FAMILY')) mime = getText(vcard.querySelector('PHOTO > TYPE')); data = getText(vcard.querySelector('PHOTO > BINVAL')); return contact.set('avatar', { return contact.unset('avatar'); failcb = function(stanza) { return console.warn("couldn't get vcard", stanza); bjid = contact.get('bjid'); if (bjid === Strophe.getBareJidFromJid(X.conn.jid)) { return X.conn.vcard.get(okcb, bjid, failcb); onPresence = function(stanza) { var contact, delay, from, priority, ref, show, stamp, status, type; type = (ref = stanza.getAttribute('type')) != null ? ref : 'available'; console.warn("not handling <presence type=\"" + type + "\">", stanza); console.error('got <presence type="error">', stanza); from = stanza.getAttribute('from'); contact = getContact(from); show = getText(stanza.getElementsByTagName('show')[0]); status = getText(stanza.getElementsByTagName('status')[0]); priority = getText(stanza.getElementsByTagName('priority')[0]); if (type === 'unavailable') { if ((type === 'available' || type === 'unavailable') && contact.get('type') !== 'self') { delay = stanza.getElementsByTagName('delay')[0]; stamp = delay != null ? new Date(delay.getAttribute('stamp')) : new Date(); id: stanza.getAttribute('id'), text: status != null ? status : "is now " + show onProfileUpdate = function(stanza) { from = stanza.getAttribute('from'); contact = getContact(from); getContactProfile(contact); onWebRTC = function(stanza) { var contact, delay, from, intent, payload, stamp; from = stanza.getAttribute('from'); contact = getContact(from); intent = stanza.getElementsByTagName('intent')[0]; payload = stanza.getElementsByTagName('payload')[0]; delay = stanza.getElementsByTagName('delay')[0]; stamp = delay != null ? new Date(delay.getAttribute('stamp')) : new Date(); switch (getText(intent)) { contact.set('callstate', 'incoming'); id: stanza.getAttribute('id'), contact.unset('callstate'); contact.w.onPayload(stanza); window.X = new Tram.XMPPInterface(); X.on('connecting', function() { return connData.unset('auth-errors'); X.on('authfail', function() { return connData.set('auth-errors', ['Invalid username or password.']); X.on('disconnected', function() { $('[data-step="login"]').removeClass('uk-hidden'); $('[data-step="main"]').addClass('uk-hidden'); X.on('connected attached', function() { $('[data-step="login"]').addClass('uk-hidden'); $('[data-step="main"]').removeClass('uk-hidden'); $(window).on('beforeunload unload', function() { return X.disconnect('Window closed'); ConnectionData = (function(superClass) { extend(ConnectionData, superClass); function ConnectionData() { return ConnectionData.__super__.constructor.apply(this, arguments); ConnectionData.prototype.defaults = { ConnectionData.prototype.validate = function(attrs, options) { this.unset('username-errors'); this.unset('password-errors'); this.unset('auth-errors'); if (((ref = attrs.username) != null ? ref : '').trim() === '') { this.set('username-errors', ['This field is required.']); if (((ref1 = attrs.password) != null ? ref1 : '') === '') { this.set('password-errors', ['This field is required.']); return this.has('username-errors') || this.has('password-errors'); window.connData = new ConnectionData(); if (connData.isValid()) { return X.connect(connData.get('username').trim(), connData.get('password')); $form = $('[data-form="connect"]'); window.connRivet = rivets.bind($form.get(0), { $form.find('input').on('keydown', function(e) { if ((!this.required || this.value !== '') && e.keyCode === 13) { index = $form.find('input').index(this); $next = $form.find('input').eq(index + 1); if ($next.length !== 0) { return $form.find('button').trigger('click'); $('[data-add-button]').on('click', function() { jid = $('#new-contact').val().trim(); 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) { return $('[data-add-button]').trigger('click'); window.setInterval(function() { return $('time[datetime]').each(function() { return $this.text(moment($this.attr('datetime')).fromNow()); //# sourceMappingURL=index.js.map