<commit_before>$(document).ready(function() {

/// Study elements
    var $txtAllStudy_ = $("#all_study");
    var $txtRecapList_ = $("#recap #recap_list");

    var studyList_ = [];
    var graspedList_ = [];
    var recapList_ = [];

    var clickCallback_ = null;
    var currentMode_ = '';

    var resetUI = function() {
       $txtAllStudy_.text("");
       $txtRecapList_.text("");

       studyList_ = [];
       graspedList_ = [];
       recapList_ = [];

       clickCallback_ = null;
       currentMode_ = '';

       Flashcard.displayVocabulary("");
    };

    /**
     *
     */
    var setUI = function() {
        // display all vocabularies
        $txtAllStudy_.text(studyList_.join(" "));
        console.log('Study list: ', studyList_);
        // bind flashcard strategy
        Flashcard.setHanCharacterDivClickCallback(clickCallback_);
        Flashcard.displayVocabulary(studyList_.pop());
    };

/// ======== study new ========

    /*
     * Flashcard click callback in StudyNew mode
     *     save the current vocabulary to graspedList_ (as a holder)
     *     pop one element from studyList_
     *     if studyList_ is empty, swap studyList_ and graspedList_
     *     shuffle studyList_
     */
    var studyNewClickCallback = function() {
        graspedList_.push(Flashcard.getLastWord());
        Flashcard.displayVocabulary(studyList_.pop());
        if (studyList_.length === 0) {
            studyList_ = Util.shuffle(graspedList_);
            graspedList_ = [];
        }
    };

    /*
     * Init elements for the study new mode
     */
    var initStudyNew = function() {
        resetUI();

        // get new studies
        var today_study = $("#input_today_study").val().trim();
        console.log("today study: ", today_study);
        studyList_ = today_study.split(" ");

        clickCallback_ = studyNewClickCallback;
        currentMode_ = "StudyNew";

        setUI();
    };

    $("#button_add_new").click(function() {
        initStudyNew();
    });

    $("#button_save_to_server").click(function() {
        if (currentMode_ === "StudyNew") {
            var newWords = [];
            newWords.push(Flashcard.getLastWord());
            newWords.push.apply(newWords, graspedList_);
            newWords.push.apply(newWords, studyList_);
            console.log(newWords);
            StudyAPI.newStudy(newWords.join(" "))
            .done(function(data, textStatus, jqXHR) {
                Util.notifySuccess("New study saved");
            })
            .fail(function(data, textStatus, jqXHR) {
                Util.notifyError("Failed saving new study");
            });
        }
    });

/// ======== revise ========
    /**
     * call getStudyHistoryIntelligent() or getStudyHistoryBetween()
     * @return $.ajax() deferred object
     */
    var getStudyHistory = function() {
        var history = $('#select_previous_study option:selected').val();
        console.log("history: ", history);

        if (history === "intelligent")
            return StudyAPI.getStudyIntelligent();

        if (history === "last_week" || history === "last_month")
            return getStudyHistoryBetween(history);
    };

    /*
     * call StudyAPI.getStudyBetween()
     * @return $.ajax() deferred object
     */
    var getStudyHistoryBetween = function(history) {
        var today = new Date();
        var end_date = new Date();
        var start_date = null;
        if (history === "last_week")
            start_date = Util.getLastWeek();
        if (history === "last_month")
            start_date = Util.getLastMonth();

        console.log('end_date (today):', end_date);
        console.log('start_date: ', start_date);
        return StudyAPI.getStudyBetween(start_date, end_date);
    };

    /**
     * Flashcard click callback in revise mode
     *     remove from studyList_, and save to graspedList_
     *     update progress UI
     *     if studyList_ is to be empty,
     *         save revising history to server
     *     show next vocabulary
     */
    var reviseClickCallback = function() {
        graspedList_.push(Flashcard.getLastWord());

        if (studyList_.length === 0) {
            saveRevise();
            // go to recap mode
            if (recapList_.length > 0)
                initRecap();
            else
                resetUI();
        } else {
            Flashcard.displayVocabulary(studyList_.pop());
        }
    };

    /**
     * Save revise to server
     * Start Revise mode if ncessary
     */
    var saveRevise = function() {
        $.when(
            StudyAPI.reviseStudy(graspedList_.join(" ")),
            StudyAPI.newStudy(recapList_.join(" "))
        ).done(function(r1, r2) {
            Util.notifySuccess("Revise saved");
        })
        .fail(function(r1, r2) {
            Util.notifyError("Failed saving revise");
        });
    };

    /*
     * Init elements for the revise mode
     */
    var initRevise = function() {
        // get study history
        getStudyHistory()
        .done(function(data, textStatus, jqXHR) {
            resetUI();

            Util.notifySuccess("Study history loaded");
            console.log('history data: ', data);
            studyList_ = JSON.parse(data);
            if (studyList_.length > 0) {
                clickCallback_ = reviseClickCallback;
                currentMode_ = "Revise";

                setUI();
            }
            else {
                Util.notifyError("No learning history available");
                $txtAllStudy_.text("No learning history available");
            }
        })
        .fail(function(data, textStatus, jqXHR) {
            Util.notifyError("Failed loading the study history");
        });
    };

    $("#button_load_history").click(function() {
        initRevise();
    });

    $("#button_add_to_recap_list").click(function() {
        if (currentMode_ === 'Revise') {
            recapList_.push(Flashcard.getLastWord());
            console.log('recap list: ', recapList_);
            console.log('study list: ', studyList_)
            if (studyList_.length === 0) {
                saveRevise();
                // go to recap mode
                if (recapList_.length > 0)
                    initRecap();
                else
                    resetUI();
            } else {
                Flashcard.displayVocabulary(studyList_.pop());
                $txtRecapList_.text(recapList_);
            }
        }
    });

/// ======== recap ========

    var recapClickCallback = function() {
        recapList_.push(Flashcard.getLastWord());
        Flashcard.displayVocabulary(studyList_.pop());
        if (studyList_.length === 0) {
            studyList_ = recapList_;
            recapList_ = [];
        }
    };

    var initRecap = function() {
        studyList_ = recapList_;
        recapList_ = [];
        $txtRecapList_.text("recap mode");
        clickCallback_ = recapClickCallback;
        currentMode_ = "Recap";

        setUI();
        Util.notifySuccess("Switch to Recap mode");
    };

    // initialise
    // bind Flashcard
    Flashcard.init($("#flashcard"));

});<commit_msg>shuffle revise list<commit_after>$(document).ready(function() {

/// Study elements
    var $txtAllStudy_ = $("#all_study");
    var $txtRecapList_ = $("#recap #recap_list");

    var studyList_ = [];
    var graspedList_ = [];
    var recapList_ = [];

    var clickCallback_ = null;
    var currentMode_ = '';

    var resetUI = function() {
       $txtAllStudy_.text("");
       $txtRecapList_.text("");

       studyList_ = [];
       graspedList_ = [];
       recapList_ = [];

       clickCallback_ = null;
       currentMode_ = '';

       Flashcard.displayVocabulary("");
    };

    /**
     *
     */
    var setUI = function() {
        // display all vocabularies
        $txtAllStudy_.text(studyList_.join(" "));
        console.log('Study list: ', studyList_);
        // bind flashcard strategy
        Flashcard.setHanCharacterDivClickCallback(clickCallback_);
        Flashcard.displayVocabulary(studyList_.pop());
    };

/// ======== study new ========

    /*
     * Flashcard click callback in StudyNew mode
     *     save the current vocabulary to graspedList_ (as a holder)
     *     pop one element from studyList_
     *     if studyList_ is empty, swap studyList_ and graspedList_
     *     shuffle studyList_
     */
    var studyNewClickCallback = function() {
        graspedList_.push(Flashcard.getLastWord());
        Flashcard.displayVocabulary(studyList_.pop());
        if (studyList_.length === 0) {
            studyList_ = Util.shuffle(graspedList_);
            graspedList_ = [];
        }
    };

    /*
     * Init elements for the study new mode
     */
    var initStudyNew = function() {
        resetUI();

        // get new studies
        var today_study = $("#input_today_study").val().trim();
        console.log("today study: ", today_study);
        studyList_ = today_study.split(" ");

        clickCallback_ = studyNewClickCallback;
        currentMode_ = "StudyNew";

        setUI();
    };

    $("#button_add_new").click(function() {
        initStudyNew();
    });

    $("#button_save_to_server").click(function() {
        if (currentMode_ === "StudyNew") {
            var newWords = [];
            newWords.push(Flashcard.getLastWord());
            newWords.push.apply(newWords, graspedList_);
            newWords.push.apply(newWords, studyList_);
            console.log(newWords);
            StudyAPI.newStudy(newWords.join(" "))
            .done(function(data, textStatus, jqXHR) {
                Util.notifySuccess("New study saved");
            })
            .fail(function(data, textStatus, jqXHR) {
                Util.notifyError("Failed saving new study");
            });
        }
    });

/// ======== revise ========
    /**
     * call getStudyHistoryIntelligent() or getStudyHistoryBetween()
     * @return $.ajax() deferred object
     */
    var getStudyHistory = function() {
        var history = $('#select_previous_study option:selected').val();
        console.log("history: ", history);

        if (history === "intelligent")
            return StudyAPI.getStudyIntelligent();

        if (history === "last_week" || history === "last_month")
            return getStudyHistoryBetween(history);
    };

    /*
     * call StudyAPI.getStudyBetween()
     * @return $.ajax() deferred object
     */
    var getStudyHistoryBetween = function(history) {
        var today = new Date();
        var end_date = new Date();
        var start_date = null;
        if (history === "last_week")
            start_date = Util.getLastWeek();
        if (history === "last_month")
            start_date = Util.getLastMonth();

        console.log('end_date (today):', end_date);
        console.log('start_date: ', start_date);
        return StudyAPI.getStudyBetween(start_date, end_date);
    };

    /**
     * Flashcard click callback in revise mode
     *     remove from studyList_, and save to graspedList_
     *     update progress UI
     *     if studyList_ is to be empty,
     *         save revising history to server
     *     show next vocabulary
     */
    var reviseClickCallback = function() {
        graspedList_.push(Flashcard.getLastWord());

        if (studyList_.length === 0) {
            saveRevise();
            // go to recap mode
            if (recapList_.length > 0)
                initRecap();
            else
                resetUI();
        } else {
            Flashcard.displayVocabulary(studyList_.pop());
        }
    };

    /**
     * Save revise to server
     * Start Revise mode if ncessary
     */
    var saveRevise = function() {
        $.when(
            StudyAPI.reviseStudy(graspedList_.join(" ")),
            StudyAPI.newStudy(recapList_.join(" "))
        ).done(function(r1, r2) {
            Util.notifySuccess("Revise saved");
        })
        .fail(function(r1, r2) {
            Util.notifyError("Failed saving revise");
        });
    };

    /*
     * Init elements for the revise mode
     */
    var initRevise = function() {
        // get study history
        getStudyHistory()
        .done(function(data, textStatus, jqXHR) {
            resetUI();

            Util.notifySuccess("Study history loaded");
            console.log('history data: ', data);
            studyList_ = JSON.parse(data);
            if (studyList_.length > 0) {
                studyList_ = Util.shuffle(studyList_);
                clickCallback_ = reviseClickCallback;
                currentMode_ = "Revise";

                setUI();
            }
            else {
                Util.notifyError("No learning history available");
                $txtAllStudy_.text("No learning history available");
            }
        })
        .fail(function(data, textStatus, jqXHR) {
            Util.notifyError("Failed loading the study history");
        });
    };

    $("#button_load_history").click(function() {
        initRevise();
    });

    $("#button_add_to_recap_list").click(function() {
        if (currentMode_ === 'Revise') {
            recapList_.push(Flashcard.getLastWord());
            console.log('recap list: ', recapList_);
            console.log('study list: ', studyList_)
            if (studyList_.length === 0) {
                saveRevise();
                // go to recap mode
                if (recapList_.length > 0)
                    initRecap();
                else
                    resetUI();
            } else {
                Flashcard.displayVocabulary(studyList_.pop());
                $txtRecapList_.text(recapList_);
            }
        }
    });

/// ======== recap ========

    var recapClickCallback = function() {
        recapList_.push(Flashcard.getLastWord());
        Flashcard.displayVocabulary(studyList_.pop());
        if (studyList_.length === 0) {
            studyList_ = recapList_;
            recapList_ = [];
        }
    };

    var initRecap = function() {
        studyList_ = recapList_;
        recapList_ = [];
        $txtRecapList_.text("recap mode");
        clickCallback_ = recapClickCallback;
        currentMode_ = "Recap";

        setUI();
        Util.notifySuccess("Switch to Recap mode");
    };

    // initialise
    // bind Flashcard
    Flashcard.init($("#flashcard"));

});<|endoftext|>


<commit_before>/* global Talkilla, Backbone, _, jQuery*/
/**
 * Talkilla Backbone views.
 */
(function(app, Backbone, _, $) {
  "use strict";

  /**
   * Global app view.
   */
  app.views.AppView = Backbone.View.extend({
    el: 'body',

    initialize: function() {
      this.notifications = new app.views.NotificationsView();
      this.login = new app.views.LoginView();
      this.users = new app.views.UsersView();
      this.call = new app.views.CallView({model: new app.models.Call()});
    },

    render: function() {
      this.login.render();
      this.users.render();
      this.call.render();
      return this;
    }
  });

  /**
   * Base notification view.
   */
  app.views.NotificationView = Backbone.View.extend({
    template: _.template([
      '<div class="alert alert-<%= type %>">',
      '  ×',
      '  <%= message %>',
      '
'
    ].join('')),

    clear: function() {
      this.undelegateEvents();
      this.remove();
    },

    render: function() {
      this.$el.html(this.template(this.model.toJSON()));
      return this;
    }
  });

  /**
   * Incoming call notification view.
   */
  app.views.IncomingCallNotificationView = app.views.NotificationView.extend({
    template: _.template([
      '
',
      '
Incoming call from <%= caller %>
',
      '
Do you want to take the call?',
      '    Accept',
      '    Deny',
      '
',
      '
'
    ].join('')),

    events: {
      'click .accept': 'accept',
      'click .deny': 'deny'
    },

    accept: function(event) {
      event.preventDefault();
      var callView = app.router.view.call;
      callView.offer = this.model.get('offer');
      callView.callee = app.data.users.findWhere({
        nick: this.model.get('caller')
      });
      callView.render();
      this.clear();
    },

    deny: function(event) {
      event.preventDefault();
      // XXX to be replaced
      /*
      app.services.ws.send(JSON.stringify({
        'call_deny': this.model.toJSON()
      }));
      */
      this.clear();
    }
  });

  /**
   * Pending call notification view.
   */
  app.views.PendingCallNotificationView = app.views.NotificationView.extend({
    template: _.template([
      '
',
      '  ×',
      '
Calling <%= callee %>…',
      '    Cancel
',
      '
'
    ].join('')),

    events: {
      'click .btn-cancel': 'cancel'
    },

    initialize: function() {
      // app events
      app.on('hangup_done', function() {
        this.clear();
      }.bind(this));
    },

    cancel: function(event) {
      event.preventDefault();
      app.trigger('hangup');
      this.clear();
    }
  });

  /**
   * Denied call notification view.
   */
  app.views.DeniedCallNotificationView = app.views.NotificationView.extend({
    template: _.template([
      '
',
      '  ×',
      '
<%= callee %> declined the call
',
      '
'
    ].join(''))
  });

  /**
   * Notifications list view.
   */
  app.views.NotificationsView = Backbone.View.extend({
    el: '#messages',

    notifications: [],

    initialize: function() {
      // service events
      app.services.on('incoming_call', function(data) {
        var notification = new app.views.IncomingCallNotificationView({
          model: new app.models.IncomingCall(data)
        });
        this.addNotification(notification);
      }.bind(this));

      app.services.on('call_offer', function(data) {
        var notification = new app.views.PendingCallNotificationView({
          model: new app.models.PendingCall(data)
        });
        this.addNotification(notification);
      }.bind(this));

      app.services.on('call_denied', function(data) {
        var notification = new app.views.DeniedCallNotificationView({
          model: new app.models.DeniedCall(data)
        });
        this.addNotification(notification);
      }.bind(this));

      // app events
      app.on('hangup_done', function() {
        this.render();
      }.bind(this));

      app.on('signin', function() {
        this.clear();
      }.bind(this));

      app.on('signout', function() {
        this.clear();
      }.bind(this));
    },

    /**
     * Adds a new notification.
     * @param {app.views.NotificationView} notification
     */
    addNotification: function(notification) {
      var DeniedCallNotificationView = app.views.DeniedCallNotificationView;
      var PendingCallNotificationView = app.views.PendingCallNotificationView;
      var el = notification.render().el;

      this.notifications.push(notification);
      this.$el.append(el);

      // A denied call notification replace a pending call notification
      if (notification instanceof DeniedCallNotificationView)
        this.notifications = this.notifications.filter(function(notif) {
          var isPending = (notif instanceof PendingCallNotificationView);

          if (isPending)
            notif.clear();

          return !isPending;
        });

      return this;
    },

    /**
     * Clear current active notification if any and empty the notifications
     * list.
     */
    clear: function() {
      if (this.notification) {
        this.notification.clear();
        this.notification = undefined;
      }
      this.$el.html('');
    }
  });

  /**
   * User list entry view.
   */
  app.views.UserEntryView = Backbone.View.extend({
    tagName: 'li',

    template: _.template('<a href="#call/<%= nick %>"><%= nick %>'),

    initialize: function(options) {
      this.model = options && options.model;
      this.active = options && options.active;
    },

    render: function() {
      this.$el.html(this.template(this.model.toJSON()));
      if (this.active)
        this.$('a').addClass('active');
      return this;
    }
  });

  /**
   * User list view.
   */
  app.views.UsersView = Backbone.View.extend({
    el: '#users',

    views: [],
    activeNotification: null,

    initialize: function() {
      app.data.users = this.collection = new app.models.UserSet();

      this.collection.on('change', function() {
        this.render();
      }.bind(this));

      this.collection.on('reset', function() {
        this.render();
      }.bind(this));

      // purge the list on sign out
      app.on('signout', function() {
        this.collection.reset();
        this.callee = undefined;
        this.render();
      }.bind(this));

      // highlight callee's username on call
      app.on('call', function(call) {
        this.callee = call && call.callee;
        this.render();
      }.bind(this));

      // unhighlight all usernames on hang up done
      app.on('hangup_done', function() {
        this.callee = undefined;
        this.render();
      }.bind(this));
    },

    /**
     * Initializes all user entry items with every online user records except
     * the one of currently logged in user, if any.
     */
    initViews: function() {
      if (!this.collection)
        return;
      var callee = this.callee;
      this.views = [];
      this.collection.chain().reject(function(user) {
        // filter out current signed in user, if any
        if (!app.data.user.isLoggedIn())
          return false;
        return user.get('nick') === app.data.user.get('nick');
      }).each(function(user) {
        // create a dedicated list entry for each user
        this.views.push(new app.views.UserEntryView({
          model:  user,
          active: !!(callee &&
                     callee.get('nick') === user.get('nick'))
        }));
      }.bind(this));
    },

    render: function() {
      this.initViews();
      // remove user entries
      this.$('li:not(.nav-header)').remove();
      if (!this.collection)
        return this;
      // render all subviews
      var userList = _.chain(this.views).map(function(view) {
        return view.render();
      }).pluck('el').value();
      this.$('ul').append(userList);
      // show/hide element regarding auth status
      if (app.data.user.isLoggedIn())
        this.$el.show();
      else
        this.$el.hide();
      // show/hide invite if user is alone
      if (this.collection.length === 1) {
        if (!this.activeNotification)
          this.activeNotification =
            app.utils.notifyUI('You are the only person logged in, ' +
                                'invite your friends.', 'info');
      }
      else {
        if (this.activeNotification)
          this.activeNotification.clear();
        this.activeNotification = null;
      }
      return this;
    }
  });

  /**
   * Login/logout forms view.
   */
  app.views.LoginView = Backbone.View.extend({
    el: '#login',

    events: {
      'submit form#signin': 'signin',
      'submit form#signout': 'signout'
    },

    initialize: function() {
      app.data.user = new app.models.User();
      app.data.user.on('change', function(model) {
        if (model.isLoggedIn()) {
          app.trigger('signin', model);
          app.router.navigate('', {trigger: true});
          app.router.index();
          return;
        }

        app.resetApp();
      });
    },

    render: function() {
      if (!app.data.user.get("nick")) {
        this.$('#signin').show();
        this.$('#signout').hide().find('.nick').text('');
      } else {
        this.$('#signin').hide();
        this.$('#signout').show().find('.nick').text(app.data.user.get('nick'));
      }
      return this;
    },

    /**
     * Signs in a user.
     *
     * @param  {FormEvent}  Signin form submit event
     */
    signin: function(event) {
      event.preventDefault();
      var nick = $.trim($(event.currentTarget).find('[name="nick"]').val());
      if (!nick)
        return app.utils.notifyUI('please enter a nickname');
      app.services.login(nick);
    },

    /**
     * Signs out a user.
     *
     * @param  {FormEvent}  Signout form submit event
     */
    signout: function(event) {
      event.preventDefault();
      app.services.logout();
    }
  });

  /**
   * Main video conversation view.
   */
  app.views.CallView = Backbone.View.extend({
    el: '#call',

    // video objects
    local: undefined,
    remote: undefined,

    // The call's peer connection.
    pc: undefined,

    events: {
      'click .btn-hangup': 'hangup'
    },

    initialize: function(options) {
      this.callee = options && options.callee;

      if (!(options && ('model' in options))) {
        throw new Error('No model passed to CallView.initialize()');
      }

      app.trigger('hangup');
      this.local = $('#local-video').get(0);
      this.remote = $('#remote-video').get(0);

      // service events
      app.services.on('call_accepted', function(data) {
        app.media.addAnswerToPeerConnection(
          this.pc,

          data.answer,

          // Nothing to do on success
          function () {},

          function onError(err) {
            app.utils.log(err);
            app.utils.notifyUI('Unable to initiate call', 'error');
          }
        );
      }.bind(this));

      // app events
      app.on('hangup', function () {
        this.hangup();
        this.render();
      }.bind(this));

      app.on('signout', function() {
        // ensure a call is always terminated on user signout
        app.trigger('hangup');
        this.render();
      }.bind(this));

      app.on('add_local_stream', function(stream) {
        this.local.mozSrcObject = stream;
        this.local.play();
      }.bind(this));

      app.on('add_remote_stream', function(stream) {
        this.remote.mozSrcObject = stream;
        this.remote.play();
      }.bind(this));
    },

    /**
     * Initiates the call.
     */
    initiate: function() {
      app.trigger('call', {callee: this.callee});
      app.media.startPeerConnection(
        this.callee,

        this.offer,

        function onSuccess(pc) {
          this.pc = pc;
          this.$('.btn-hangup').removeClass('disabled');
        }.bind(this),

        function onError(err) {
          app.utils.log(err);
          app.utils.notifyUI('Unable to initiate call', 'error');
        });
    },

    /**
     * Hangs up the call.
     */
    hangup: function(event) {
      if (event)
        event.preventDefault();

      // Stop the media elements running
      if (this.local && this.local.mozSrcObject) {
        this.local.mozSrcObject.stop();
        this.local.mozSrcObject = null;
      }
      if (this.remote) {
        this.remote.pause();
        this.remote.mozSrcObject = null;
      }

      // XXX trigger "hangup" event on model here

      app.router.navigate('', {trigger: true});
    },

    render: function() {
      if (!app.data.user || !this.callee) {
        this.$el.hide();
        return this;
      }
      this.$('.callee').text(this.callee.get('nick'));
      this.initiate();
      this.$el.show();
      return this;
    }
  });
})(Talkilla, Backbone, _, jQuery);
<commit_msg>using app.services#postEvent in views<commit_after>/* global Talkilla, Backbone, _, jQuery*/
/**
 * Talkilla Backbone views.
 */
(function(app, Backbone, _, $) {
  "use strict";

  /**
   * Global app view.
   */
  app.views.AppView = Backbone.View.extend({
    el: 'body',

    initialize: function() {
      this.notifications = new app.views.NotificationsView();
      this.login = new app.views.LoginView();
      this.users = new app.views.UsersView();
      this.call = new app.views.CallView({model: new app.models.Call()});
    },

    render: function() {
      this.login.render();
      this.users.render();
      this.call.render();
      return this;
    }
  });

  /**
   * Base notification view.
   */
  app.views.NotificationView = Backbone.View.extend({
    template: _.template([
      '<div class="alert alert-<%= type %>">',
      '  ×',
      '  <%= message %>',
      '
'
    ].join('')),

    clear: function() {
      this.undelegateEvents();
      this.remove();
    },

    render: function() {
      this.$el.html(this.template(this.model.toJSON()));
      return this;
    }
  });

  /**
   * Incoming call notification view.
   */
  app.views.IncomingCallNotificationView = app.views.NotificationView.extend({
    template: _.template([
      '
',
      '
Incoming call from <%= caller %>
',
      '
Do you want to take the call?',
      '    Accept',
      '    Deny',
      '
',
      '
'
    ].join('')),

    events: {
      'click .accept': 'accept',
      'click .deny': 'deny'
    },

    accept: function(event) {
      event.preventDefault();
      var callView = app.router.view.call;
      callView.offer = this.model.get('offer');
      callView.callee = app.data.users.findWhere({
        nick: this.model.get('caller')
      });
      callView.render();
      this.clear();
    },

    deny: function(event) {
      event.preventDefault();
      app.services.postEvent('call_deny', this.model.toJSON());
      this.clear();
    }
  });

  /**
   * Pending call notification view.
   */
  app.views.PendingCallNotificationView = app.views.NotificationView.extend({
    template: _.template([
      '
',
      '  ×',
      '
Calling <%= callee %>…',
      '    Cancel
',
      '
'
    ].join('')),

    events: {
      'click .btn-cancel': 'cancel'
    },

    initialize: function() {
      // app events
      app.on('hangup_done', function() {
        this.clear();
      }.bind(this));
    },

    cancel: function(event) {
      event.preventDefault();
      app.trigger('hangup');
      this.clear();
    }
  });

  /**
   * Denied call notification view.
   */
  app.views.DeniedCallNotificationView = app.views.NotificationView.extend({
    template: _.template([
      '
',
      '  ×',
      '
<%= callee %> declined the call
',
      '
'
    ].join(''))
  });

  /**
   * Notifications list view.
   */
  app.views.NotificationsView = Backbone.View.extend({
    el: '#messages',

    notifications: [],

    initialize: function() {
      // service events
      app.services.on('incoming_call', function(data) {
        var notification = new app.views.IncomingCallNotificationView({
          model: new app.models.IncomingCall(data)
        });
        this.addNotification(notification);
      }.bind(this));

      app.services.on('call_offer', function(data) {
        var notification = new app.views.PendingCallNotificationView({
          model: new app.models.PendingCall(data)
        });
        this.addNotification(notification);
      }.bind(this));

      app.services.on('call_denied', function(data) {
        var notification = new app.views.DeniedCallNotificationView({
          model: new app.models.DeniedCall(data)
        });
        this.addNotification(notification);
      }.bind(this));

      // app events
      app.on('hangup_done', function() {
        this.render();
      }.bind(this));

      app.on('signin', function() {
        this.clear();
      }.bind(this));

      app.on('signout', function() {
        this.clear();
      }.bind(this));
    },

    /**
     * Adds a new notification.
     * @param {app.views.NotificationView} notification
     */
    addNotification: function(notification) {
      var DeniedCallNotificationView = app.views.DeniedCallNotificationView;
      var PendingCallNotificationView = app.views.PendingCallNotificationView;
      var el = notification.render().el;

      this.notifications.push(notification);
      this.$el.append(el);

      // A denied call notification replace a pending call notification
      if (notification instanceof DeniedCallNotificationView)
        this.notifications = this.notifications.filter(function(notif) {
          var isPending = (notif instanceof PendingCallNotificationView);

          if (isPending)
            notif.clear();

          return !isPending;
        });

      return this;
    },

    /**
     * Clear current active notification if any and empty the notifications
     * list.
     */
    clear: function() {
      if (this.notification) {
        this.notification.clear();
        this.notification = undefined;
      }
      this.$el.html('');
    }
  });

  /**
   * User list entry view.
   */
  app.views.UserEntryView = Backbone.View.extend({
    tagName: 'li',

    template: _.template('<a href="#call/<%= nick %>"><%= nick %>'),

    initialize: function(options) {
      this.model = options && options.model;
      this.active = options && options.active;
    },

    render: function() {
      this.$el.html(this.template(this.model.toJSON()));
      if (this.active)
        this.$('a').addClass('active');
      return this;
    }
  });

  /**
   * User list view.
   */
  app.views.UsersView = Backbone.View.extend({
    el: '#users',

    views: [],
    activeNotification: null,

    initialize: function() {
      app.data.users = this.collection = new app.models.UserSet();

      this.collection.on('change', function() {
        this.render();
      }.bind(this));

      this.collection.on('reset', function() {
        this.render();
      }.bind(this));

      // purge the list on sign out
      app.on('signout', function() {
        this.collection.reset();
        this.callee = undefined;
        this.render();
      }.bind(this));

      // highlight callee's username on call
      app.on('call', function(call) {
        this.callee = call && call.callee;
        this.render();
      }.bind(this));

      // unhighlight all usernames on hang up done
      app.on('hangup_done', function() {
        this.callee = undefined;
        this.render();
      }.bind(this));
    },

    /**
     * Initializes all user entry items with every online user records except
     * the one of currently logged in user, if any.
     */
    initViews: function() {
      if (!this.collection)
        return;
      var callee = this.callee;
      this.views = [];
      this.collection.chain().reject(function(user) {
        // filter out current signed in user, if any
        if (!app.data.user.isLoggedIn())
          return false;
        return user.get('nick') === app.data.user.get('nick');
      }).each(function(user) {
        // create a dedicated list entry for each user
        this.views.push(new app.views.UserEntryView({
          model:  user,
          active: !!(callee &&
                     callee.get('nick') === user.get('nick'))
        }));
      }.bind(this));
    },

    render: function() {
      this.initViews();
      // remove user entries
      this.$('li:not(.nav-header)').remove();
      if (!this.collection)
        return this;
      // render all subviews
      var userList = _.chain(this.views).map(function(view) {
        return view.render();
      }).pluck('el').value();
      this.$('ul').append(userList);
      // show/hide element regarding auth status
      if (app.data.user.isLoggedIn())
        this.$el.show();
      else
        this.$el.hide();
      // show/hide invite if user is alone
      if (this.collection.length === 1) {
        if (!this.activeNotification)
          this.activeNotification =
            app.utils.notifyUI('You are the only person logged in, ' +
                                'invite your friends.', 'info');
      }
      else {
        if (this.activeNotification)
          this.activeNotification.clear();
        this.activeNotification = null;
      }
      return this;
    }
  });

  /**
   * Login/logout forms view.
   */
  app.views.LoginView = Backbone.View.extend({
    el: '#login',

    events: {
      'submit form#signin': 'signin',
      'submit form#signout': 'signout'
    },

    initialize: function() {
      app.data.user = new app.models.User();
      app.data.user.on('change', function(model) {
        if (model.isLoggedIn()) {
          app.trigger('signin', model);
          app.router.navigate('', {trigger: true});
          app.router.index();
          return;
        }

        app.resetApp();
      });
    },

    render: function() {
      if (!app.data.user.get("nick")) {
        this.$('#signin').show();
        this.$('#signout').hide().find('.nick').text('');
      } else {
        this.$('#signin').hide();
        this.$('#signout').show().find('.nick').text(app.data.user.get('nick'));
      }
      return this;
    },

    /**
     * Signs in a user.
     *
     * @param  {FormEvent}  Signin form submit event
     */
    signin: function(event) {
      event.preventDefault();
      var nick = $.trim($(event.currentTarget).find('[name="nick"]').val());
      if (!nick)
        return app.utils.notifyUI('please enter a nickname');
      app.services.login(nick);
    },

    /**
     * Signs out a user.
     *
     * @param  {FormEvent}  Signout form submit event
     */
    signout: function(event) {
      event.preventDefault();
      app.services.logout();
    }
  });

  /**
   * Main video conversation view.
   */
  app.views.CallView = Backbone.View.extend({
    el: '#call',

    // video objects
    local: undefined,
    remote: undefined,

    // The call's peer connection.
    pc: undefined,

    events: {
      'click .btn-hangup': 'hangup'
    },

    initialize: function(options) {
      this.callee = options && options.callee;

      if (!(options && ('model' in options))) {
        throw new Error('No model passed to CallView.initialize()');
      }

      app.trigger('hangup');
      this.local = $('#local-video').get(0);
      this.remote = $('#remote-video').get(0);

      // service events
      app.services.on('call_accepted', function(data) {
        app.media.addAnswerToPeerConnection(
          this.pc,

          data.answer,

          // Nothing to do on success
          function () {},

          function onError(err) {
            app.utils.log(err);
            app.utils.notifyUI('Unable to initiate call', 'error');
          }
        );
      }.bind(this));

      // app events
      app.on('hangup', function () {
        this.hangup();
        this.render();
      }.bind(this));

      app.on('signout', function() {
        // ensure a call is always terminated on user signout
        app.trigger('hangup');
        this.render();
      }.bind(this));

      app.on('add_local_stream', function(stream) {
        this.local.mozSrcObject = stream;
        this.local.play();
      }.bind(this));

      app.on('add_remote_stream', function(stream) {
        this.remote.mozSrcObject = stream;
        this.remote.play();
      }.bind(this));
    },

    /**
     * Initiates the call.
     */
    initiate: function() {
      app.trigger('call', {callee: this.callee});
      app.media.startPeerConnection(
        this.callee,

        this.offer,

        function onSuccess(pc) {
          this.pc = pc;
          this.$('.btn-hangup').removeClass('disabled');
        }.bind(this),

        function onError(err) {
          app.utils.log(err);
          app.utils.notifyUI('Unable to initiate call', 'error');
        });
    },

    /**
     * Hangs up the call.
     */
    hangup: function(event) {
      if (event)
        event.preventDefault();

      // Stop the media elements running
      if (this.local && this.local.mozSrcObject) {
        this.local.mozSrcObject.stop();
        this.local.mozSrcObject = null;
      }
      if (this.remote) {
        this.remote.pause();
        this.remote.mozSrcObject = null;
      }

      // XXX trigger "hangup" event on model here

      app.router.navigate('', {trigger: true});
    },

    render: function() {
      if (!app.data.user || !this.callee) {
        this.$el.hide();
        return this;
      }
      this.$('.callee').text(this.callee.get('nick'));
      this.initiate();
      this.$el.show();
      return this;
    }
  });
})(Talkilla, Backbone, _, jQuery);
<|endoftext|>


<commit_before>'use strict';

/* global $, window, socket, ajaxify, app */

var keysToTranslate = [
	'[[qanda:topic_solved]]',
	'[[qanda:topic_unsolved]]',
	'[[qanda:thread.tool.as_question]]',
	'[[qanda:thread.alert.as_question]]',
	'[[qanda:thread.alert.make_normal]]',
	'[[qanda:thread.alert.solved]]',
	'[[qanda:thread.alert.unsolved]]',
	'[[qanda:post.alert.correct_answer]]',
];

var translations = {};

$('document').ready(function () {
	function translate(cb) {
		if (translations.length) {
			return cb();
		}

		require(['translator'], function (translator) {
			translator.translate(keysToTranslate.join(','), function (translated) {
				translated = translated.split(',');

				for (var t = 0; t < keysToTranslate.length; t++) {
					translations[keysToTranslate[t]] = translated[t];
				}

				console.log(translations, translated, keysToTranslate);
				cb();
			});
		});
	}

	$(window).on('action:ajaxify.end', function (ev, data) {
		if (data.url.match(/^topic\//)) {
			translate(function () {
				addLabel();
				markPostAsSolved();
			});
		}
	});

	$(window).on('action:topic.tools.load', addHandlers);
	$(window).on('action:post.tools.load', addPostHandlers);

	$(window).on('action:posts.loaded', markPostAsSolved);

	$(window).on('action:composer.loaded', function (ev, data) {
		translate(function () {
			// Return early if it is a reply and not a new topic
			if (data.hasOwnProperty('composerData') && !data.composerData.isMain) {
				return;
			}

			var item = $('<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"></button>

' + translations['[[qanda:thread.tool.as_question]]'] + '

');
			var actionBar = $('.composer[data-uuid="' + data.post_uuid + '"] .action-bar');

			item.on('click', 'li', function () {
				$(window).one('action:composer.submit', function (ev, data) {
					data.composerData.isQuestion = true;
				});
			});

			actionBar.append(item);
		});
	});

	function addHandlers() {
		$('.toggleQuestionStatus').on('click', toggleQuestionStatus);
		$('.toggleSolved').on('click', toggleSolved);
	}

	function addPostHandlers() {
		$('[component="qanda/post-solved"]').on('click', markPostAsAnswer);
	}

	function addLabel() {
		if (ajaxify.data.hasOwnProperty('isQuestion') && parseInt(ajaxify.data.isQuestion, 10) === 1) {
			require(['components'], function (components) {
				if (parseInt(ajaxify.data.isSolved, 10) === 0) {
					components.get('post/header').prepend(' ' + translations['[[qanda:topic_unsolved]]'] + '');
				} else if (parseInt(ajaxify.data.isSolved, 10) === 1) {
					components.get('post/header').prepend(' ' + translations['[[qanda:topic_solved]]'] + '');
				}
			});
		}
	}

	function toggleQuestionStatus() {
		var tid = ajaxify.data.tid;
		callToggleQuestion(tid, true);
	}

	function callToggleQuestion(tid, refresh) {
		socket.emit('plugins.QandA.toggleQuestionStatus', { tid: tid }, function (err, data) {
			if (err) {
				return app.alertError(err);
			}

			app.alertSuccess(translations[data.isQuestion ? '[[qanda:thread.alert.as_question]]' : '[[qanda:thread.alert.make_normal]]']);
			if (refresh) {
				ajaxify.refresh();
			}
		});
	}

	function toggleSolved() {
		var tid = ajaxify.data.tid;
		socket.emit('plugins.QandA.toggleSolved', { tid: tid }, function (err, data) {
			if (err) {
				return app.alertError(err);
			}

			app.alertSuccess(translations[data.isSolved ? '[[qanda:thread.alert.solved]]' : '[[qanda:thread.alert.unsolved]]']);
			ajaxify.refresh();
		});
	}

	function markPostAsAnswer() {
		var tid = ajaxify.data.tid;
		var pid = $(this).parents('[data-pid]').attr('data-pid');

		socket.emit('plugins.QandA.toggleSolved', { tid: tid, pid: pid }, function (err, data) {
			if (err) {
				return app.alertError(err);
			}

			app.alertSuccess(translations[data.isSolved ? '[[qanda:post.alert.correct_answer]]' : '[[qanda:thread.alert.unsolved]]']);
			ajaxify.refresh();
		});
	}

	function markPostAsSolved() {
		translate(function () {
			if (ajaxify.data.pagination.currentPage === 1) {
				$('[component="post"][data-pid="' + ajaxify.data.solvedPid + '"]').addClass('isSolved');
				$('[component="post"][data-pid="' + ajaxify.data.solvedPid + '"][data-index="-1"] .post-footer').addClass('hidden');
			}
		});
	}
});
<commit_msg>remove console.log<commit_after>'use strict';

/* global $, window, socket, ajaxify, app */

var keysToTranslate = [
	'[[qanda:topic_solved]]',
	'[[qanda:topic_unsolved]]',
	'[[qanda:thread.tool.as_question]]',
	'[[qanda:thread.alert.as_question]]',
	'[[qanda:thread.alert.make_normal]]',
	'[[qanda:thread.alert.solved]]',
	'[[qanda:thread.alert.unsolved]]',
	'[[qanda:post.alert.correct_answer]]',
];

var translations = {};

$('document').ready(function () {
	function translate(cb) {
		if (translations.length) {
			return cb();
		}

		require(['translator'], function (translator) {
			translator.translate(keysToTranslate.join(','), function (translated) {
				translated = translated.split(',');

				for (var t = 0; t < keysToTranslate.length; t++) {
					translations[keysToTranslate[t]] = translated[t];
				}

				cb();
			});
		});
	}

	$(window).on('action:ajaxify.end', function (ev, data) {
		if (data.url.match(/^topic\//)) {
			translate(function () {
				addLabel();
				markPostAsSolved();
			});
		}
	});

	$(window).on('action:topic.tools.load', addHandlers);
	$(window).on('action:post.tools.load', addPostHandlers);

	$(window).on('action:posts.loaded', markPostAsSolved);

	$(window).on('action:composer.loaded', function (ev, data) {
		translate(function () {
			// Return early if it is a reply and not a new topic
			if (data.hasOwnProperty('composerData') && !data.composerData.isMain) {
				return;
			}

			var item = $('<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"></button>

' + translations['[[qanda:thread.tool.as_question]]'] + '

');
			var actionBar = $('.composer[data-uuid="' + data.post_uuid + '"] .action-bar');

			item.on('click', 'li', function () {
				$(window).one('action:composer.submit', function (ev, data) {
					data.composerData.isQuestion = true;
				});
			});

			actionBar.append(item);
		});
	});

	function addHandlers() {
		$('.toggleQuestionStatus').on('click', toggleQuestionStatus);
		$('.toggleSolved').on('click', toggleSolved);
	}

	function addPostHandlers() {
		$('[component="qanda/post-solved"]').on('click', markPostAsAnswer);
	}

	function addLabel() {
		if (ajaxify.data.hasOwnProperty('isQuestion') && parseInt(ajaxify.data.isQuestion, 10) === 1) {
			require(['components'], function (components) {
				if (parseInt(ajaxify.data.isSolved, 10) === 0) {
					components.get('post/header').prepend(' ' + translations['[[qanda:topic_unsolved]]'] + '');
				} else if (parseInt(ajaxify.data.isSolved, 10) === 1) {
					components.get('post/header').prepend(' ' + translations['[[qanda:topic_solved]]'] + '');
				}
			});
		}
	}

	function toggleQuestionStatus() {
		var tid = ajaxify.data.tid;
		callToggleQuestion(tid, true);
	}

	function callToggleQuestion(tid, refresh) {
		socket.emit('plugins.QandA.toggleQuestionStatus', { tid: tid }, function (err, data) {
			if (err) {
				return app.alertError(err);
			}

			app.alertSuccess(translations[data.isQuestion ? '[[qanda:thread.alert.as_question]]' : '[[qanda:thread.alert.make_normal]]']);
			if (refresh) {
				ajaxify.refresh();
			}
		});
	}

	function toggleSolved() {
		var tid = ajaxify.data.tid;
		socket.emit('plugins.QandA.toggleSolved', { tid: tid }, function (err, data) {
			if (err) {
				return app.alertError(err);
			}

			app.alertSuccess(translations[data.isSolved ? '[[qanda:thread.alert.solved]]' : '[[qanda:thread.alert.unsolved]]']);
			ajaxify.refresh();
		});
	}

	function markPostAsAnswer() {
		var tid = ajaxify.data.tid;
		var pid = $(this).parents('[data-pid]').attr('data-pid');

		socket.emit('plugins.QandA.toggleSolved', { tid: tid, pid: pid }, function (err, data) {
			if (err) {
				return app.alertError(err);
			}

			app.alertSuccess(translations[data.isSolved ? '[[qanda:post.alert.correct_answer]]' : '[[qanda:thread.alert.unsolved]]']);
			ajaxify.refresh();
		});
	}

	function markPostAsSolved() {
		translate(function () {
			if (ajaxify.data.pagination.currentPage === 1) {
				$('[component="post"][data-pid="' + ajaxify.data.solvedPid + '"]').addClass('isSolved');
				$('[component="post"][data-pid="' + ajaxify.data.solvedPid + '"][data-index="-1"] .post-footer').addClass('hidden');
			}
		});
	}
});
<|endoftext|>


<commit_before>// Queue handler for ajax requests
ajax_handler = [];

// Abort any unfinished ajax requests
function kill_ajax() {
    $.each(ajax_handler, function( index, value ) { value.abort() });
    ajax_handler.length = 0;
}

// Submit for all records
function run_records(form_data) {

    var records = [ "Recent", "RecentThreat",  "RecentCert", "WhoIs", "HistoricalDNS", "Historical", "Malware", "SafeBrowsing", "Search", "External", "DNSTwist" ];

    $.each(records, function( index, record ) {
        // Clear out old information from DOM elements and submit new ajax requests
        $(record).empty();

        // Push additional form data to differentiate ajax requests
        form_data.push({name: 'record_type', value: record});

        send_ajax(form_data, record);

        // Pop off additional form data to in preparation for next request
        form_data.pop();
    });
}

// Submit request for record
function send_ajax(form_data, record){

    var record_element = "#" + record + "Panel";

    ajax_handler.push(
        $.ajax({
            type:"POST",
            url:"/pivoteer/",
            data: form_data,
            beforeSend: function(xhr, settings) {
                $(record_element).html("
Retrieving data
");
                $('a[href='+record_element+']').find("span").attr("class", "glyphicon glyphicon-hourglass");
            },

            error: function (){
                $( record_element ).html('
Unable to retrieve records
');
                $('a[href='+record_element+']').find("span").attr("class", "glyphicon glyphicon-exclamation-sign");
            },

            success: function (task){
                if (task.errors) {
                    $( record_element ).html(task.errors.indicator);
                    $('a[href='+record_element+']').find("span").attr("class", "glyphicon glyphicon-exclamation-sign");
                } else {
                    poll_ajax(task.id, record_element);
                }
            }
        })
    );
}

// Poll for record completion
function poll_ajax(task, record_element){

    var parameters = {task_id: task};

    $.ajax({
        type:"POST",
        url:"/pivoteer/tasks/",
        data: parameters,

        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        },

        error: function (){
            $(record_element).html('
Unable to retrieve records
');
        },

        success: function (task_results){
            if (task_results.status == 'loading') {
                setTimeout(function() { poll_ajax(task, record_element); }, 6000); // wait 3 seconds then call ajax request again
            } else {
                $(record_element).html(task_results);
                initialize_table(record_element);
                $('a[href='+record_element+']').find("span").attr("class", "glyphicon glyphicon-ok-sign");
            }
        }

    });
}

// Initiate data table elements on returned records
function initialize_table(record_element) {

    if (record_element == '#RecentPanel') {
        $('#CR_table').dataTable({
            "iDisplayLength": 15,
            "bInfo": false,
            "bLengthChange": false,
            "bFilter": true,
            "aaSorting": [[2, "desc"]]
        });

    }  else if (record_element == '#WhoIsPanel') {

        $('#CW_table').dataTable({
            "iDisplayLength":  10,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         false,
            "aaSorting":      [[0, "desc"]]
        });

        $('#HW_table').dataTable({
            "iDisplayLength":  10,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         false,
            "aaSorting":      [[1, "desc"]]
        });

    } else if (record_element == "#HistoricalDNSPanel") {
        $('#HR_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         true,
            "aaSorting":      [[3, "desc"]]
        });

    } else if (record_element == "#HistoricalPanel") {
        $('#HRD_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         true,
            "aaSorting":      [[3, "desc"]]
        });

    } else if (record_element == "#MalwarePanel") {
        $('#MR_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         true,
            "aaSorting":      [[0, "desc"]]
        });
    } else if (record_element == "#SafeBrowsingPanel") {
        $('#SB_table').dataTable({
            "iDisplayLength": 50,
            "info": false,
            "bLengthChange": false,
            "bFilter": true,
            "aaSorting":      [[0, "desc"]]
        });
    } else if (record_element == "#SearchPanel") {
        $('#SR_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bSort":           false
        });
    } else if (record_element == "#DNSTwistPanel") {
        $('#DT_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":true,
            "aaSorting":      [[0, "desc"]]
        })

    }
}

// Cookie Handling Using jQuery
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

var csrftoken = getCookie('csrftoken');
// End Cookie Handling

// Custom method on form submission to begin research
$('#research_indicator').submit(function( event ){
    event.preventDefault();
    kill_ajax();

    $("#pivot_navigator").show();

    // Populate data for ajax and DOM manipulation
    var entry = $('input[name=indicator]').val();
    var form_data = $('#research_indicator').serializeArray();

    // Clear out pivot navigation menu and insert new initial entry
    $("#pivot_navigator").empty().append("
" + entry + "
");

    run_records(form_data);
});

$('#content').on('click', '.pivot', function( event ){
    kill_ajax();

    $("#pivot_navigator").show();

    var pivot = $(this).text();
    var pivot_data = [{name: "indicator", value: pivot}, {name: "csrfmiddlewaretoken", value: csrftoken}];

    // Check if this is a back pivot or a new pivot
    if ($(this).hasClass('tracking')){
        $( '.pivot' ).parent().slice($(this).parent().index() + 1).remove();
    }
    else {
        $("#pivot_navigator").append("
" + pivot + "
");
    }

    run_records(pivot_data);
});

// Manipulate displayed elements upon initial page load
$( document ).ready(function() {
    $("#pivot_navigator").hide();
});

$("#export").on( "click", "a", function(event) {
    // Capture link event
    event.preventDefault();

    // Grab reference to link within event context
    var link = $(this);
    var linkURL = link.attr("href");
    var current_pivot = $("#pivot_navigator").find("li").last().find("span").text();
    var connector = -1 === linkURL.indexOf("?") ? "?" : "&";
    var fullURL = linkURL + connector + "indicator=" + current_pivot;
    window.open(fullURL);
});<commit_msg>Updated correct table id with corresponding html page<commit_after>// Queue handler for ajax requests
ajax_handler = [];

// Abort any unfinished ajax requests
function kill_ajax() {
    $.each(ajax_handler, function( index, value ) { value.abort() });
    ajax_handler.length = 0;
}

// Submit for all records
function run_records(form_data) {

    var records = [ "Recent", "RecentThreat",  "RecentCert", "WhoIs", "HistoricalDNS", "Historical", "Malware", "SafeBrowsing", "Search", "External", "DNSTwist" ];

    $.each(records, function( index, record ) {
        // Clear out old information from DOM elements and submit new ajax requests
        $(record).empty();

        // Push additional form data to differentiate ajax requests
        form_data.push({name: 'record_type', value: record});

        send_ajax(form_data, record);

        // Pop off additional form data to in preparation for next request
        form_data.pop();
    });
}

// Submit request for record
function send_ajax(form_data, record){

    var record_element = "#" + record + "Panel";

    ajax_handler.push(
        $.ajax({
            type:"POST",
            url:"/pivoteer/",
            data: form_data,
            beforeSend: function(xhr, settings) {
                $(record_element).html("
Retrieving data
");
                $('a[href='+record_element+']').find("span").attr("class", "glyphicon glyphicon-hourglass");
            },

            error: function (){
                $( record_element ).html('
Unable to retrieve records
');
                $('a[href='+record_element+']').find("span").attr("class", "glyphicon glyphicon-exclamation-sign");
            },

            success: function (task){
                if (task.errors) {
                    $( record_element ).html(task.errors.indicator);
                    $('a[href='+record_element+']').find("span").attr("class", "glyphicon glyphicon-exclamation-sign");
                } else {
                    poll_ajax(task.id, record_element);
                }
            }
        })
    );
}

// Poll for record completion
function poll_ajax(task, record_element){

    var parameters = {task_id: task};

    $.ajax({
        type:"POST",
        url:"/pivoteer/tasks/",
        data: parameters,

        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        },

        error: function (){
            $(record_element).html('
Unable to retrieve records
');
        },

        success: function (task_results){
            if (task_results.status == 'loading') {
                setTimeout(function() { poll_ajax(task, record_element); }, 6000); // wait 3 seconds then call ajax request again
            } else {
                $(record_element).html(task_results);
                initialize_table(record_element);
                $('a[href='+record_element+']').find("span").attr("class", "glyphicon glyphicon-ok-sign");
            }
        }

    });
}

// Initiate data table elements on returned records
function initialize_table(record_element) {

    if (record_element == '#RecentPanel') {
        $('#CR_table').dataTable({
            "iDisplayLength": 15,
            "bInfo": false,
            "bLengthChange": false,
            "bFilter": true,
            "aaSorting": [[2, "desc"]]
        });

    }  else if (record_element == '#WhoIsPanel') {

        $('#CW_table').dataTable({
            "iDisplayLength":  10,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         false,
            "aaSorting":      [[0, "desc"]]
        });

        $('#HW_table').dataTable({
            "iDisplayLength":  10,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         false,
            "aaSorting":      [[1, "desc"]]
        });

    } else if (record_element == "#HistoricalDNSPanel") {
        $('#HRD_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         true,
            "aaSorting":      [[3, "desc"]]
        });

    } else if (record_element == "#HistoricalPanel") {
        $('#HR_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         true,
            "aaSorting":      [[3, "desc"]]
        });

    } else if (record_element == "#MalwarePanel") {
        $('#MR_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":         true,
            "aaSorting":      [[0, "desc"]]
        });
    } else if (record_element == "#SafeBrowsingPanel") {
        $('#SB_table').dataTable({
            "iDisplayLength": 50,
            "info": false,
            "bLengthChange": false,
            "bFilter": true,
            "aaSorting":      [[0, "desc"]]
        });
    } else if (record_element == "#SearchPanel") {
        $('#SR_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bSort":           false
        });
    } else if (record_element == "#DNSTwistPanel") {
        $('#DT_table').dataTable({
            "iDisplayLength":  50,
            "bInfo":            false,
            "bLengthChange":   false,
            "bFilter":true,
            "aaSorting":      [[0, "desc"]]
        })

    }
}

// Cookie Handling Using jQuery
function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

var csrftoken = getCookie('csrftoken');
// End Cookie Handling

// Custom method on form submission to begin research
$('#research_indicator').submit(function( event ){
    event.preventDefault();
    kill_ajax();

    $("#pivot_navigator").show();

    // Populate data for ajax and DOM manipulation
    var entry = $('input[name=indicator]').val();
    var form_data = $('#research_indicator').serializeArray();

    // Clear out pivot navigation menu and insert new initial entry
    $("#pivot_navigator").empty().append("
" + entry + "
");

    run_records(form_data);
});

$('#content').on('click', '.pivot', function( event ){
    kill_ajax();

    $("#pivot_navigator").show();

    var pivot = $(this).text();
    var pivot_data = [{name: "indicator", value: pivot}, {name: "csrfmiddlewaretoken", value: csrftoken}];

    // Check if this is a back pivot or a new pivot
    if ($(this).hasClass('tracking')){
        $( '.pivot' ).parent().slice($(this).parent().index() + 1).remove();
    }
    else {
        $("#pivot_navigator").append("
" + pivot + "
");
    }

    run_records(pivot_data);
});

// Manipulate displayed elements upon initial page load
$( document ).ready(function() {
    $("#pivot_navigator").hide();
});

$("#export").on( "click", "a", function(event) {
    // Capture link event
    event.preventDefault();

    // Grab reference to link within event context
    var link = $(this);
    var linkURL = link.attr("href");
    var current_pivot = $("#pivot_navigator").find("li").last().find("span").text();
    var connector = -1 === linkURL.indexOf("?") ? "?" : "&";
    var fullURL = linkURL + connector + "indicator=" + current_pivot;
    window.open(fullURL);
});<|endoftext|>


<commit_before>'use strict';

// set up SVG for D3
var width  = 960,
    height = 500,
    selected_node = null,
    selected_link = null,
    mousedown_link = null,
    mousedown_node = null,
    mouseup_node = null,
    editing = false;

var svg = d3.select('#graph')
  .append('svg')
  .attr('oncontextmenu', 'return false;')
  .attr('width', width)
  .attr('height', height);

window.graph.links.forEach(function(link) {
  window.graph.nodes.forEach(function(node) {
    if (node.id === link.source.id) {
      link.source = node;
    }
    if (node.id === link.target.id) {
      link.target = node;
    }
  });
});

// init D3 force layout
var force = d3.layout.force()
    .nodes(window.graph.nodes)
    .links(window.graph.links)
    .size([width, height])
    .linkDistance(function(d) { return Math.log(3 / d.strength * 10) * 50; })
    .charge(-500)
    .on('tick', tick)

// line displayed when dragging new nodes
var drag_line = svg.append('line')
  .attr('class', 'link dragline hidden');

// handles to link and node element groups
var path = svg.append('g').selectAll('.link'),
    node = svg.append('g').selectAll('.node');

// update force layout (called automatically each iteration)
function tick() {
  if (!drag_line.classed('hidden')) {
    return;
  }
  path.select('line')
    .attr('x1', function(d) { return d.source.x; })
    .attr('y1', function(d) { return d.source.y; })
    .attr('x2', function(d) { return d.target.x; })
    .attr('y2', function(d) { return d.target.y; })
  path.select('.source-text')
    .attr('dx', function(d) { return d.source.x})
    .attr('dy', function(d) { return d.source.y + d.source.r * 2});
  path.select('.target-text')
    .attr('dx', function(d) { return d.target.x})
    .attr('dy', function(d) { return d.target.y + d.target.r * 2});
  path.select('.center-text')
    .attr('dx', function(d) {
        return (d.source.x + ((d.target.x - d.source.x) / 2));
    })
    .attr('dy', function(d) {
        return (d.source.y + ((d.target.y - d.source.y) / 2)) - 10;
    });
  node.attr('transform', function(d) {
    return 'translate(' + d.x + ',' + d.y + ')';
  });
}

// update graph (called when needed)
function restart() {
  // path (link) group
  path = path.data(window.graph.links);

  // update existing links
  path.classed('selected', function(d) { return d === selected_link; });

  // add new links
  var pathG = path.enter()
    .append('g')
    .classed('link', true)
    .classed('selected', function(d) { return d === selected_link; });
  pathG.append('line')
    .attr('x1', function(d) { return d.source.x; })
    .attr('y1', function(d) { return d.source.y; })
    .attr('x2', function(d) { return d.target.x; })
    .attr('y2', function(d) { return d.target.y; })
    .attr('stroke-width', function(d) { return d.strength; })
    .attr('stroke-dasharray', function(d) {
      if (d.dashed) {
        return '' + [d.strength / 1.5, d.strength / 1.5];
      }
    });
  pathG.append('text')
    .attr('class', 'center-text meaning hidden');
  pathG.append('text')
    .attr('class', 'source-text meaning hidden');
  pathG.append('text')
    .attr('class', 'target-text meaning hidden');
  // remove old links
  path.exit().remove();

  path.select('line')
    .attr('stroke-width', function(d) { return d.strength; })
    .attr('stroke-dasharray', function(d) {
      if (d.dashed) {
        return '' + [d.strength / 1.5, d.strength / 1.5];
      }
    });
  path.select('.center-text')
    .text(function(d) { return d.centerText; });
  path.select('.source-text')
    .text(function(d) { return d.sourceText; });
  path.select('.target-text')
    .text(function(d) { return d.targetText; });
  path.on('mouseover', function(d) {
      d3.select(this).selectAll('.meaning')
        .classed('hidden', false);
    })
    .on('mouseout', function(d) {
      d3.select(this).selectAll('.meaning')
        .classed('hidden', true);
    });

  // circle (node) group
  // NB: the function arg is crucial here! nodes are known by id, not by index!
  node = node.data(window.graph.nodes, function(d) { return d.id; });

  // add new nodes
  var nodeG = node.enter()
    .append('g')
    .classed('node', true);

  nodeG.append('circle')
    .attr('class', 'node')
    .attr('r', function(d) { return d.r; })
    .attr('style', function(d) {
      if (d.dashed) {
        return 'fill:#ccc!important';
      }
    })
    .attr('stroke-dasharray', function(d) {
      if (d.dashed) {
        return '' + [d.r / 4, d.r / 4];
      }
    });

  // show node IDs
  nodeG.append('text')
    .attr('x', 0)
    .attr('y', function(d) { return -d.r - 2; })
    .attr('class', 'id')
    .attr('text-anchor', 'middle')
    .text(function(d) { return d.name; });

  node.select('circle')
    .attr('r', function(d) { return d.r; })
    .attr('style', function(d) {
      if (d.dashed) {
        return 'fill:#ccc!important';
      }
    })
    .attr('stroke-dasharray', function(d) {
      if (d.dashed) {
        return '' + [d.r / 4, d.r / 4];
      }
    });

  node.select('.id')
    .attr('y', function(d) { return -d.r - 2; })
    .text(function(d) { return d.name; });

  // remove old nodes
  node.exit().remove();

  // set the graph in motion
  force.start();
  if (d3.select('#graph').classed('build')) {
    try {
      writeGraph();
    } catch(e) {
      console.log(e);
    }
  } else {
    node.call(force.drag);
  }
}

// app starts here
restart();
<commit_msg>Turn off text selection for the polycule graph. This was causing weird behavior when editing<commit_after>'use strict';

// set up SVG for D3
var width  = 960,
    height = 500,
    selected_node = null,
    selected_link = null,
    mousedown_link = null,
    mousedown_node = null,
    mouseup_node = null,
    editing = false;

var svg = d3.select('#graph')
  .append('svg')
  .attr('oncontextmenu', 'return false;')
  .attr('style', '-moz-user-select: none; -webkit-user-select: none; -ms-user-select:none; user-select:none;-o-user-select:none;')
  .attr('width', width)
  .attr('height', height);

window.graph.links.forEach(function(link) {
  window.graph.nodes.forEach(function(node) {
    if (node.id === link.source.id) {
      link.source = node;
    }
    if (node.id === link.target.id) {
      link.target = node;
    }
  });
});

// init D3 force layout
var force = d3.layout.force()
    .nodes(window.graph.nodes)
    .links(window.graph.links)
    .size([width, height])
    .linkDistance(function(d) { return Math.log(3 / d.strength * 10) * 50; })
    .charge(-500)
    .on('tick', tick)

// line displayed when dragging new nodes
var drag_line = svg.append('line')
  .attr('class', 'link dragline hidden');

// handles to link and node element groups
var path = svg.append('g').selectAll('.link'),
    node = svg.append('g').selectAll('.node');

// update force layout (called automatically each iteration)
function tick() {
  if (!drag_line.classed('hidden')) {
    return;
  }
  path.select('line')
    .attr('x1', function(d) { return d.source.x; })
    .attr('y1', function(d) { return d.source.y; })
    .attr('x2', function(d) { return d.target.x; })
    .attr('y2', function(d) { return d.target.y; })
  path.select('.source-text')
    .attr('dx', function(d) { return d.source.x})
    .attr('dy', function(d) { return d.source.y + d.source.r * 2});
  path.select('.target-text')
    .attr('dx', function(d) { return d.target.x})
    .attr('dy', function(d) { return d.target.y + d.target.r * 2});
  path.select('.center-text')
    .attr('dx', function(d) {
        return (d.source.x + ((d.target.x - d.source.x) / 2));
    })
    .attr('dy', function(d) {
        return (d.source.y + ((d.target.y - d.source.y) / 2)) - 10;
    });
  node.attr('transform', function(d) {
    return 'translate(' + d.x + ',' + d.y + ')';
  });
}

// update graph (called when needed)
function restart() {
  // path (link) group
  path = path.data(window.graph.links);

  // update existing links
  path.classed('selected', function(d) { return d === selected_link; });

  // add new links
  var pathG = path.enter()
    .append('g')
    .classed('link', true)
    .classed('selected', function(d) { return d === selected_link; });
  pathG.append('line')
    .attr('x1', function(d) { return d.source.x; })
    .attr('y1', function(d) { return d.source.y; })
    .attr('x2', function(d) { return d.target.x; })
    .attr('y2', function(d) { return d.target.y; })
    .attr('stroke-width', function(d) { return d.strength; })
    .attr('stroke-dasharray', function(d) {
      if (d.dashed) {
        return '' + [d.strength / 1.5, d.strength / 1.5];
      }
    });
  pathG.append('text')
    .attr('class', 'center-text meaning hidden');
  pathG.append('text')
    .attr('class', 'source-text meaning hidden');
  pathG.append('text')
    .attr('class', 'target-text meaning hidden');
  // remove old links
  path.exit().remove();

  path.select('line')
    .attr('stroke-width', function(d) { return d.strength; })
    .attr('stroke-dasharray', function(d) {
      if (d.dashed) {
        return '' + [d.strength / 1.5, d.strength / 1.5];
      }
    });
  path.select('.center-text')
    .text(function(d) { return d.centerText; });
  path.select('.source-text')
    .text(function(d) { return d.sourceText; });
  path.select('.target-text')
    .text(function(d) { return d.targetText; });
  path.on('mouseover', function(d) {
      d3.select(this).selectAll('.meaning')
        .classed('hidden', false);
    })
    .on('mouseout', function(d) {
      d3.select(this).selectAll('.meaning')
        .classed('hidden', true);
    });

  // circle (node) group
  // NB: the function arg is crucial here! nodes are known by id, not by index!
  node = node.data(window.graph.nodes, function(d) { return d.id; });

  // add new nodes
  var nodeG = node.enter()
    .append('g')
    .classed('node', true);

  nodeG.append('circle')
    .attr('class', 'node')
    .attr('r', function(d) { return d.r; })
    .attr('style', function(d) {
      if (d.dashed) {
        return 'fill:#ccc!important';
      }
    })
    .attr('stroke-dasharray', function(d) {
      if (d.dashed) {
        return '' + [d.r / 4, d.r / 4];
      }
    });

  // show node IDs
  nodeG.append('text')
    .attr('x', 0)
    .attr('y', function(d) { return -d.r - 2; })
    .attr('class', 'id')
    .attr('text-anchor', 'middle')
    .text(function(d) { return d.name; });

  node.select('circle')
    .attr('r', function(d) { return d.r; })
    .attr('style', function(d) {
      if (d.dashed) {
        return 'fill:#ccc!important';
      }
    })
    .attr('stroke-dasharray', function(d) {
      if (d.dashed) {
        return '' + [d.r / 4, d.r / 4];
      }
    });

  node.select('.id')
    .attr('y', function(d) { return -d.r - 2; })
    .text(function(d) { return d.name; });

  // remove old nodes
  node.exit().remove();

  // set the graph in motion
  force.start();
  if (d3.select('#graph').classed('build')) {
    try {
      writeGraph();
    } catch(e) {
      console.log(e);
    }
  } else {
    node.call(force.drag);
  }
}

// app starts here
restart();
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import {Tabs, Tab, ButtonToolbar, Button, FormControl,
	FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap';
import ReactAddonsLinkedStateMixin from 'react-addons-linked-state-mixin';
import {AgGridReact} from 'ag-grid-react';
import LoginForm from './login-form';
import ConnectionTable from './tables/connection-table';
import SampleTable from './tables/sample-table';
import OrderTable from './tables/order-table';
import OrderForm from './order-form';
import PositionTable from './tables/position-table';
import TradeTable from './tables/trade-table';
import AccountTable from './tables/account-table';
import TickerControl from './ticker-control';

var SubscribeBox = React.createClass( {
    getInitialState: function() {
	return {};
    },
    componentDidMount: function() {
	var source = new EventSource(this.props.url);
	var obj = this;
	$.each(this.props.event, function(k, v) {
	    source.addEventListener(k, v);
	});
    },
    render: function() {
        return null;
    }
});

var Injector = React.createClass( {
    mixins: [ReactAddonsLinkedStateMixin],
    getInitialState: function() {
	return {message: 'Hello!',
		textinput : ''};
    },
    inject : function() {
	var self = this;
	jQuery.ajax({
	    url: "/inject",
	    type: "POST",
	    data: self.state.textinput,
	    contentType: "application/json; charset=utf-8",
	    success: function (response) {
		self.setState({message: response});
	    }
	});
    },
    injectTest : function() {
	this.setState({message : "test inject"});
    },
    clear: function() {
	this.setState({textinput : ''});
    },
    fileOpen: function(e) {
	var self = this;
	var files = e.target.files,
	    reader = new FileReader();
	reader.onload = function() {
	    self.setState({textinput: this.result});
	}
	reader.readAsText(files[0]);
    },
    render: function() {
	return (

<Button bsStyle="success" onClick={this.inject}>Inject</Button>
<Button bsStyle="success" onClick={this.clear}>Clear</Button>
<Button bsStyle="success" onClick={this.injectTest}>Test</Button>
<FormControl componentClass="file" onChange={this.fileOpen} />
<FormControl componentClass="textarea" valueLink={this.linkState('textinput')} />
<FormControl componentClass="textarea" valueLink={this.linkState('message')} />

	);
    }
});

function publish() {
    $.get("/ping");
};

var columns = [
    { name : 'index' },
    { name : 'firstName' },
    { name : 'city' }
]

var data = [];

function FieldGroup({ id, label, help, ...props }) {
  return (

      {label}
      <FormControl {...props} />
      {help && <HelpBlock>{help}</HelpBlock>}

  );
}
console.log("New SPTrader");

var SpTraderApp = React.createClass({
    getInitialState: function() {
	var l = this;
	$.getJSON("/login-status/80", function(d) {
	    if (parseInt(d) != -1) {
		l.setState({showLoginForm: false});
	    }
	});

	return {
	    log: '',
	    loginLabel: '',
	    account_info: {},
	    connection_info: {},
	    showLoginForm: true,
	    showOrderForm: false,
	    tickers: [],
	    orders: [],
	    trades: []
	};
    },
    submitModal: function(data) {
	$.ajax({
	    type: 'post',
	    url: '/login',
	    data: JSON.stringify(data),
	    contentType: "application/json"
	});
    },
    logout: function() {
	$.get("/logout");
	this.setState({loginLabel: ''});
	this.setState({showLoginForm: true});
    },
    addToLog: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({log: this.state.log + event.data + "\n"});
    },
    loginReply: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({log: this.state.log + event.data + "\n"});
	if (parseInt(data.ret_code) != 0) {
	    this.setState({loginLabel: data.ret_msg});
	} else {
	    this.setState({showLoginForm: false});
	}
    },
    connectedReply: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({log: this.state.log + event.data + "\n"});
	var conn_info = this.state.connection_info;
	var host_type = parseInt(data.host_type);
	var con_status = parseInt(data.con_status);
	conn_info[host_type] = con_status;
	this.setState({conn_info: conn_info})
	if (parseInt(host_type) == 80 &&
	    parseInt(con_status) == 2) {
	    var l = this;
	    $.getJSON("/ticker/list", function(d) {
		l.setState({tickers: d.data});
	    });
	    $.getJSON("/account-info");
	    $.getJSON("/order/list", function(d) {
		l.setState({orders: d.data});
		});
	    $.getJSON("/trade/list", function(d) {
		l.setState({trades: d.data});
	    });
	}
    },
    showOrderForm: function(event) {
	this.setState({showOrderForm: true});
    },
    submitOrder: function(event) {
	this.setState({showOrderForm: false});
    },
    accountInfoPush: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({log: this.state.log + event.data + "\n"});
	this.setState({account_info: data});
    },
    updateTickers: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({tickers: data.data});
    },
    render: function() {
	var events = {
	    "ping" : this.addToLog,
	    "LoginReply" : this.loginReply,
	    "ConnectedReply" : this.connectedReply,
	    "AccountInfoPush" : this.accountInfoPush,
	    "UpdateTickers" : this.updateTickers
	}
	return(
		<Tabs id="tabs">
		<Tab eventKey={1} title="Login">
		<LoginForm show={this.state.showLoginForm}
	    label={this.state.loginLabel}
	    onSubmit={this.submitModal}/>
		<Button bsStyle="success" onClick={this.logout}>Logout</Button>
		<ConnectionTable data={this.state.connection_info}/>
		<Tabs id="tab1">
		<Tab eventKey={1} title="Account">
		<AccountTable data={this.state.account_info} />
		</Tab>
		<Tab eventKey={2} title="Order">
		<OrderForm show={this.state.showOrderForm}
	    onSubmit={this.submitOrder}/>
		<Button bsStyle="success" onClick={this.showOrderForm}>Show Order</Button>
		<OrderTable data={this.state.orders} />
		</Tab>
		<Tab eventKey={3} title="Position">
		<PositionTable />
		</Tab>
		<Tab eventKey={4} title="Trade">
		<TradeTable data={this.state.trades}/>
		</Tab>
		<Tab eventKey={5} title="Ticker">
		<TickerControl tickers={this.state.tickers}/>
		</Tab>
		</Tabs>
		</Tab>
		<Tab eventKey={2} title="Strategies">
		</Tab>
		<Tab eventKey={3} title="Scratchpad">
		<ButtonToolbar>
		<Button bsStyle="success" onClick={publish}>Ping</Button>
		</ButtonToolbar>
		<SubscribeBox url="/log/subscribe" event={events} />
		<FormControl componentClass="textarea" value={this.state.log} />
		<SampleTable/>
		</Tab>
		</Tabs>
	)
    }
});

var helloWorld = React.createClass({
    render: function() {
	return (
Greetings from SPTrader
)
    }
});

ReactDOM.render(
    <helloWorld />,
    document.getElementById('content')
);

ReactDOM.render(
    <SpTraderApp />,
    document.getElementById('test')
);
<commit_msg>add all events<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import {Tabs, Tab, ButtonToolbar, Button, FormControl,
	FormGroup, ControlLabel, HelpBlock } from 'react-bootstrap';
import ReactAddonsLinkedStateMixin from 'react-addons-linked-state-mixin';
import {AgGridReact} from 'ag-grid-react';
import LoginForm from './login-form';
import ConnectionTable from './tables/connection-table';
import SampleTable from './tables/sample-table';
import OrderTable from './tables/order-table';
import OrderForm from './order-form';
import PositionTable from './tables/position-table';
import TradeTable from './tables/trade-table';
import AccountTable from './tables/account-table';
import TickerControl from './ticker-control';

var SubscribeBox = React.createClass( {
    getInitialState: function() {
	return {};
    },
    componentDidMount: function() {
	var source = new EventSource(this.props.url);
	var obj = this;
	$.each(this.props.event, function(k, v) {
	    source.addEventListener(k, v);
	});
    },
    render: function() {
        return null;
    }
});

var Injector = React.createClass( {
    mixins: [ReactAddonsLinkedStateMixin],
    getInitialState: function() {
	return {message: 'Hello!',
		textinput : ''};
    },
    inject : function() {
	var self = this;
	jQuery.ajax({
	    url: "/inject",
	    type: "POST",
	    data: self.state.textinput,
	    contentType: "application/json; charset=utf-8",
	    success: function (response) {
		self.setState({message: response});
	    }
	});
    },
    injectTest : function() {
	this.setState({message : "test inject"});
    },
    clear: function() {
	this.setState({textinput : ''});
    },
    fileOpen: function(e) {
	var self = this;
	var files = e.target.files,
	    reader = new FileReader();
	reader.onload = function() {
	    self.setState({textinput: this.result});
	}
	reader.readAsText(files[0]);
    },
    render: function() {
	return (

<Button bsStyle="success" onClick={this.inject}>Inject</Button>
<Button bsStyle="success" onClick={this.clear}>Clear</Button>
<Button bsStyle="success" onClick={this.injectTest}>Test</Button>
<FormControl componentClass="file" onChange={this.fileOpen} />
<FormControl componentClass="textarea" valueLink={this.linkState('textinput')} />
<FormControl componentClass="textarea" valueLink={this.linkState('message')} />

	);
    }
});

function publish() {
    $.get("/ping");
};

var columns = [
    { name : 'index' },
    { name : 'firstName' },
    { name : 'city' }
]

var data = [];

function FieldGroup({ id, label, help, ...props }) {
  return (

      {label}
      <FormControl {...props} />
      {help && <HelpBlock>{help}</HelpBlock>}

  );
}
console.log("New SPTrader");

var SpTraderApp = React.createClass({
    getInitialState: function() {
	var l = this;
	$.getJSON("/login-status/80", function(d) {
	    if (parseInt(d) != -1) {
		l.setState({showLoginForm: false});
	    }
	});

	return {
	    log: '',
	    loginLabel: '',
	    account_info: {},
	    connection_info: {},
	    showLoginForm: true,
	    showOrderForm: false,
	    tickers: [],
	    orders: [],
	    trades: []
	};
    },
    submitModal: function(data) {
	$.ajax({
	    type: 'post',
	    url: '/login',
	    data: JSON.stringify(data),
	    contentType: "application/json"
	});
    },
    logout: function() {
	$.get("/logout");
	this.setState({loginLabel: ''});
	this.setState({showLoginForm: true});
    },
    addToLog: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({log: this.state.log + event.data + "\n"});
    },
    loginReply: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({log: this.state.log + event.data + "\n"});
	if (parseInt(data.ret_code) != 0) {
	    this.setState({loginLabel: data.ret_msg});
	} else {
	    this.setState({showLoginForm: false});
	}
    },
    connectedReply: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({log: this.state.log + event.data + "\n"});
	var conn_info = this.state.connection_info;
	var host_type = parseInt(data.host_type);
	var con_status = parseInt(data.con_status);
	conn_info[host_type] = con_status;
	this.setState({conn_info: conn_info})
	if (parseInt(host_type) == 80 &&
	    parseInt(con_status) == 2) {
	    var l = this;
	    $.getJSON("/ticker/list", function(d) {
		l.setState({tickers: d.data});
	    });
	    $.getJSON("/account-info");
	    $.getJSON("/order/list", function(d) {
		l.setState({orders: d.data});
		});
	    $.getJSON("/trade/list", function(d) {
		l.setState({trades: d.data});
	    });
	}
    },
    showOrderForm: function(event) {
	this.setState({showOrderForm: true});
    },
    submitOrder: function(event) {
	this.setState({showOrderForm: false});
    },
    accountInfoPush: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({log: this.state.log + event.data + "\n"});
	this.setState({account_info: data});
    },
    updateTickers: function(event) {
	data = JSON.parse(event.data);
	console.log(data);
	this.setState({tickers: data.data});
    },
    render: function() {
	var events = {
	    "ping" : this.addToLog,
	    "LoginReply" : this.loginReply,
	    "ConnectedReply" : this.connectedReply,
	    "AccountInfoPush" : this.accountInfoPush,
	    "UpdateTickers" : this.updateTickers,
	    "AccountPositionPush" : this.addToLog,
	    "ApiTradeReport" : this.addToLog,
	    "ApiPriceUpdate" : this.addToLog,
	    "InstrumentListReply" : this.addToLog,
	    "ProductListByCodeReply" : this.addToLog
	}
	return(
		<Tabs id="tabs">
		<Tab eventKey={1} title="Login">
		<LoginForm show={this.state.showLoginForm}
	    label={this.state.loginLabel}
	    onSubmit={this.submitModal}/>
		<Button bsStyle="success" onClick={this.logout}>Logout</Button>
		<ConnectionTable data={this.state.connection_info}/>
		<Tabs id="tab1">
		<Tab eventKey={1} title="Account">
		<AccountTable data={this.state.account_info} />
		</Tab>
		<Tab eventKey={2} title="Order">
		<OrderForm show={this.state.showOrderForm}
	    onSubmit={this.submitOrder}/>
		<Button bsStyle="success" onClick={this.showOrderForm}>Show Order</Button>
		<OrderTable data={this.state.orders} />
		</Tab>
		<Tab eventKey={3} title="Position">
		<PositionTable />
		</Tab>
		<Tab eventKey={4} title="Trade">
		<TradeTable data={this.state.trades}/>
		</Tab>
		<Tab eventKey={5} title="Ticker">
		<TickerControl tickers={this.state.tickers}/>
		</Tab>
		</Tabs>
		</Tab>
		<Tab eventKey={2} title="Strategies">
		</Tab>
		<Tab eventKey={3} title="Scratchpad">
		<ButtonToolbar>
		<Button bsStyle="success" onClick={publish}>Ping</Button>
		</ButtonToolbar>
		<SubscribeBox url="/log/subscribe" event={events} />
		<FormControl componentClass="textarea" value={this.state.log} />
		<SampleTable/>
		</Tab>
		</Tabs>
	)
    }
});

var helloWorld = React.createClass({
    render: function() {
	return (
Greetings from SPTrader
)
    }
});

ReactDOM.render(
    <helloWorld />,
    document.getElementById('content')
);

ReactDOM.render(
    <SpTraderApp />,
    document.getElementById('test')
);
<|endoftext|>


<commit_before>'use strict';

// Define navigator.mediaDevices.getUserMedia() for older devices.

/**
 * Constraints to apply to MediaStream.
 * On this codelab, you will be streaming video, but not audio.
 */
const mediaStreamConstraints = {
  audio: false,
  video: true,
};

/** Video element where stream will be placed. */
const localVideo = document.querySelector('video');

/** Handles success by adding the MediaStream to the video element. */
const localMediaStreamSuccessCallback = (mediaStream) => {
  window.localStream = mediaStream;  // Makes stream available to the console.
  if (window.URL) {
    localVideo.src = window.URL.createObjectURL(mediaStream);
  } else {
    localVideo.src = mediaStream;
  }
};

/** Handles error by logging a message to the console with the error message. */
const localMediaStreamErrorCallback = (error) => {
  console.log('navigator.getUserMedia error: ', error);
};

// Initializes media stream.
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
  .then(localMediaStreamSuccessCallback, localMediaStreamErrorCallback);
<commit_msg>Change promise syntax<commit_after>'use strict';

// Define navigator.mediaDevices.getUserMedia() for older devices.

/**
 * Constraints to apply to MediaStream.
 * On this codelab, you will be streaming video, but not audio.
 */
const mediaStreamConstraints = {
  audio: false,
  video: true,
};

/** Video element where stream will be placed. */
const localVideo = document.querySelector('video');

/** Handles success by adding the MediaStream to the video element. */
const localMediaStreamSuccessCallback = (mediaStream) => {
  window.localStream = mediaStream;  // Makes stream available to the console.
  if (window.URL) {
    localVideo.src = window.URL.createObjectURL(mediaStream);
  } else {
    localVideo.src = mediaStream;
  }
};

/** Handles error by logging a message to the console with the error message. */
const localMediaStreamErrorCallback = (error) => {
  console.log('navigator.getUserMedia error: ', error);
};

// Initializes media stream.
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
  .then(localMediaStreamSuccessCallback)
  .catch(localMediaStreamErrorCallback);
<|endoftext|>


<commit_before>import React from 'react';
import { storiesOf } from '@storybook/react';
import { boolean, number, select, text } from '@storybook/addon-knobs';
import { Avatar, AvatarStack, Bullet, Counter, TextBody, Tooltip } from '../src';
import avatars from './static/data/avatar';

const directions = ['horizontal', 'vertical'];
const sizes = ['tiny', 'small', 'medium', 'large', 'hero'];
const shapes = ['circle', 'rounded'];

const TooltippedAvatar = Tooltip(Avatar);

storiesOf('Avatars', module)
  .addParameters({
    info: {
      propTablesExclude: [Bullet, Counter],
    },
  })
  .add('Avatar', () => (
    <Avatar
      editable={boolean('Editable', false)}
      fullName={text('Full name', 'John Doe')}
      id={text('Id', '63227a3c-c80b-11e9-a32f-2a2ae2dbcce4')}
      imageUrl={boolean('Image available', false) ? avatars[0].image : null}
      onImageChange={() => console.log('Change image')}
      size={select('Size', sizes, 'large')}
      shape={select('Shape', shapes, 'circle')}
    />
  ))
  .add('AvatarStack', () => (
    <AvatarStack
      direction={select('Direction', directions, 'horizontal')}
      displayMax={number('Display max', 5)}
      inverse={boolean('Inverse', false)}
      size={select('Size', sizes, 'large')}
    >
      {avatars.map(({ image }, index) => (
        <Avatar key={index} imageUrl={image} />
      ))}
    </AvatarStack>
  ))
  .add('With bullet', () => (
    <Avatar
      editable={boolean('Editable', false)}
      fullName={text('Full name', 'John Doe')}
      id="63227a3c-c80b-11e9-a32f-2a2ae2dbcce4"
      imageUrl={boolean('Image available', false) ? avatars[0].image : null}
      onImageChange={() => console.log('Change image')}
      size={select('Size', sizes, 'large')}
      shape={select('Shape', shapes, 'circle')}
    >
      <Bullet borderColor="neutral" borderTint="lightest" color="ruby" />
    </Avatar>
  ))
  .add('With counter', () => (
    <Avatar
      editable={boolean('Editable', false)}
      fullName={text('Full name', 'John Doe')}
      id="63227a3c-c80b-11e9-a32f-2a2ae2dbcce4"
      imageUrl={boolean('Image available', false) ? avatars[0].image : null}
      onImageChange={() => console.log('Change image')}
      size={select('Size', sizes, 'large')}
      shape={select('Shape', shapes, 'circle')}
    >
      <Counter color="ruby" count={15} maxCount={6} borderColor="neutral" borderTint="lightest" />
    </Avatar>
  ))
  .add('With tooltip', () => (
    <TooltippedAvatar
      editable={boolean('Editable', false)}
      fullName={text('Full name', 'John Doe')}
      id="63227a3c-c80b-11e9-a32f-2a2ae2dbcce4"
      imageUrl={boolean('Image available', false) ? avatars[0].image : null}
      onImageChange={() => console.log('Change image')}
      size={select('Size', sizes, 'large')}
      shape={select('Shape', shapes, 'circle')}
      tooltip={<TextBody>I am the tooltip</TextBody>}
    />
  ));
<commit_msg>Update stories<commit_after>import React from 'react';
import { storiesOf } from '@storybook/react';
import { boolean, number, select, text } from '@storybook/addon-knobs';
import { Avatar, AvatarStack, Bullet, Counter, TextBody, Tooltip } from '../src';
import avatars from './static/data/avatar';

const directions = ['horizontal', 'vertical'];
const sizes = ['tiny', 'small', 'medium', 'large', 'hero'];
const shapes = ['circle', 'rounded'];

const TooltippedAvatar = Tooltip(Avatar);

storiesOf('Avatars', module)
  .addParameters({
    info: {
      propTablesExclude: [Bullet, Counter],
    },
  })
  .add('Avatar', () => (
    <Avatar
      creatable={boolean('Creatable', false)}
      editable={boolean('Editable', false)}
      fullName={text('Full name', 'John Doe')}
      id={text('Id', '63227a3c-c80b-11e9-a32f-2a2ae2dbcce4')}
      imageUrl={boolean('Image available', false) ? avatars[0].image : null}
      onImageChange={() => console.log('Change image')}
      size={select('Size', sizes, 'large')}
      shape={select('Shape', shapes, 'circle')}
    />
  ))
  .add('AvatarStack', () => (
    <AvatarStack
      direction={select('Direction', directions, 'horizontal')}
      displayMax={number('Display max', 5)}
      inverse={boolean('Inverse', false)}
      size={select('Size', sizes, 'large')}
    >
      {avatars.map(({ image }, index) => (
        <Avatar key={index} imageUrl={image} />
      ))}
    </AvatarStack>
  ))
  .add('With bullet', () => (
    <Avatar
      creatable={boolean('Creatable', false)}
      editable={boolean('Editable', false)}
      fullName={text('Full name', 'John Doe')}
      id={text('Id', '63227a3c-c80b-11e9-a32f-2a2ae2dbcce4')}
      imageUrl={boolean('Image available', false) ? avatars[0].image : null}
      onImageChange={() => console.log('Change image')}
      size={select('Size', sizes, 'large')}
      shape={select('Shape', shapes, 'circle')}
    >
      <Bullet borderColor="neutral" borderTint="lightest" color="ruby" />
    </Avatar>
  ))
  .add('With counter', () => (
    <Avatar
      creatable={boolean('Creatable', false)}
      editable={boolean('Editable', false)}
      fullName={text('Full name', 'John Doe')}
      id={text('Id', '63227a3c-c80b-11e9-a32f-2a2ae2dbcce4')}
      imageUrl={boolean('Image available', false) ? avatars[0].image : null}
      onImageChange={() => console.log('Change image')}
      size={select('Size', sizes, 'large')}
      shape={select('Shape', shapes, 'circle')}
    >
      <Counter color="ruby" count={15} maxCount={6} borderColor="neutral" borderTint="lightest" />
    </Avatar>
  ))
  .add('With tooltip', () => (
    <TooltippedAvatar
      creatable={boolean('Creatable', false)}
      editable={boolean('Editable', false)}
      fullName={text('Full name', 'John Doe')}
      id={text('Id', '63227a3c-c80b-11e9-a32f-2a2ae2dbcce4')}
      imageUrl={boolean('Image available', false) ? avatars[0].image : null}
      onImageChange={() => console.log('Change image')}
      size={select('Size', sizes, 'large')}
      shape={select('Shape', shapes, 'circle')}
      tooltip={<TextBody>I am the tooltip</TextBody>}
    />
  ));
<|endoftext|>