forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			185 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
	
		
			5.9 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.store = loop.store || {};
 | 
						|
 | 
						|
loop.store.TextChatStore = (function() {
 | 
						|
  "use strict";
 | 
						|
 | 
						|
  var sharedActions = loop.shared.actions;
 | 
						|
 | 
						|
  var CHAT_MESSAGE_TYPES = loop.store.CHAT_MESSAGE_TYPES = {
 | 
						|
    RECEIVED: "recv",
 | 
						|
    SENT: "sent",
 | 
						|
    SPECIAL: "special"
 | 
						|
  };
 | 
						|
 | 
						|
  var CHAT_CONTENT_TYPES = loop.shared.utils.CHAT_CONTENT_TYPES;
 | 
						|
 | 
						|
  /**
 | 
						|
   * A store to handle text chats. The store has a message list that may
 | 
						|
   * contain different types of messages and data.
 | 
						|
   */
 | 
						|
  var TextChatStore = loop.store.createStore({
 | 
						|
    actions: [
 | 
						|
      "dataChannelsAvailable",
 | 
						|
      "receivedTextChatMessage",
 | 
						|
      "sendTextChatMessage",
 | 
						|
      "updateRoomInfo"
 | 
						|
    ],
 | 
						|
 | 
						|
    /**
 | 
						|
     * Initializes the store.
 | 
						|
     *
 | 
						|
     * @param  {Object} options An object containing options for this store.
 | 
						|
     *                          It should consist of:
 | 
						|
     *                          - sdkDriver: The sdkDriver to use for sending
 | 
						|
     *                                       messages.
 | 
						|
     */
 | 
						|
    initialize: function(options) {
 | 
						|
      options = options || {};
 | 
						|
 | 
						|
      if (!options.sdkDriver) {
 | 
						|
        throw new Error("Missing option sdkDriver");
 | 
						|
      }
 | 
						|
 | 
						|
      this._sdkDriver = options.sdkDriver;
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns initial state data for this active room.
 | 
						|
     */
 | 
						|
    getInitialStoreState: function() {
 | 
						|
      return {
 | 
						|
        textChatEnabled: false,
 | 
						|
        // The messages currently received. Care should be taken when updating
 | 
						|
        // this - do not update the in-store array directly, but use a clone or
 | 
						|
        // separate array and then use setStoreState().
 | 
						|
        messageList: [],
 | 
						|
        length: 0
 | 
						|
      };
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Handles information for when data channels are available - enables
 | 
						|
     * text chat.
 | 
						|
     *
 | 
						|
     * @param {sharedActions.DataChannelsAvailable} actionData
 | 
						|
     */
 | 
						|
    dataChannelsAvailable: function(actionData) {
 | 
						|
      this.setStoreState({ textChatEnabled: actionData.available });
 | 
						|
 | 
						|
      if (actionData.available) {
 | 
						|
        window.dispatchEvent(new CustomEvent("LoopChatEnabled"));
 | 
						|
      }
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Appends a message to the store, which may be of type 'sent' or 'received'.
 | 
						|
     *
 | 
						|
     * @param {CHAT_MESSAGE_TYPES} type
 | 
						|
     * @param {Object} messageData Data for this message. Options are:
 | 
						|
     * - {CHAT_CONTENT_TYPES} contentType
 | 
						|
     * - {String}             message     The message detail.
 | 
						|
     * - {Object}             extraData   Extra data associated with the message.
 | 
						|
     */
 | 
						|
    _appendTextChatMessage: function(type, messageData) {
 | 
						|
      // We create a new list to avoid updating the store's state directly,
 | 
						|
      // which confuses the views.
 | 
						|
      var message = {
 | 
						|
        type: type,
 | 
						|
        contentType: messageData.contentType,
 | 
						|
        message: messageData.message,
 | 
						|
        extraData: messageData.extraData,
 | 
						|
        sentTimestamp: messageData.sentTimestamp,
 | 
						|
        receivedTimestamp: messageData.receivedTimestamp
 | 
						|
      };
 | 
						|
      var newList = [].concat(this._storeState.messageList);
 | 
						|
      var isContext = message.contentType === CHAT_CONTENT_TYPES.CONTEXT;
 | 
						|
      if (isContext) {
 | 
						|
        var contextUpdated = false;
 | 
						|
        for (var i = 0, l = newList.length; i < l; ++i) {
 | 
						|
          // Replace the current context message with the provided update.
 | 
						|
          if (newList[i].contentType === CHAT_CONTENT_TYPES.CONTEXT) {
 | 
						|
            newList[i] = message;
 | 
						|
            contextUpdated = true;
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
        if (!contextUpdated) {
 | 
						|
          newList.push(message);
 | 
						|
        }
 | 
						|
      } else {
 | 
						|
        newList.push(message);
 | 
						|
      }
 | 
						|
      this.setStoreState({ messageList: newList });
 | 
						|
 | 
						|
      // Notify MozLoopService if appropriate that a message has been appended
 | 
						|
      // and it should therefore check if we need a different sized window or not.
 | 
						|
      if (message.contentType !== CHAT_CONTENT_TYPES.ROOM_NAME) {
 | 
						|
        window.dispatchEvent(new CustomEvent("LoopChatMessageAppended"));
 | 
						|
      }
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Handles received text chat messages.
 | 
						|
     *
 | 
						|
     * @param {sharedActions.ReceivedTextChatMessage} actionData
 | 
						|
     */
 | 
						|
    receivedTextChatMessage: function(actionData) {
 | 
						|
      // If we don't know how to deal with this content, then skip it
 | 
						|
      // as this version doesn't support it.
 | 
						|
      if (actionData.contentType !== CHAT_CONTENT_TYPES.TEXT) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
 | 
						|
      this._appendTextChatMessage(CHAT_MESSAGE_TYPES.RECEIVED, actionData);
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Handles sending of a chat message.
 | 
						|
     *
 | 
						|
     * @param {sharedActions.SendTextChatMessage} actionData
 | 
						|
     */
 | 
						|
    sendTextChatMessage: function(actionData) {
 | 
						|
      this._appendTextChatMessage(CHAT_MESSAGE_TYPES.SENT, actionData);
 | 
						|
      this._sdkDriver.sendTextChatMessage(actionData);
 | 
						|
    },
 | 
						|
 | 
						|
    /**
 | 
						|
     * Handles receiving information about the room - specifically the room name
 | 
						|
     * so it can be added to the list.
 | 
						|
     *
 | 
						|
     * @param  {sharedActions.UpdateRoomInfo} actionData
 | 
						|
     */
 | 
						|
    updateRoomInfo: function(actionData) {
 | 
						|
      // XXX When we add special messages to desktop, we'll need to not post
 | 
						|
      // multiple changes of room name, only the first. Bug 1171940 should fix this.
 | 
						|
      if (actionData.roomName) {
 | 
						|
        this._appendTextChatMessage(CHAT_MESSAGE_TYPES.SPECIAL, {
 | 
						|
          contentType: CHAT_CONTENT_TYPES.ROOM_NAME,
 | 
						|
          message: actionData.roomName
 | 
						|
        });
 | 
						|
      }
 | 
						|
 | 
						|
      // Append the context if we have any.
 | 
						|
      if (("urls" in actionData) && actionData.urls && actionData.urls.length) {
 | 
						|
        // We only support the first url at the moment.
 | 
						|
        var urlData = actionData.urls[0];
 | 
						|
 | 
						|
        this._appendTextChatMessage(CHAT_MESSAGE_TYPES.SPECIAL, {
 | 
						|
          contentType: CHAT_CONTENT_TYPES.CONTEXT,
 | 
						|
          message: urlData.description,
 | 
						|
          extraData: {
 | 
						|
            location: urlData.location,
 | 
						|
            thumbnail: urlData.thumbnail
 | 
						|
          }
 | 
						|
        });
 | 
						|
      }
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  return TextChatStore;
 | 
						|
})();
 |