"use strict";var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {return typeof obj;} : function (obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;}; /* 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.roomViews = function (mozL10n) {
  "use strict";

  var ROOM_STATES = loop.store.ROOM_STATES;
  var FAILURE_DETAILS = loop.shared.utils.FAILURE_DETAILS;
  var sharedActions = loop.shared.actions;
  var sharedMixins = loop.shared.mixins;
  var sharedDesktopViews = loop.shared.desktopViews;
  var sharedViews = loop.shared.views;

  /**
   * ActiveRoomStore mixin.
   * @type {Object}
   */
  var ActiveRoomStoreMixin = { 
    mixins: [Backbone.Events], 

    propTypes: { 
      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired }, 


    componentWillMount: function componentWillMount() {
      this.listenTo(this.props.roomStore, "change:activeRoom", 
      this._onActiveRoomStateChanged);
      this.listenTo(this.props.roomStore, "change:error", 
      this._onRoomError);
      this.listenTo(this.props.roomStore, "change:savingContext", 
      this._onRoomSavingContext);}, 


    componentWillUnmount: function componentWillUnmount() {
      this.stopListening(this.props.roomStore);}, 


    _onActiveRoomStateChanged: function _onActiveRoomStateChanged() {
      // Only update the state if we're mounted, to avoid the problem where
      // stopListening doesn't nuke the active listeners during a event
      // processing.
      if (this.isMounted()) {
        this.setState(this.props.roomStore.getStoreState("activeRoom"));}}, 



    _onRoomError: function _onRoomError() {
      // Only update the state if we're mounted, to avoid the problem where
      // stopListening doesn't nuke the active listeners during a event
      // processing.
      if (this.isMounted()) {
        this.setState({ error: this.props.roomStore.getStoreState("error") });}}, 



    _onRoomSavingContext: function _onRoomSavingContext() {
      // Only update the state if we're mounted, to avoid the problem where
      // stopListening doesn't nuke the active listeners during a event
      // processing.
      if (this.isMounted()) {
        this.setState({ savingContext: this.props.roomStore.getStoreState("savingContext") });}}, 



    getInitialState: function getInitialState() {
      var storeState = this.props.roomStore.getStoreState("activeRoom");
      return _.extend({ 
        // Used by the UI showcase.
        roomState: this.props.roomState || storeState.roomState, 
        savingContext: false }, 
      storeState);} };



  /**
   * Used to display errors in direct calls and rooms to the user.
   */
  var FailureInfoView = React.createClass({ displayName: "FailureInfoView", 
    propTypes: { 
      failureReason: React.PropTypes.string.isRequired }, 


    /**
     * Returns the translated message appropraite to the failure reason.
     *
     * @return {String} The translated message for the failure reason.
     */
    _getMessage: function _getMessage() {
      switch (this.props.failureReason) {
        case FAILURE_DETAILS.NO_MEDIA:
        case FAILURE_DETAILS.UNABLE_TO_PUBLISH_MEDIA:
          return mozL10n.get("no_media_failure_message");
        case FAILURE_DETAILS.TOS_FAILURE:
          return mozL10n.get("tos_failure_message", 
          { clientShortname: mozL10n.get("clientShortname2") });
        case FAILURE_DETAILS.ICE_FAILED:
          return mozL10n.get("ice_failure_message");
        default:
          return mozL10n.get("generic_failure_message");}}, 



    render: function render() {
      return (
        React.createElement("div", { className: "failure-info" }, 
        React.createElement("div", { className: "failure-info-logo" }), 
        React.createElement("h2", { className: "failure-info-message" }, this._getMessage())));} });





  /**
   * Something went wrong view. Displayed when there's a big problem.
   */
  var RoomFailureView = React.createClass({ displayName: "RoomFailureView", 
    mixins: [sharedMixins.AudioMixin], 

    propTypes: { 
      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired, 
      failureReason: React.PropTypes.string }, 


    componentDidMount: function componentDidMount() {
      this.play("failure");}, 


    handleRejoinCall: function handleRejoinCall() {
      this.props.dispatcher.dispatch(new sharedActions.JoinRoom());}, 


    render: function render() {
      var btnTitle;
      if (this.props.failureReason === FAILURE_DETAILS.ICE_FAILED) {
        btnTitle = mozL10n.get("retry_call_button");} else 
      {
        btnTitle = mozL10n.get("rejoin_button");}


      return (
        React.createElement("div", { className: "room-failure" }, 
        React.createElement(FailureInfoView, { failureReason: this.props.failureReason }), 
        React.createElement("div", { className: "btn-group call-action-group" }, 
        React.createElement("button", { className: "btn btn-info btn-rejoin", 
          onClick: this.handleRejoinCall }, 
        btnTitle))));} });







  /**
   * Desktop room conversation view.
   */
  var DesktopRoomConversationView = React.createClass({ displayName: "DesktopRoomConversationView", 
    mixins: [
    ActiveRoomStoreMixin, 
    sharedMixins.DocumentTitleMixin, 
    sharedMixins.MediaSetupMixin, 
    sharedMixins.RoomsAudioMixin, 
    sharedMixins.WindowCloseMixin], 


    propTypes: { 
      chatWindowDetached: React.PropTypes.bool.isRequired, 
      cursorStore: React.PropTypes.instanceOf(loop.store.RemoteCursorStore).isRequired, 
      dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired, 
      facebookEnabled: React.PropTypes.bool.isRequired, 
      // The poster URLs are for UI-showcase testing and development.
      localPosterUrl: React.PropTypes.string, 
      onCallTerminated: React.PropTypes.func.isRequired, 
      remotePosterUrl: React.PropTypes.string, 
      roomStore: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired }, 


    componentWillUpdate: function componentWillUpdate(nextProps, nextState) {
      // The SDK needs to know about the configuration and the elements to use
      // for display. So the best way seems to pass the information here - ideally
      // the sdk wouldn't need to know this, but we can't change that.
      if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT && 
      nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
        this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({ 
          publisherConfig: this.getDefaultPublisherConfig({ 
            publishVideo: !this.state.videoMuted }) }));}




      // Now that we're ready to share, automatically start sharing a tab only
      // if we're not already connected to the room via the sdk, e.g. not in the
      // case a remote participant just left.
      if (nextState.roomState === ROOM_STATES.SESSION_CONNECTED && 
      !(this.state.roomState === ROOM_STATES.SESSION_CONNECTED || 
      this.state.roomState === ROOM_STATES.HAS_PARTICIPANTS)) {
        this.props.dispatcher.dispatch(new sharedActions.StartBrowserShare());}}, 



    /**
     * User clicked on the "Leave" button.
     */
    leaveRoom: function leaveRoom() {
      if (this.state.used) {
        // The room has been used, so we might want to display the feedback view.
        // Therefore we leave the room to ensure that we have stopped sharing etc,
        // then trigger the call terminated handler that'll do the right thing
        // for the feedback view.
        this.props.dispatcher.dispatch(new sharedActions.LeaveRoom());
        this.props.onCallTerminated();} else 
      {
        // If the room hasn't been used, we simply close the window.
        this.closeWindow();}}, 



    /**
     * Determine if the invitation controls should be shown.
     *
     * @return {Boolean} True if there's no guests.
     */
    _shouldRenderInvitationOverlay: function _shouldRenderInvitationOverlay() {
      var hasGuests = _typeof(this.state.participants) === "object" && 
      this.state.participants.filter(function (participant) {
        return !participant.owner;}).
      length > 0;

      // Don't show if the room has participants whether from the room state or
      // there being non-owner guests in the participants array.
      return this.state.roomState !== ROOM_STATES.HAS_PARTICIPANTS && !hasGuests;}, 


    /**
     * Works out if remote video should be rended or not, depending on the
     * room state and other flags.
     *
     * @return {Boolean} True if remote video should be rended.
     *
     * XXX Refactor shouldRenderRemoteVideo & shouldRenderLoading into one fn
     *     that returns an enum
     */
    shouldRenderRemoteVideo: function shouldRenderRemoteVideo() {
      switch (this.state.roomState) {
        case ROOM_STATES.HAS_PARTICIPANTS:
          if (this.state.remoteVideoEnabled) {
            return true;}


          if (this.state.mediaConnected) {
            // since the remoteVideo hasn't yet been enabled, if the
            // media is connected, then we should be displaying an avatar.
            return false;}


          return true;

        case ROOM_STATES.READY:
        case ROOM_STATES.GATHER:
        case ROOM_STATES.INIT:
        case ROOM_STATES.JOINING:
        case ROOM_STATES.SESSION_CONNECTED:
        case ROOM_STATES.JOINED:
        case ROOM_STATES.MEDIA_WAIT:
          // this case is so that we don't show an avatar while waiting for
          // the other party to connect
          return true;

        case ROOM_STATES.CLOSING:
          return true;

        default:
          console.warn("DesktopRoomConversationView.shouldRenderRemoteVideo:" + 
          " unexpected roomState: ", this.state.roomState);
          return true;}}, 



    /**
     * Should we render a visual cue to the user (e.g. a spinner) that a local
     * stream is on its way from the camera?
     *
     * @returns {boolean}
     * @private
     */
    _isLocalLoading: function _isLocalLoading() {
      return this.state.roomState === ROOM_STATES.MEDIA_WAIT && 
      !this.state.localSrcMediaElement;}, 


    /**
     * Should we render a visual cue to the user (e.g. a spinner) that a remote
     * stream is on its way from the other user?
     *
     * @returns {boolean}
     * @private
     */
    _isRemoteLoading: function _isRemoteLoading() {
      return !!(this.state.roomState === ROOM_STATES.HAS_PARTICIPANTS && 
      !this.state.remoteSrcMediaElement && 
      !this.state.mediaConnected);}, 


    handleContextMenu: function handleContextMenu(e) {
      e.preventDefault();}, 


    render: function render() {
      if (this.state.roomName || this.state.roomContextUrls) {
        var roomTitle = this.state.roomName || 
        this.state.roomContextUrls[0].description || 
        this.state.roomContextUrls[0].location;
        if (!roomTitle) {
          roomTitle = mozL10n.get("room_name_untitled_page");}

        this.setTitle(roomTitle);}


      var shouldRenderInvitationOverlay = this._shouldRenderInvitationOverlay();
      var roomData = this.props.roomStore.getStoreState("activeRoom");

      switch (this.state.roomState) {
        case ROOM_STATES.FAILED:
        case ROOM_STATES.FULL:{
            // Note: While rooms are set to hold a maximum of 2 participants, the
            //       FULL case should never happen on desktop.
            return (
              React.createElement(RoomFailureView, { 
                dispatcher: this.props.dispatcher, 
                failureReason: this.state.failureReason }));}


        case ROOM_STATES.ENDED:{
            // When conversation ended we either display a feedback form or
            // close the window. This is decided in the AppControllerView.
            return null;}

        default:{
            return (
              React.createElement("div", { className: "room-conversation-wrapper desktop-room-wrapper", 
                onContextMenu: this.handleContextMenu }, 
              React.createElement(sharedViews.MediaLayoutView, { 
                cursorStore: this.props.cursorStore, 
                dispatcher: this.props.dispatcher, 
                displayScreenShare: false, 
                isLocalLoading: this._isLocalLoading(), 
                isRemoteLoading: this._isRemoteLoading(), 
                isScreenShareLoading: false, 
                localPosterUrl: this.props.localPosterUrl, 
                localSrcMediaElement: this.state.localSrcMediaElement, 
                localVideoMuted: this.state.videoMuted, 
                matchMedia: this.state.matchMedia || window.matchMedia.bind(window), 
                remotePosterUrl: this.props.remotePosterUrl, 
                remoteSrcMediaElement: this.state.remoteSrcMediaElement, 
                renderRemoteVideo: this.shouldRenderRemoteVideo(), 
                screenShareMediaElement: this.state.screenShareMediaElement, 
                screenSharePosterUrl: null, 
                showInitialContext: false, 
                showMediaWait: false, 
                showTile: false }, 
              React.createElement(sharedViews.ConversationToolbar, { 
                audio: { enabled: !this.state.audioMuted, visible: true }, 
                dispatcher: this.props.dispatcher, 
                hangup: this.leaveRoom, 
                showHangup: this.props.chatWindowDetached, 
                video: { enabled: !this.state.videoMuted, visible: true } }), 
              React.createElement(sharedDesktopViews.SharePanelView, { 
                dispatcher: this.props.dispatcher, 
                error: this.state.error, 
                facebookEnabled: this.props.facebookEnabled, 
                locationForMetrics: "conversation", 
                roomData: roomData, 
                show: shouldRenderInvitationOverlay }))));}}} });








  return { 
    ActiveRoomStoreMixin: ActiveRoomStoreMixin, 
    FailureInfoView: FailureInfoView, 
    RoomFailureView: RoomFailureView, 
    DesktopRoomConversationView: DesktopRoomConversationView };}(


document.mozL10n || navigator.mozL10n);
