From c736a7722e0cb0afe7966b6379e340939366e3bc Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 15 Oct 2013 00:02:45 -0700 Subject: [PATCH] Save jingle changes --- clientapp/app.js | 1 + clientapp/helpers/xmppEventHandlers.js | 46 ++++++++++++++++++++++++++ clientapp/models/contact.js | 21 ++++++++++-- clientapp/models/me.js | 2 -- clientapp/pages/chat.js | 11 +++++- package.json | 9 +++-- public/x-manifest.cache | 2 +- server.js | 3 ++ 8 files changed, 85 insertions(+), 10 deletions(-) diff --git a/clientapp/app.js b/clientapp/app.js index b51150f..e7396a1 100644 --- a/clientapp/app.js +++ b/clientapp/app.js @@ -28,6 +28,7 @@ module.exports = { } config = JSON.parse(config); + config.useStreamManagement = false; _.extend(this, Backbone.Events); diff --git a/clientapp/helpers/xmppEventHandlers.js b/clientapp/helpers/xmppEventHandlers.js index b668202..c4bc88c 100644 --- a/clientapp/helpers/xmppEventHandlers.js +++ b/clientapp/helpers/xmppEventHandlers.js @@ -333,4 +333,50 @@ module.exports = function (client, app) { } } }); + + client.on('jingle:incoming', function (session) { + var contact = me.getContact(session.peer); + contact.callState = 'incoming'; + contact.jingleCall = session; + }); + + client.on('jingle:outgoing', function (session) { + var contact = me.getContact(session.peer); + contact.callState = 'outgoing'; + contact.jingleCall = session; + }); + + client.on('jingle:terminated', function (session) { + var contact = me.getContact(session.peer); + contact.callState = ''; + contact.jingleCall = null; + }); + + client.on('jingle:accepted', function (session) { + var contact = me.getContact(session.peer); + contact.callState = 'active'; + }); + + client.on('jingle:localstream:added', function (stream) { + me.stream = stream; + }); + + client.on('jingle:localstream:removed', function () { + me.stream = null; + }); + + client.on('jingle:remotestream:added', function (session) { + var contact = me.getContact(session.peer); + contact.stream = session.stream; + }); + + client.on('jingle:remotestream:removed', function (session) { + var contact = me.getContact(session.peer); + contact.stream = null; + }); + + client.on('jingle:ringing', function (session) { + var contact = me.getContact(session.peer); + contact.callState = 'ringing'; + }); }; diff --git a/clientapp/models/contact.js b/clientapp/models/contact.js index bc14de8..0a2483f 100644 --- a/clientapp/models/contact.js +++ b/clientapp/models/contact.js @@ -2,6 +2,7 @@ "use strict"; var _ = require('underscore'); +var crypto = require('crypto'); var async = require('async'); var uuid = require('node-uuid'); var HumanModel = require('human-model'); @@ -44,7 +45,9 @@ module.exports = HumanModel.define({ offlineStatus: ['string', true, ''], topResource: 'string', unreadCount: ['number', true, 0], - _forceUpdate: ['number', true, 0] + _forceUpdate: ['number', true, 0], + callState: 'string', + stream: 'object' }, derived: { displayName: { @@ -137,7 +140,7 @@ module.exports = HumanModel.define({ } }, jingleResources: { - cache: false, + deps: ['_forceUpdate'], fn: function () { return this.resources.filter(function (res) { return res.supportsJingleMedia; @@ -149,6 +152,17 @@ module.exports = HumanModel.define({ resources: Resources, messages: Messages }, + call: function () { + if (this.jingleResources) { + var peer = this.jingleResources[0]; + this.callState = 'starting'; + app.api.jingle.startLocalMedia(null, function (err) { + if (!err) { + app.api.call(peer.id); + } + }); + } + }, setAvatar: function (id, type) { var self = this; fetchAvatar(this.jid, id, type, function (avatar) { @@ -254,8 +268,9 @@ module.exports = HumanModel.define({ save: function () { if (!this.inRoster) return; + var storageId = crypto.createHash('sha1').update(this.owner + '/' + this.id).digest('hex'); var data = { - storageId: this.storageId, + storageId: storageId, owner: this.owner, jid: this.jid, name: this.name, diff --git a/clientapp/models/me.js b/clientapp/models/me.js index dfb9b1e..41735c7 100644 --- a/clientapp/models/me.js +++ b/clientapp/models/me.js @@ -6,7 +6,6 @@ var Contacts = require('./contacts'); var Contact = require('./contact'); var MUCs = require('./mucs'); var MUC = require('./muc'); -var uuid = require('node-uuid'); var fetchAvatar = require('../helpers/fetchAvatar'); @@ -74,7 +73,6 @@ module.exports = HumanModel.define({ contact = new Contact(data); contact.inRoster = true; contact.owner = this.jid.bare; - contact.storageId = uuid.v4(); contact.save(); this.contacts.add(contact); } diff --git a/clientapp/pages/chat.js b/clientapp/pages/chat.js index 96bd59e..ba748d7 100644 --- a/clientapp/pages/chat.js +++ b/clientapp/pages/chat.js @@ -7,6 +7,7 @@ var templates = require('../templates'); var Message = require('../views/message'); var MessageModel = require('../models/message'); var chatHelpers = require('../helpers/chatHelpers'); +var attachMediaStream = require('attachmediastream'); module.exports = BasePage.extend(chatHelpers).extend({ @@ -22,6 +23,8 @@ module.exports = BasePage.extend(chatHelpers).extend({ this.listenTo(this.model.messages, 'change:edited', this.refreshModel); this.listenTo(this.model.messages, 'change:pending', this.refreshModel); + this.listenTo(this.model, 'change:stream', this.handleStream); + this.render(); }, events: { @@ -80,7 +83,8 @@ module.exports = BasePage.extend(chatHelpers).extend({ handlePageUnloaded: function () { this.scrollPageUnload(); }, - handleCallClick: function () { + handleCallClick: function (e) { + e.preventDefault(); this.model.call(); return false; }, @@ -191,6 +195,11 @@ module.exports = BasePage.extend(chatHelpers).extend({ var resources = val || this.model.jingleResources; this.$('button.call').prop('disabled', !resources.length); }, + handleStream: function () { + if (this.model.stream) { + attachMediaStream(this.model.stream, this.$('.remoteVideo')); + } + }, appendModel: function (model, preload) { var self = this; var isGrouped = model.shouldGroupWith(this.lastModel); diff --git a/package.json b/package.json index d05f204..1de6254 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Otalk: WebRTC Enabled XMPP Client, in the Browser", "repository": { - "type": "git", + "type": "git", "url": "git@github.com:andyet/otalk.git" }, "dependencies": { @@ -23,9 +23,12 @@ "templatizer": "0.1.2", "underscore": "1.5.1", "raf-component": "1.1.1", - "stanza.io": "2.5.7", + "stanza.io": "2.5.9", "notify.js": "0.0.1", - "wildemitter": "0.0.5" + "wildemitter": "0.0.5", + "attachmediastream": "", + "crypto-browserify": "1.0.3", + "browserify": "2.25.1" }, "devDependencies": { "precommit-hook": "0.3.6" diff --git a/public/x-manifest.cache b/public/x-manifest.cache index d907103..10c01e4 100644 --- a/public/x-manifest.cache +++ b/public/x-manifest.cache @@ -1,5 +1,5 @@ CACHE MANIFEST -# 0.0.1 1381790561081 +# 0.0.1 1381820535074 CACHE: /app.js diff --git a/server.js b/server.js index 5bdfbef..e53a7c7 100644 --- a/server.js +++ b/server.js @@ -28,6 +28,9 @@ var clientApp = new Moonboots({ __dirname + '/clientapp/libraries/resampler.js', __dirname + '/clientapp/libraries/IndexedDBShim.min.js' ], + browserify: { + debug: false + }, stylesheets: [ __dirname + '/public/css/otalk.css' ],