fune/browser/components/loop/content/js/conversation.js

193 lines
6 KiB
JavaScript

/* 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/. */
var loop = loop || {};
loop.conversation = (function(mozL10n) {
"use strict";
var sharedMixins = loop.shared.mixins;
var sharedActions = loop.shared.actions;
var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
var FeedbackView = loop.feedbackViews.FeedbackView;
var RoomFailureView = loop.roomViews.RoomFailureView;
/**
* Master controller view for handling if incoming or outgoing calls are
* in progress, and hence, which view to display.
*/
var AppControllerView = React.createClass({displayName: "AppControllerView",
mixins: [
Backbone.Events,
loop.store.StoreMixin("conversationAppStore"),
sharedMixins.DocumentTitleMixin,
sharedMixins.WindowCloseMixin
],
propTypes: {
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
mozLoop: React.PropTypes.object.isRequired,
roomStore: React.PropTypes.instanceOf(loop.store.RoomStore)
},
getInitialState: function() {
return this.getStoreState();
},
_renderFeedbackForm: function() {
this.setTitle(mozL10n.get("conversation_has_ended"));
return (React.createElement(FeedbackView, {
mozLoop: this.props.mozLoop,
onAfterFeedbackReceived: this.closeWindow}));
},
/**
* We only show the feedback for once every 6 months, otherwise close
* the window.
*/
handleCallTerminated: function() {
var delta = new Date() - new Date(this.state.feedbackTimestamp);
// Show timestamp if feedback period (6 months) passed.
// 0 is default value for pref. Always show feedback form on first use.
if (this.state.feedbackTimestamp === 0 ||
delta >= this.state.feedbackPeriod) {
this.props.dispatcher.dispatch(new sharedActions.ShowFeedbackForm());
return;
}
this.closeWindow();
},
render: function() {
if (this.state.showFeedbackForm) {
return this._renderFeedbackForm();
}
switch(this.state.windowType) {
case "room": {
return (React.createElement(DesktopRoomConversationView, {
chatWindowDetached: this.state.chatWindowDetached,
dispatcher: this.props.dispatcher,
mozLoop: this.props.mozLoop,
onCallTerminated: this.handleCallTerminated,
roomStore: this.props.roomStore}));
}
case "failed": {
return (React.createElement(RoomFailureView, {
dispatcher: this.props.dispatcher,
failureReason: FAILURE_DETAILS.UNKNOWN,
mozLoop: this.props.mozLoop}));
}
default: {
// If we don't have a windowType, we don't know what we are yet,
// so don't display anything.
return null;
}
}
}
});
/**
* Conversation initialisation.
*/
function init() {
// Do the initial L10n setup, we do this before anything
// else to ensure the L10n environment is setup correctly.
mozL10n.initialize(navigator.mozLoop);
// Plug in an alternate client ID mechanism, as localStorage and cookies
// don't work in the conversation window
window.OT.overrideGuidStorage({
get: function(callback) {
callback(null, navigator.mozLoop.getLoopPref("ot.guid"));
},
set: function(guid, callback) {
// See nsIPrefBranch
const PREF_STRING = 32;
navigator.mozLoop.setLoopPref("ot.guid", guid, PREF_STRING);
callback(null);
}
});
// We want data channels only if the text chat preference is enabled.
var useDataChannels = loop.shared.utils.getBoolPreference("textChat.enabled");
var dispatcher = new loop.Dispatcher();
var sdkDriver = new loop.OTSdkDriver({
isDesktop: true,
useDataChannels: useDataChannels,
dispatcher: dispatcher,
sdk: OT,
mozLoop: navigator.mozLoop
});
// expose for functional tests
loop.conversation._sdkDriver = sdkDriver;
// Create the stores.
var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, {
isDesktop: true,
mozLoop: navigator.mozLoop,
sdkDriver: sdkDriver
});
var conversationAppStore = new loop.store.ConversationAppStore({
activeRoomStore: activeRoomStore,
dispatcher: dispatcher,
mozLoop: navigator.mozLoop
});
var roomStore = new loop.store.RoomStore(dispatcher, {
mozLoop: navigator.mozLoop,
activeRoomStore: activeRoomStore
});
var textChatStore = new loop.store.TextChatStore(dispatcher, {
sdkDriver: sdkDriver
});
loop.store.StoreMixin.register({
conversationAppStore: conversationAppStore,
textChatStore: textChatStore
});
// Obtain the windowId and pass it through
var locationHash = loop.shared.utils.locationData().hash;
var windowId;
var hash = locationHash.match(/#(.*)/);
if (hash) {
windowId = hash[1];
}
React.render(
React.createElement(AppControllerView, {
dispatcher: dispatcher,
mozLoop: navigator.mozLoop,
roomStore: roomStore}), document.querySelector("#main"));
document.documentElement.setAttribute("lang", mozL10n.getLanguage());
document.documentElement.setAttribute("dir", mozL10n.getDirection());
document.body.setAttribute("platform", loop.shared.utils.getPlatform());
dispatcher.dispatch(new sharedActions.GetWindowData({
windowId: windowId
}));
}
return {
AppControllerView: AppControllerView,
init: init,
/**
* Exposed for the use of functional tests to be able to check
* metric-related execution as the call sequence progresses.
*
* @type loop.OTSdkDriver
*/
_sdkDriver: null
};
})(document.mozL10n);
document.addEventListener("DOMContentLoaded", loop.conversation.init);