/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ /* global loop:true */ var loop = loop || {}; loop.shared = loop.shared || {}; loop.shared.views = (function(OT) { "use strict"; var sharedModels = loop.shared.models; /** * Base Backbone view. */ var BaseView = Backbone.View.extend({ /** * Hides view element. * * @return {BaseView} */ hide: function() { this.$el.hide(); return this; }, /** * Shows view element. * * @return {BaseView} */ show: function() { this.$el.show(); return this; } }); /** * Conversation view. */ var ConversationView = BaseView.extend({ el: "#conversation", // height set to "auto" to fix video layout on Google Chrome // @see https://bugzilla.mozilla.org/show_bug.cgi?id=991122 videoStyles: { width: "100%", height: "auto" }, events: { 'click .btn.stop': 'hangup' }, /** * Establishes webrtc communication using OT sdk. */ initialize: function(options) { options = options || {}; if (!options.sdk) { throw new Error("missing required sdk"); } this.sdk = options.sdk; // XXX: this feels like to be moved to the ConversationModel, but as it's // tighly coupled with the DOM (element ids to receive streams), we'd need // an abstraction we probably don't want yet. this.session = this.sdk.initSession(this.model.get("sessionId")); this.publisher = this.sdk.initPublisher(this.model.get("apiKey"), "outgoing", this.videoStyles); this.session.connect(this.model.get("apiKey"), this.model.get("sessionToken")); this.listenTo(this.session, "sessionConnected", this._sessionConnected); this.listenTo(this.session, "streamCreated", this._streamCreated); this.listenTo(this.session, "connectionDestroyed", this._connectionDestroyed); this.listenTo(this.session, "sessionDisconnected", this._sessionDisconnected); this.listenTo(this.session, "networkDisconnected", this._networkDisconnected); }, hangup: function(event) { event.preventDefault(); this.session.disconnect(); }, /** * Session is created. * http://tokbox.com/opentok/libraries/client/js/reference/SessionConnectEvent.html * * @param {SessionConnectEvent} event */ _sessionConnected: function(event) { this.session.publish(this.publisher); }, /** * New created streams are available. * http://tokbox.com/opentok/libraries/client/js/reference/StreamEvent.html * * @param {StreamEvent} event */ _streamCreated: function(event) { this._subscribeToStreams(event.streams); }, /** * Local user hung up. * http://tokbox.com/opentok/libraries/client/js/reference/SessionDisconnectEvent.html * * @param {SessionDisconnectEvent} event */ _sessionDisconnected: function(event) { this.model.trigger("session:ended"); }, /** * Peer hung up. Disconnects local session. * http://tokbox.com/opentok/libraries/client/js/reference/ConnectionEvent.html * * @param {ConnectionEvent} event */ _connectionDestroyed: function(event) { this.model.trigger("session:peer-hungup", { connectionId: event.connection.connectionId }); this.session.unpublish(this.publisher); this.session.disconnect(); }, /** * Network was disconnected. * http://tokbox.com/opentok/libraries/client/js/reference/ConnectionEvent.html * * @param {ConnectionEvent} event */ _networkDisconnected: function(event) { this.model.trigger("session:network-disconnected"); this.session.unpublish(this.publisher); this.session.disconnect(); }, /** * Subscribes and attaches each available stream to a DOM element. * * XXX: for now we only support a single remote stream, hence a singe DOM * element. * * @param {Array} streams A list of media streams. */ _subscribeToStreams: function(streams) { streams.forEach(function(stream) { if (stream.connection.connectionId !== this.session.connection.connectionId) { this.session.subscribe(stream, "incoming", this.videoStyles); } }.bind(this)); } }); /** * Notification view. */ var NotificationView = Backbone.View.extend({ template: _.template([ '