<commit_before>var su = ''; //http://ec2-54-200-40-68.us-west-2.compute.amazonaws.com:8080';

var _user_details = '/user/details';

var _user_details = 'http://web.mit.edu/ambhave/www/suitup/user_details.json';

function init_user_details() {
    console.log('init_user_details()');

    $.getJSON(_user_details, function (data) {
        $('.user_username').text(data['username']);
    }).error(function (jqXhr, textStatus, error) {
        alert("ERROR: " + textStatus + ", " + error);
    });
}

$(document).ready(function () {
  //  login();
    //  init_user_details();

});

var chatroomid = 0;

function chat_join(s) {
    $.ajax({
        type: "GET",
        url: su + '/chatroom/join',
        success: function (data) {
            chatroomid = data['crid'];
            $('#firepad').html('');
            var firepadRef = new Firebase('//hackmitsuitup.firebaseIO.com/firepads/' + chatroomid);

            var codeMirror = CodeMirror(document.getElementById('firepad'), {
                lineNumbers: true,
                mode: 'python'
            });
            var firepad = Firepad.fromCodeMirror(firepadRef, codeMirror);

            setTimeout(chat_check, 1000);
        }
    });
}

function chat_leave() {
    $.ajax({
        type: "GET",
        url: su + '/chatroom/leave',
        success: function (data) {
            $('#firepad').html('');
        }
    });
}

function chat_send(chat, convo) {
    $.ajax({
        type: "GET",
        url: su + '/message/send',
        data: { 's': $('#' + chat).val() }
    });
    $('#' + convo).val($('#' + convo).val() + '\nMe: ' + $('#' + chat).val());
    $('#' + chat).val('');
}

function chat_check() {
    $.ajax({
        type: "GET",
        url: su + '/message/check',
        success: function (data) {

            if (data != '') {
                console.log(data);
                $('#convo').val($('#convo').val() + '\nOther: ' + data);
            }
            setTimeout(chat_check, 1000);
        }
    });
}

// Load the SDK asynchronously
(function (d) {
    var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
    if (d.getElementById(id)) { return; }
    js = d.createElement('script'); js.id = id; js.async = true;
    js.src = "//connect.facebook.net/en_US/all.js";
    ref.parentNode.insertBefore(js, ref);
}(document));

var access_token = null;
var user_city = null;
var fb_user = null;

function login() {
    _login_wait();

    FB.login(function (response) {
        //_check_login();
    });
}
function logout() {
    _login_wait();

    FB.logout(function (response) {
        //_login_bad();
    });
}

// Additional JS functions here
window.fbAsyncInit = function () {
    FB.init({
        appId: '615988445111525', // App ID
        channelUrl: '//localhost:8000/channel.html', // Channel File
        status: true, // check login status
        cookie: true, // enable cookies to allow the server to access the session
        xfbml: true  // parse XFBML
    });

    // Additional init code here
    //_check_login();
    _login_wait();
    FB.getLoginStatus(function (response) {
        if (response.status !== 'connected') {
            _login_bad();
        }
    });

    FB.Event.subscribe('auth.statusChange', function (response) {
        _check_login();
        console.log(response);
    });
};

/* Helper Functions */
function _hide_all_login() {
    $('.pLoginBad').hide();
    $('.pLoginDone').hide();
    $('.pLoginWait').hide();
}
function _check_login() {
    _login_wait();
    FB.getLoginStatus(function (response) {
        if (response.status === 'connected') {
            _login_done(response);
        }
        else {
            _login_bad();
        }
    });
}
function _login_wait() {
    _hide_all_login();
    $('.pLoginWait').show();
}
function _login_bad() {
    _hide_all_login();
    $('.pLoginBad').show();
}
function _login_done(response) {

    if (response != null)
        access_token = response.authResponse.accessToken;

    FB.api('/me?fields=picture,name', function (response) {
        fb_user = response;
        console.log(response);
        $('.user_username').text(response.name);
        $('.user_photourl').attr('src', response.picture.data.url);

        _hide_all_login();
        $('.pLoginDone').show();
    });

    // TODO: UNCOMMENT THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
    $.ajax({ url: su + '/login?access_token=' + access_token }).success(function (data) { chat_join(); });

    //$.ajax({url:"demo_test.txt",success:function(result){    $("#div1").html(result);  }});

    /*

    FB.api('/me/home', function(response) {
       console.log(response);
       $('#news_feed').empty();
       for (var i = 0; i < response['data'].length; i++) {
           var item = response['data'][i];
           var txt = '
 \
                    \
                        \
                    \

  \

' + item['from']['name'] + '
            \

 \

';
           $('#news_feed').append(txt);
       }
    });*/
}
function _fatal_error(message) {
    $('body').html('Fatal Error! Please refresh the page

Message: ' + message);
}

<commit_msg>loader fix<commit_after>var su = ''; //http://ec2-54-200-40-68.us-west-2.compute.amazonaws.com:8080';

var _user_details = '/user/details';

var _user_details = 'http://web.mit.edu/ambhave/www/suitup/user_details.json';

function init_user_details() {
    console.log('init_user_details()');

    $.getJSON(_user_details, function (data) {
        $('.user_username').text(data['username']);
    }).error(function (jqXhr, textStatus, error) {
        alert("ERROR: " + textStatus + ", " + error);
    });
}

$(document).ready(function () {
  //  login();
    //  init_user_details();

});

var chatroomid = -1;

function chat_join(s) {
    $.ajax({
        type: "GET",
        url: su + '/chatroom/join',
        success: function (data) {
            chatroomid = data['crid'];
            $('#firepad').html('');
            var firepadRef = new Firebase('//hackmitsuitup.firebaseIO.com/firepads/' + chatroomid);

            var codeMirror = CodeMirror(document.getElementById('firepad'), {
                lineNumbers: true,
                mode: 'python'
            });
            var firepad = Firepad.fromCodeMirror(firepadRef, codeMirror);

            setTimeout(chat_check, 1000);
        }
    });
}

function chat_leave() {
    $.ajax({
        type: "GET",
        url: su + '/chatroom/leave',
        success: function (data) {
            $('#firepad').html('');
        }
    });
    chatroomid = -1;
}

function chat_send(chat, convo) {
    $.ajax({
        type: "GET",
        url: su + '/message/send',
        data: { 's': $('#' + chat).val() }
    });
    $('#' + convo).val($('#' + convo).val() + '\nMe: ' + $('#' + chat).val());
    $('#' + chat).val('');
}

function chat_check() {
    $.ajax({
        type: "GET",
        url: su + '/message/check',
        success: function (data) {

            if (data != '') {
                console.log(data);
                $('#convo').val($('#convo').val() + '\nOther: ' + data);
            }
            setTimeout(chat_check, 1000);
        }
    });
}

// Load the SDK asynchronously
(function (d) {
    var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
    if (d.getElementById(id)) { return; }
    js = d.createElement('script'); js.id = id; js.async = true;
    js.src = "//connect.facebook.net/en_US/all.js";
    ref.parentNode.insertBefore(js, ref);
}(document));

var access_token = null;
var user_city = null;
var fb_user = null;

function login() {
    _login_wait();

    FB.login(function (response) {
        //_check_login();
    });
}
function logout() {
    _login_wait();

    FB.logout(function (response) {
        //_login_bad();
    });
}

// Additional JS functions here
window.fbAsyncInit = function () {
    FB.init({
        appId: '615988445111525', // App ID
        channelUrl: '//localhost:8000/channel.html', // Channel File
        status: true, // check login status
        cookie: true, // enable cookies to allow the server to access the session
        xfbml: true  // parse XFBML
    });

    // Additional init code here
    //_check_login();
    _login_wait();
    FB.getLoginStatus(function (response) {
        if (response.status !== 'connected') {
            _login_bad();
        }
    });

    FB.Event.subscribe('auth.statusChange', function (response) {
        _check_login();
        console.log(response);
    });
};

/* Helper Functions */
function _hide_all_login() {
    $('.pLoginBad').hide();
    $('.pLoginDone').hide();
    $('.pLoginWait').hide();
}
function _check_login() {
    _login_wait();
    FB.getLoginStatus(function (response) {
        if (response.status === 'connected') {
            _login_done(response);
        }
        else {
            _login_bad();
        }
    });
}
function _login_wait() {
    _hide_all_login();
    $('.pLoginWait').show();
}
function _login_bad() {
    _hide_all_login();
    $('.pLoginBad').show();
}
function _login_done(response) {

    if (response != null)
        access_token = response.authResponse.accessToken;

    FB.api('/me?fields=picture,name', function (response) {
        fb_user = response;
        console.log(response);
        $('.user_username').text(response.name);
        $('.user_photourl').attr('src', response.picture.data.url);

        _hide_all_login();
        $('.pLoginDone').show();
    });

    // TODO: UNCOMMENT THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
    $.ajax({ url: su + '/login?access_token=' + access_token }).success(function (data) { chat_join(); });

    //$.ajax({url:"demo_test.txt",success:function(result){    $("#div1").html(result);  }});

    /*

    FB.api('/me/home', function(response) {
       console.log(response);
       $('#news_feed').empty();
       for (var i = 0; i < response['data'].length; i++) {
           var item = response['data'][i];
           var txt = '
 \
                    \
                        \
                    \

  \

' + item['from']['name'] + '
            \

 \

';
           $('#news_feed').append(txt);
       }
    });*/
}
function _fatal_error(message) {
    $('body').html('Fatal Error! Please refresh the page

Message: ' + message);
}

<|endoftext|>


<commit_before>import {
  LOAD_START, CAN_PLAY,
  WAITING, CAN_PLAY_THROUGH, PLAYING,
  PLAY, PAUSE, END, SEEKING, SEEKED,
  SEEKING_TIME, END_SEEKING, DURATION_CHANGE,
  TIME_UPDATE, VOLUME_CHANGE, PROGRESS_CHANGE,
  RATE_CHANGE, SUSPEND, ABORT, EMPTIED,
  STALLED, LOADED_META_DATA, LOADED_DATA,
  RESIZE, ERROR
} from '../actions/video';
import { FULLSCREEN_CHANGE, PLAYER_ACTIVATE, USER_ACTIVATE } from '../actions/player';

const initialState = {
  currentSrc: null,
  duration: 0,
  currentTime: 0,
  seekingTime: 0,
  buffered: null,
  waiting: true,
  seeking: false,
  paused: true,
  autoPaused: false,
  ended: false,
  playbackRate: 1,
  muted: false,
  volume: 1,
  readyState: 0,
  networkState: 0,
  videoWidth: 0,
  videoHeight: 0,
  hasStarted: false,
  userActivity: true,
  isActive: false,
  isFullscreen: false,
};

export default function video(state = initialState, action) {
  console.log(action)
  switch (action.type) {
    case USER_ACTIVATE:
      return {
        ...state,
        userActivity: action.activity
      };
    case PLAYER_ACTIVATE:
      return {
        ...state,
        isActive: action.activity
      };
    case FULLSCREEN_CHANGE:
      return {
        ...state,
        isFullscreen: !!action.isFullscreen,
      };
    case SEEKING_TIME:
      return {
        ...state,
        seekingTime: action.time
      };
    case END_SEEKING:
      return {
        ...state,
        seekingTime: 0,
      };
    case LOAD_START:
      return {
        ...state,
        ...action.videoProps,
        hasStarted: false,
        ended: false,
      };
    case CAN_PLAY:
      return {
        ...state,
        ...action.videoProps,
        waiting: false,
      };
    case WAITING:
      return {
        ...state,
        ...action.videoProps,
        waiting: true
      };
    case CAN_PLAY_THROUGH:
    case PLAYING:
      return {
        ...state,
        ...action.videoProps,
        waiting: false
      };
    case PLAY:
      return {
        ...state,
        ...action.videoProps,
        ended: false,
        paused: false,
        autoPaused: false,
        waiting: false,
        hasStarted: true,
      };
    case PAUSE:
      return {
        ...state,
        ...action.videoProps,
        paused: true
      };
    case END:
      return {
        ...state,
        ...action.videoProps,
        ended: true
      };
    case SEEKING:
      return {
        ...state,
        ...action.videoProps,
        seeking: true
      };
    case SEEKED:
      return {
        ...state,
        ...action.videoProps,
        seeking: false
      };
    case DURATION_CHANGE:
    case TIME_UPDATE:
    case VOLUME_CHANGE:
    case PROGRESS_CHANGE:
    case RATE_CHANGE:
    case SUSPEND:
    case ABORT:
    case EMPTIED:
    case STALLED:
    case LOADED_META_DATA:
    case LOADED_DATA:
    case RESIZE:
    case ERROR:
      return {
        ...state,
        ...action.videoProps,
      };
    default:
      return state;
  }
}
<commit_msg>remove console log<commit_after>import {
  LOAD_START, CAN_PLAY,
  WAITING, CAN_PLAY_THROUGH, PLAYING,
  PLAY, PAUSE, END, SEEKING, SEEKED,
  SEEKING_TIME, END_SEEKING, DURATION_CHANGE,
  TIME_UPDATE, VOLUME_CHANGE, PROGRESS_CHANGE,
  RATE_CHANGE, SUSPEND, ABORT, EMPTIED,
  STALLED, LOADED_META_DATA, LOADED_DATA,
  RESIZE, ERROR
} from '../actions/video';
import { FULLSCREEN_CHANGE, PLAYER_ACTIVATE, USER_ACTIVATE } from '../actions/player';

const initialState = {
  currentSrc: null,
  duration: 0,
  currentTime: 0,
  seekingTime: 0,
  buffered: null,
  waiting: true,
  seeking: false,
  paused: true,
  autoPaused: false,
  ended: false,
  playbackRate: 1,
  muted: false,
  volume: 1,
  readyState: 0,
  networkState: 0,
  videoWidth: 0,
  videoHeight: 0,
  hasStarted: false,
  userActivity: true,
  isActive: false,
  isFullscreen: false,
};

export default function video(state = initialState, action) {

  switch (action.type) {
    case USER_ACTIVATE:
      return {
        ...state,
        userActivity: action.activity
      };
    case PLAYER_ACTIVATE:
      return {
        ...state,
        isActive: action.activity
      };
    case FULLSCREEN_CHANGE:
      return {
        ...state,
        isFullscreen: !!action.isFullscreen,
      };
    case SEEKING_TIME:
      return {
        ...state,
        seekingTime: action.time
      };
    case END_SEEKING:
      return {
        ...state,
        seekingTime: 0,
      };
    case LOAD_START:
      return {
        ...state,
        ...action.videoProps,
        hasStarted: false,
        ended: false,
      };
    case CAN_PLAY:
      return {
        ...state,
        ...action.videoProps,
        waiting: false,
      };
    case WAITING:
      return {
        ...state,
        ...action.videoProps,
        waiting: true
      };
    case CAN_PLAY_THROUGH:
    case PLAYING:
      return {
        ...state,
        ...action.videoProps,
        waiting: false
      };
    case PLAY:
      return {
        ...state,
        ...action.videoProps,
        ended: false,
        paused: false,
        autoPaused: false,
        waiting: false,
        hasStarted: true,
      };
    case PAUSE:
      return {
        ...state,
        ...action.videoProps,
        paused: true
      };
    case END:
      return {
        ...state,
        ...action.videoProps,
        ended: true
      };
    case SEEKING:
      return {
        ...state,
        ...action.videoProps,
        seeking: true
      };
    case SEEKED:
      return {
        ...state,
        ...action.videoProps,
        seeking: false
      };
    case DURATION_CHANGE:
    case TIME_UPDATE:
    case VOLUME_CHANGE:
    case PROGRESS_CHANGE:
    case RATE_CHANGE:
    case SUSPEND:
    case ABORT:
    case EMPTIED:
    case STALLED:
    case LOADED_META_DATA:
    case LOADED_DATA:
    case RESIZE:
    case ERROR:
      return {
        ...state,
        ...action.videoProps,
      };
    default:
      return state;
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import update from 'immutability-helper';
import Logo from './Logo';
import SearchBar from './SearchBar';
import ListPicker from './ListPicker';
import BookListPane from './BookListPane';
import base from '../base';

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      bookLists: {}
    };
  }

  componentWillMount() {
    this.ref = base.syncState('bookLists',
      {
        context: this,
        state: 'bookLists',
        defaultValue: {
          'To Read': {
            listName: 'To Read',
            selected: true,
            books: {
              'book-1': {
                title: 'To Kill A Mockingbird',
                author: 'Harper Lee',
                pubDate: '1952',
                img: 'url-to-image',
                list: 'To Read'
              },
              'book-2:': {
                title: 'The Tempest',
                author: 'William Shakespeare',
                pubDate: '1519',
                img: 'url-to-image',
                list: 'To Read'
              }
            }
          },

          'Read': {
            listName: 'Read',
            selected: false,
            books: {
              'book-3': {
                title: 'Ragtime',
                author: 'E.L. Doctorow',
                pubDate: '1931',
                img: 'url-to-image',
                list: 'Read'
              },
              'book-4:': {
                title: 'Middlesex',
                author: 'Jeffery Eugenides',
                pubDate: '2004',
                img: 'url-to-image',
                list: 'Read'
              }
            }
          },

          'Favorites': {
            listName: 'Favorites',
            selected: false,
            books: {
              'book-5': {
                title: 'Infinite Jest',
                author: 'David Foster Wallace',
                pubDate: '1994',
                img: 'url-to-image',
                list: 'Favorites'
              }
            }
          }

        }
      });
  }

  componentWillUnmount() {
    base.removeBinding(this.ref);
  }

  // newBook will come from api
  addBookToList = (listName, newBook) => {
    // will have to add check for no books in list
    const books = {...this.state.bookLists[listName].books};
    // use id prop from api instead of date ts
    const id = Date.now();
    // if(books.hasOwnProperty(id)) {
    //   return alert('book is already in list!');
    // }

    newBook.list = listName;
    books[`book-${id}`] = newBook;
    this.setState({
      bookLists: update(this.state.bookLists, {[listName]: {books: {$set: books}}})
    });
  };

  removeBookFromList = (listName, book) => {
    const books = {...this.state.bookLists[listName].books};
    books[book] = null;
    this.setState(newState => {
      return {
        bookLists: update(this.state.bookLists, {[listName]: {books: {$set: books}}})
      };
    });
  };

  getCurrentList = () => {
    const currListName =
      Object
        .keys(this.state.bookLists)
        .find(list => this.state.bookLists[list].selected);

    return this.state.bookLists[currListName]
      ? this.state.bookLists[currListName]
      : {};
  };

  toggleSelected = (listName) => {
    let selected = this.state.bookLists[listName].selected;
    selected = !selected;
    this.setState(newState => {
      return {
        bookLists: update(newState.bookLists, {[listName]: {selected: {$set: selected}}})
      };
    });
  };

  createList = (listName) => {
    const bookLists = {...this.state.bookLists};
    if(bookLists.hasOwnProperty(listName)) {
      return alert('list already exists!');
    }

    // sample data for testing
    bookLists[listName] = {
      listName: listName,
      selected: false,
      books: {}
    };
    this.setState({ bookLists });
  };

  // removeList

  switchList = (listName) => {
    const currList = this.getCurrentList();
    if(listName === currList.listName) return;
    this.toggleSelected(listName);
    this.toggleSelected(currList.listName);
  };

  render() {
    return (

        <Logo/>
        <SearchBar/>
        <ListPicker switchList={this.switchList} lists={this.state.bookLists}/>
        <BookListPane
          currentList={this.getCurrentList()}
          addBook={this.addBookToList}/>

    )
  }
}

export default App;
<commit_msg>add checking methods<commit_after>import React from 'react';
import update from 'immutability-helper';
import Logo from './Logo';
import SearchBar from './SearchBar';
import ListPicker from './ListPicker';
import BookListPane from './BookListPane';
import base from '../base';

class App extends React.Component {
  constructor() {
    super();

    this.state = {
      bookLists: {}
    };
  }

  componentWillMount() {
    this.ref = base.syncState('bookLists',
      {
        context: this,
        state: 'bookLists',
        defaultValue: {
          'To Read': {
            listName: 'To Read',
            selected: true,
            books: {
              'book-1': {
                title: 'To Kill A Mockingbird',
                author: 'Harper Lee',
                pubDate: '1952',
                img: 'url-to-image',
                list: 'To Read'
              },
              'book-2': {
                title: 'The Tempest',
                author: 'William Shakespeare',
                pubDate: '1519',
                img: 'url-to-image',
                list: 'To Read'
              }
            }
          },

          'Read': {
            listName: 'Read',
            selected: false,
            books: {
              'book-3': {
                title: 'Ragtime',
                author: 'E.L. Doctorow',
                pubDate: '1931',
                img: 'url-to-image',
                list: 'Read'
              },
              'book-4': {
                title: 'Middlesex',
                author: 'Jeffery Eugenides',
                pubDate: '2004',
                img: 'url-to-image',
                list: 'Read'
              }
            }
          },

          'Favorites': {
            listName: 'Favorites',
            selected: false,
            books: {
              'book-5': {
                title: 'Infinite Jest',
                author: 'David Foster Wallace',
                pubDate: '1994',
                img: 'url-to-image',
                list: 'Favorites'
              }
            }
          }

        }
      });
  }

  componentWillUnmount() {
    base.removeBinding(this.ref);
  }

  doesListExist = (bookLists, listName) => {
    return bookLists.hasOwnProperty(listName);
  };

  isBookInList = (books, bookID) => {
    return books.hasOwnProperty(bookID);
  };

  // newBook will come from api
  addBookToList = (listName, newBook) => {
    const books = {...this.state.bookLists[listName].books};
    // use id prop from api instead of date ts
    const id = Date.now();
    if(this.isBookInList(books, newBook.ID)) {
      return alert('book is already in list!');
    }
    newBook.list = listName;
    books[`book-${id}`] = newBook;
    this.setState({
      bookLists: update(this.state.bookLists, {[listName]: {books: {$set: books}}})
    });
  };

  removeBookFromList = (listName, bookID) => {
    const books = {...this.state.bookLists[listName].books};
    if(!this.isBookInList(books, bookID)) {
      return alert('book is not in list!');
    }
    books[bookID] = null;
    this.setState(newState => {
      return {
        bookLists: update(this.state.bookLists, {[listName]: {books: {$set: books}}})
      };
    });
  };

  getCurrentList = () => {
    const currListName =
      Object
        .keys(this.state.bookLists)
        .find(list => this.state.bookLists[list].selected);

    return this.state.bookLists[currListName]
      ? this.state.bookLists[currListName]
      : {};
  };

  toggleSelected = (listName) => {
    let selected = this.state.bookLists[listName].selected;
    selected = !selected;
    this.setState(newState => {
      return {
        bookLists: update(newState.bookLists, {[listName]: {selected: {$set: selected}}})
      };
    });
  };

  createList = (listName) => {
    const bookLists = {...this.state.bookLists};
    if(this.doesListExist(bookLists, listName)) {
      return alert('list already exists!');
    }
    // sample data for testing
    bookLists[listName] = {
      listName: listName,
      selected: false,
      books: {}
    };
    this.setState({ bookLists });
  };

  // TODO: removeList

  switchList = (listName) => {
    const currList = this.getCurrentList();
    if(listName === currList.listName) return;
    this.toggleSelected(listName);
    this.toggleSelected(currList.listName);
  };

  render() {
    return (

        <Logo/>
        <SearchBar/>
        <ListPicker switchList={this.switchList} lists={this.state.bookLists}/>
        <BookListPane
          currentList={this.getCurrentList()}
          addBook={this.addBookToList}/>

    )
  }
}

export default App;
<|endoftext|>


<commit_before>"use strict";

var _ = require('underscore'),
    Marionette = require('../../../shim/backbone.marionette'),
    ZeroClipboard = require('zeroclipboard'),
    models = require('./models'),
    modalConfirmTmpl = require('./templates/confirmModal.html'),
    modalInputTmpl = require('./templates/inputModal.html'),
    modalShareTmpl = require('./templates/shareModal.html'),

    ENTER_KEYCODE = 13,
    BASIC_MODAL_CLASS = 'modal modal-basic fade';

var ModalBaseView = Marionette.ItemView.extend({
    className: BASIC_MODAL_CLASS,

    attributes: {
        'tabindex': '-1'
    },

    events: {
        'shown.bs.modal': 'onModalShown',
        'keyup': 'onKeyUp',
        'hidden.bs.modal': 'onModalHidden'
    },

    onRender: function() {
        this.$el.modal('show');
    },

    onModalShown: function() {
        // Not implemented.
    },

    onKeyUp: function(e) {
        if (e.keyCode === ENTER_KEYCODE) {
            this.primaryAction();
        }
    },

    primaryAction: function() {
        // Not implemented.
    },

    onModalHidden: function() {
        this.destroy();
    },

    hide: function() {
        this.$el.modal('hide');
    }
});

var ConfirmView = ModalBaseView.extend({
    template: modalConfirmTmpl,

    ui: {
        confirmation: '.confirm'
    },

    events: _.defaults({
        'click @ui.confirmation': 'primaryAction'
    }, ModalBaseView.prototype.events),

    primaryAction: function() {
        this.triggerMethod('confirmation');
        this.hide();
    }
});

var InputView = ModalBaseView.extend({
    template: modalInputTmpl,

    ui: {
        save: '.save',
        input: 'input',
        error: '.error'
    },

    events: _.defaults({
        'click @ui.save': 'primaryAction'
    }, ModalBaseView.prototype.events),

    onModalShown: function() {
        this.ui.input.focus().select();
    },

    primaryAction: function() {
        var val = this.ui.input.val().trim();
        if (val) {
            this.triggerMethod('update', val);
            this.hide();
        } else {
            this.ui.error.text('Please enter a valid project name');
        }
    }
});

var ShareView = ModalBaseView.extend({
    template: modalShareTmpl,

    ui: {
        'signin': '.signin',
        'copy': '.copy',
        'input': 'input'
    },

    events: _.defaults({
        'click @ui.signin': 'signIn'
    }, ModalBaseView.prototype.events),

    initialize: function() {
        this.zc = new ZeroClipboard();
    },

    // Override to attach ZeroClipboard to ui.copy button
    onRender: function() {
        var self = this;
        this.$el.on('shown.bs.modal', function() {
            self.zc.clip(self.ui.copy);
        });

        if (this.model.get('is_private')) {
            var question = 'This project is currently private. ' +
                    'You must make it public before it can be shared with others. ' +
                    'Once public, anyone with the URL can access it.',
                confirm = new ConfirmView({
                    model: new models.ConfirmModel({
                        question: question,
                        confirmLabel: 'Make Public',
                        cancelLabel: 'Cancel'
                    })
                });

            confirm.render();
            confirm.on('confirmation', function() {
                var project = self.options.app.currProject;
                project.set('is_private', false);
                project.saveProjectAndScenarios();

                self.$el.modal('show');
            });
        } else {
            this.$el.modal('show');
        }
    },

    onModalShown: function() {
        this.ui.input.focus().select();
    },

    signIn: function() {
        this.options.app.getUserOrShowLogin();
    }

});

module.exports = {
    ShareView: ShareView,
    InputView: InputView,
    ConfirmView: ConfirmView
};
<commit_msg>Trigger event when canceling a confirmation modal.<commit_after>"use strict";

var _ = require('underscore'),
    Marionette = require('../../../shim/backbone.marionette'),
    ZeroClipboard = require('zeroclipboard'),
    models = require('./models'),
    modalConfirmTmpl = require('./templates/confirmModal.html'),
    modalInputTmpl = require('./templates/inputModal.html'),
    modalShareTmpl = require('./templates/shareModal.html'),

    ENTER_KEYCODE = 13,
    BASIC_MODAL_CLASS = 'modal modal-basic fade';

var ModalBaseView = Marionette.ItemView.extend({
    className: BASIC_MODAL_CLASS,

    attributes: {
        'tabindex': '-1'
    },

    events: {
        'shown.bs.modal': 'onModalShown',
        'keyup': 'onKeyUp',
        'hidden.bs.modal': 'onModalHidden'
    },

    onRender: function() {
        this.$el.modal('show');
    },

    onModalShown: function() {
        // Not implemented.
    },

    onKeyUp: function(e) {
        if (e.keyCode === ENTER_KEYCODE) {
            this.primaryAction();
        }
    },

    primaryAction: function() {
        // Not implemented.
    },

    onModalHidden: function() {
        this.destroy();
    },

    hide: function() {
        this.$el.modal('hide');
    }
});

var ConfirmView = ModalBaseView.extend({
    template: modalConfirmTmpl,

    ui: {
        confirmation: '.confirm',
        deny: '.btn-default'
    },

    events: _.defaults({
        'click @ui.confirmation': 'primaryAction',
        'click @ui.deny': 'dismissAction'
    }, ModalBaseView.prototype.events),

    primaryAction: function() {
        this.triggerMethod('confirmation');
        this.hide();
    },

    dismissAction: function() {
        this.triggerMethod('deny');
    }
});

var InputView = ModalBaseView.extend({
    template: modalInputTmpl,

    ui: {
        save: '.save',
        input: 'input',
        error: '.error'
    },

    events: _.defaults({
        'click @ui.save': 'primaryAction'
    }, ModalBaseView.prototype.events),

    onModalShown: function() {
        this.ui.input.focus().select();
    },

    primaryAction: function() {
        var val = this.ui.input.val().trim();
        if (val) {
            this.triggerMethod('update', val);
            this.hide();
        } else {
            this.ui.error.text('Please enter a valid project name');
        }
    }
});

var ShareView = ModalBaseView.extend({
    template: modalShareTmpl,

    ui: {
        'signin': '.signin',
        'copy': '.copy',
        'input': 'input'
    },

    events: _.defaults({
        'click @ui.signin': 'signIn'
    }, ModalBaseView.prototype.events),

    initialize: function() {
        this.zc = new ZeroClipboard();
    },

    // Override to attach ZeroClipboard to ui.copy button
    onRender: function() {
        var self = this;
        this.$el.on('shown.bs.modal', function() {
            self.zc.clip(self.ui.copy);
        });

        if (this.model.get('is_private')) {
            var question = 'This project is currently private. ' +
                    'You must make it public before it can be shared with others. ' +
                    'Once public, anyone with the URL can access it.',
                confirm = new ConfirmView({
                    model: new models.ConfirmModel({
                        question: question,
                        confirmLabel: 'Make Public',
                        cancelLabel: 'Cancel'
                    })
                });

            confirm.render();
            confirm.on('confirmation', function() {
                var project = self.options.app.currProject;
                project.set('is_private', false);
                project.saveProjectAndScenarios();

                self.$el.modal('show');
            });
        } else {
            this.$el.modal('show');
        }
    },

    onModalShown: function() {
        this.ui.input.focus().select();
    },

    signIn: function() {
        this.options.app.getUserOrShowLogin();
    }

});

module.exports = {
    ShareView: ShareView,
    InputView: InputView,
    ConfirmView: ConfirmView
};
<|endoftext|>


<commit_before>var su = ''; //http://ec2-54-200-40-68.us-west-2.compute.amazonaws.com:8080';

var _user_details = '/user/details';

var chat_check_id, firepad, chatroomid;

var _user_details = 'http://web.mit.edu/ambhave/www/suitup/user_details.json';

function init_user_details() {
    console.log('init_user_details()');

    $.getJSON(_user_details, function (data) {
        $('.user_username').text(data['username']);
    }).error(function (jqXhr, textStatus, error) {
        alert("ERROR: " + textStatus + ", " + error);
    });
}

$(document).ready(function () {
  //  login();
    //  init_user_details();

});

function chat_join(s) {
    $.ajax({
        type: "GET",
        url: su + '/chatroom/join',
        success: function (data) {
            chatroomid = JSON.parse(data).crid;
            $('#firepad').html('');
            var firepadRef = new Firebase('//hackmitsuitup.firebaseIO.com/firepads/' + chatroomid);
            var codeMirror = CodeMirror(document.getElementById('firepad'), {
                lineNumbers: true,
                mode: 'python'
            });
            firepad = Firepad.fromCodeMirror(firepadRef, codeMirror);
            webrtc.on('readyToCall', function () {
            });
            setTimeout(join_room, 2000);
            chat_check_id = setTimeout(chat_check, 1000);
            question_new();
        }
    });
}

function join_room() {
    // webrtc.createRoom(chatroomid);
    webrtc.joinRoom(String(chatroomid));
}

function chat_leave() {
    clearTimeout(chat_check_id);
    $.ajax({
        type: "GET",
        url: su + '/chatroom/leave',
        success: function (data) {
            $('#firepad').html('');
        }
    });
    chatroomid = null;
    webrtc.leaveRoom(webrtc.roomName);
}
$(window).bind('beforeunload', function () {
    $.ajax({
        type: "GET",
        url: su + '/chatroom/leave',
        async: false
    });

});

function chat_send(chat, convo) {
    $.ajax({
        type: "GET",
        url: su + '/message/send',
        data: { 's': $('#' + chat).val() }
    });
    $('#' + convo).html($('#' + convo).html() + 'Me: ' + $('#' + chat).val());
    $('#' + chat).val('');
}

function chat_check() {
    $.ajax({
        type: "GET",
        url: su + '/message/check',
        success: function (data) {
            sts = JSON.parse(data).status;
            if ( sts == "failure") {
                console.log("Rejoining to new person");
                $('#firepad').html('');
                $('#convo').val('');
                $('#chat').val('');
                chat_join();
            } else {
                if(JSON.parse(data).s != "") {
                    //$('#convo').val($('#convo').val() + '\nOther: ' + JSON.parse(data).s);
                    $('#convo').html($('#convo').html() + 'Other: ' + JSON.parse(data).s);
                    setTimeout(chat_check, 1000);
                } else {
                    setTimeout(chat_check, 2000);
                }
            }
        }
    });
}

function question_new() {
    $.getJSON(su + '/question/new', {'cvid': chatroomid }, function (data) {
        $('.questions_title').text(data['title']);
        $('.questions_body').html(data['body']);
    }).error(function (jqXhr, textStatus, error) {
        alert("ERROR: " + textStatus + ", " + error);
    });
}

function question_submit() {
    $.ajax({
        type: "POST",
        data: {'submission': firepad.getText(), 'cvid': chatroomid },
        url: su + '/question/submit',
        success: function (data) {

        }
    });
}

// Load the SDK asynchronously
(function (d) {
    var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
    if (d.getElementById(id)) { return; }
    js = d.createElement('script'); js.id = id; js.async = true;
    js.src = "//connect.facebook.net/en_US/all.js";
    ref.parentNode.insertBefore(js, ref);
}(document));

var access_token = null;
var user_city = null;
var fb_user = null;

function login() {
    _login_wait();

    FB.login(function (response) {
        //_check_login();
    });
}
function logout() {
    _login_wait();

    FB.logout(function (response) {
        //_login_bad();
    });
}

// Additional JS functions here
window.fbAsyncInit = function () {
    FB.init({
        appId: '615988445111525', // App ID
        channelUrl: '//localhost:8000/channel.html', // Channel File
        status: true, // check login status
        cookie: true, // enable cookies to allow the server to access the session
        xfbml: true  // parse XFBML
    });

    // Additional init code here
    //_check_login();
    _login_wait();
    FB.getLoginStatus(function (response) {
        if (response.status !== 'connected') {
            _login_bad();
        }
    });

    FB.Event.subscribe('auth.statusChange', function (response) {
        _check_login();
        console.log(response);
    });
};

/* Helper Functions */
function _hide_all_login() {
    $('.pLoginBad').hide();
    $('.pLoginDone').hide();
    $('.pLoginWait').hide();
}
function _check_login() {
    _login_wait();
    FB.getLoginStatus(function (response) {
        if (response.status === 'connected') {
            _login_done(response);
        }
        else {
            _login_bad();
        }
    });
}
function _login_wait() {
    _hide_all_login();
    $('.pLoginWait').show();
}
function _login_bad() {
    _hide_all_login();
    $('.pLoginBad').show();
}
function _login_done(response) {

    if (response != null)
        access_token = response.authResponse.accessToken;

    FB.api('/me?fields=picture,name', function (response) {
        fb_user = response;
        console.log(response);
        $('.user_username').text(response.name);
        $('.user_photourl').attr('src', response.picture.data.url);

        _hide_all_login();
        $('.pLoginDone').show();
    });

    // TODO: UNCOMMENT THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
    $.ajax({ url: su + '/login?access_token=' + access_token }).success(function (data) { chat_join(); });

    //$.ajax({url:"demo_test.txt",success:function(result){    $("#div1").html(result);  }});

    /*

    FB.api('/me/home', function(response) {
       console.log(response);
       $('#news_feed').empty();
       for (var i = 0; i < response['data'].length; i++) {
           var item = response['data'][i];
           var txt = '
 \
                    \
                        \
                    \

  \

' + item['from']['name'] + '
            \

 \

';
           $('#news_feed').append(txt);
       }
    });*/
}
function _fatal_error(message) {
    $('body').html('Fatal Error! Please refresh the page

Message: ' + message);
}

<commit_msg>fix chat<commit_after>var su = ''; //http://ec2-54-200-40-68.us-west-2.compute.amazonaws.com:8080';

var _user_details = '/user/details';

var chat_check_id, firepad, chatroomid;

var _user_details = 'http://web.mit.edu/ambhave/www/suitup/user_details.json';

function init_user_details() {
    console.log('init_user_details()');

    $.getJSON(_user_details, function (data) {
        $('.user_username').text(data['username']);
    }).error(function (jqXhr, textStatus, error) {
        alert("ERROR: " + textStatus + ", " + error);
    });
}

$(document).ready(function () {
  //  login();
    //  init_user_details();

});

function chat_join(s) {
    $.ajax({
        type: "GET",
        url: su + '/chatroom/join',
        success: function (data) {
            chatroomid = JSON.parse(data).crid;
            $('#firepad').html('');
            var firepadRef = new Firebase('//hackmitsuitup.firebaseIO.com/firepads/' + chatroomid);
            var codeMirror = CodeMirror(document.getElementById('firepad'), {
                lineNumbers: true,
                mode: 'python'
            });
            firepad = Firepad.fromCodeMirror(firepadRef, codeMirror);
            webrtc.on('readyToCall', function () {
            });
            setTimeout(join_room, 2000);
            chat_check_id = setTimeout(chat_check, 1000);
            question_new();
        }
    });
}

function join_room() {
    // webrtc.createRoom(chatroomid);
    webrtc.joinRoom(String(chatroomid));
}

function chat_leave() {
    clearTimeout(chat_check_id);
    $.ajax({
        type: "GET",
        url: su + '/chatroom/leave',
        success: function (data) {
            $('#firepad').html('');
        }
    });
    chatroomid = null;
    webrtc.leaveRoom(webrtc.roomName);
}
$(window).bind('beforeunload', function () {
    $.ajax({
        type: "GET",
        url: su + '/chatroom/leave',
        async: false
    });

});

function chat_send(chat, convo) {
    $.ajax({
        type: "GET",
        url: su + '/message/send',
        data: { 's': $('#' + chat).val() }
    });
    $('#' + convo).html($('#' + convo).html() + 'Me: ' + $('#' + chat).val());
    $('#' + chat).val('');
}

function chat_check() {
    $.ajax({
        type: "GET",
        url: su + '/message/check',
        success: function (data) {
            sts = JSON.parse(data).status;
            if ( sts == "failure") {
                console.log("Rejoining to new person");
                $('#firepad').html('');
                $('#convo').val('');
                $('#chat').val('');
                chat_join();
            } else {
                if(JSON.parse(data).s != "") {
                    //$('#convo').val($('#convo').val() + '\nOther: ' + JSON.parse(data).s);
                    $('#convo').html($('#convo').html() + '
Other: ' + JSON.parse(data).s);
                    setTimeout(chat_check, 1000);
                } else {
                    setTimeout(chat_check, 2000);
                }
            }
        }
    });
}

function question_new() {
    $.getJSON(su + '/question/new', {'cvid': chatroomid }, function (data) {
        $('.questions_title').text(data['title']);
        $('.questions_body').html(data['body']);
    }).error(function (jqXhr, textStatus, error) {
        alert("ERROR: " + textStatus + ", " + error);
    });
}

function question_submit() {
    $.ajax({
        type: "POST",
        data: {'submission': firepad.getText(), 'cvid': chatroomid },
        url: su + '/question/submit',
        success: function (data) {

        }
    });
}

// Load the SDK asynchronously
(function (d) {
    var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
    if (d.getElementById(id)) { return; }
    js = d.createElement('script'); js.id = id; js.async = true;
    js.src = "//connect.facebook.net/en_US/all.js";
    ref.parentNode.insertBefore(js, ref);
}(document));

var access_token = null;
var user_city = null;
var fb_user = null;

function login() {
    _login_wait();

    FB.login(function (response) {
        //_check_login();
    });
}
function logout() {
    _login_wait();

    FB.logout(function (response) {
        //_login_bad();
    });
}

// Additional JS functions here
window.fbAsyncInit = function () {
    FB.init({
        appId: '615988445111525', // App ID
        channelUrl: '//localhost:8000/channel.html', // Channel File
        status: true, // check login status
        cookie: true, // enable cookies to allow the server to access the session
        xfbml: true  // parse XFBML
    });

    // Additional init code here
    //_check_login();
    _login_wait();
    FB.getLoginStatus(function (response) {
        if (response.status !== 'connected') {
            _login_bad();
        }
    });

    FB.Event.subscribe('auth.statusChange', function (response) {
        _check_login();
        console.log(response);
    });
};

/* Helper Functions */
function _hide_all_login() {
    $('.pLoginBad').hide();
    $('.pLoginDone').hide();
    $('.pLoginWait').hide();
}
function _check_login() {
    _login_wait();
    FB.getLoginStatus(function (response) {
        if (response.status === 'connected') {
            _login_done(response);
        }
        else {
            _login_bad();
        }
    });
}
function _login_wait() {
    _hide_all_login();
    $('.pLoginWait').show();
}
function _login_bad() {
    _hide_all_login();
    $('.pLoginBad').show();
}
function _login_done(response) {

    if (response != null)
        access_token = response.authResponse.accessToken;

    FB.api('/me?fields=picture,name', function (response) {
        fb_user = response;
        console.log(response);
        $('.user_username').text(response.name);
        $('.user_photourl').attr('src', response.picture.data.url);

        _hide_all_login();
        $('.pLoginDone').show();
    });

    // TODO: UNCOMMENT THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
    $.ajax({ url: su + '/login?access_token=' + access_token }).success(function (data) { chat_join(); });

    //$.ajax({url:"demo_test.txt",success:function(result){    $("#div1").html(result);  }});

    /*

    FB.api('/me/home', function(response) {
       console.log(response);
       $('#news_feed').empty();
       for (var i = 0; i < response['data'].length; i++) {
           var item = response['data'][i];
           var txt = '
 \
                    \
                        \
                    \

  \

' + item['from']['name'] + '
            \

 \

';
           $('#news_feed').append(txt);
       }
    });*/
}
function _fatal_error(message) {
    $('body').html('Fatal Error! Please refresh the page

Message: ' + message);
}

<|endoftext|>


<commit_before>// @flow
import styled from "styled-components";
import { withLayout } from "./LayoutProvider";
import { breakpoint, applyBreakpointStyle } from "../utils";
import { applyStyle } from '../utils/styles';
import hexToRgb from '../utils/hexToRgb';

const applyWidth = (rule, value, defaultValue = '') => {
  switch (typeof value) {
  case 'string':
    return `${rule}: ${value};`;
  case 'object':
    return Object.keys(value).map(key =>
      breakpoint(key, (props, name) => `${rule}: ${value[key]};`)
    );
  default:
    return defaultValue;
  }
}

const debugStyles = {
  outline: '1px solid #fff',
  background: 'rgba(0, 0, 100, .15)'
};

const toRgba = (rbg) => {
  const result = [];

  rbg.map((n) => result.push(String(n)));
  result.push('.15');

  return result.join(',');
}
const getDebugStyles = (props) => {
  const outline = props.debug.outline ? props.debug.outline : debugStyles.outline;
  const background = /^#/.test(props.debug.fill) ? `rgba(${toRgba(hexToRgb(props.debug.fill))})` : debugStyles.background;

  console.log(background);

  return [`background: ${background}`, `outline: ${outline}`];
};

const compute = name =>
  breakpoint(name, (props, name) => [
    applyBreakpointStyle('width', props.width, name),
    applyBreakpointStyle('height', props.height, name),
    applyBreakpointStyle('margin-left', props.shift, name),
    applyBreakpointStyle('flex-grow', props.grow, name, { on: 1, off: 0 }),
    applyBreakpointStyle('flex-shrink', props.shrink, name, { on: 1, off: 0 }),
    applyBreakpointStyle('flex', props.flex, name),
    applyBreakpointStyle('padding', props.gutter, name),
    applyBreakpointStyle('padding', props.fluid, name, { on: '0', off: props.gutter }),
  ]);

const Box = styled.div`
  box-sizing: border-box;
  display: ${props => props.block ? "block" : "flex"};
  flex-direction: column;
  overflow: ${props => props.overflow ? props.overflow : "auto"};
  ${props => applyStyle(props.debug && props.debug.enabled, getDebugStyles(props))};

  ${compute("xs")}
  ${compute("sm")}
  ${compute("md")}
  ${compute("lg")}
`;

Box.defaultProps = {
  shrink: true
};

export default withLayout(Box);
<commit_msg>remove console.log<commit_after>// @flow
import styled from "styled-components";
import { withLayout } from "./LayoutProvider";
import { breakpoint, applyBreakpointStyle } from "../utils";
import { applyStyle } from '../utils/styles';
import hexToRgb from '../utils/hexToRgb';

const applyWidth = (rule, value, defaultValue = '') => {
  switch (typeof value) {
  case 'string':
    return `${rule}: ${value};`;
  case 'object':
    return Object.keys(value).map(key =>
      breakpoint(key, (props, name) => `${rule}: ${value[key]};`)
    );
  default:
    return defaultValue;
  }
}

const debugStyles = {
  outline: '1px solid #fff',
  background: 'rgba(0, 0, 100, .15)'
};

const toRgba = (rbg) => {
  const result = [];

  rbg.map((n) => result.push(String(n)));
  result.push('.15');

  return result.join(',');
}
const getDebugStyles = (props) => {
  const outline = props.debug.outline ? props.debug.outline : debugStyles.outline;
  const background = /^#/.test(props.debug.fill) ? `rgba(${toRgba(hexToRgb(props.debug.fill))})` : debugStyles.background;

  return [`background: ${background}`, `outline: ${outline}`];
};

const compute = name =>
  breakpoint(name, (props, name) => [
    applyBreakpointStyle('width', props.width, name),
    applyBreakpointStyle('height', props.height, name),
    applyBreakpointStyle('margin-left', props.shift, name),
    applyBreakpointStyle('flex-grow', props.grow, name, { on: 1, off: 0 }),
    applyBreakpointStyle('flex-shrink', props.shrink, name, { on: 1, off: 0 }),
    applyBreakpointStyle('flex', props.flex, name),
    applyBreakpointStyle('padding', props.gutter, name),
    applyBreakpointStyle('padding', props.fluid, name, { on: '0', off: props.gutter }),
  ]);

const Box = styled.div`
  box-sizing: border-box;
  display: ${props => props.block ? "block" : "flex"};
  flex-direction: column;
  overflow: ${props => props.overflow ? props.overflow : "auto"};
  ${props => applyStyle(props.debug && props.debug.enabled, getDebugStyles(props))};

  ${compute("xs")}
  ${compute("sm")}
  ${compute("md")}
  ${compute("lg")}
`;

Box.defaultProps = {
  shrink: true
};

export default withLayout(Box);
<|endoftext|>


<commit_before>//Dependencies.
var Immutable = require('immutable');
var CoreStore = require('../CoreStore');
var getDefinition = require('./definition');
var uuid = require('uuid').v4;
const CLEAR = 'clear';
const UPDATE = 'update';
var AppDispatcher = require('../../dispatcher');

/**
 * Class standing for the cartridge store.
 */
class RequestStore extends CoreStore {
  /**
   * Add a listener on the global change on the search store.
   * @param {object} conf - The configuration of the request store.
   */
  constructor(conf){
    conf = conf || {};
    conf.definition = conf.definition || getDefinition();
    super(conf);
    this.pending = Immutable.Map({});
    this.success = Immutable.Map({});
    this.error = Immutable.Map({});
    this.cancelled = Immutable.Map({});
  }
  /**
   * Get a message from its identifier.
   * @param {string} messageId - The message identifier.
   * @returns {object} - The requested message.
   */
  getRequest(requestId){
    if(!this.data.has(requestId)){
      return undefined;
    }
    return this.data.get(requestId);
  }
  /**
   * Get the requests by type
   * @return {object} An object with the total of request by type.
   */
  getRequests(){
    return {
      'pending': this.pending.size,
      'cancelled': this.cancelled.size,
      'success': this.success.size,
      'error': this.error.size,
      'total': this.pending.size + this.cancelled.size + this.success.size + this.error.size
    };
  }
  /**
   * Add a listener on the global change on the search store.
   * @param {object} message - The message to add.
   */
  updateRequest(request){
    request.id = request.id || `${uuid()}`;
    //If the status is supported
    if(this.definition[request.status]){
      //Update the associated collection
      this[request.status] = this[request.status].set(request.id, request);
      //Remove the associated request from pending
      if(request.status !== 'pending' && this.pending.has(request.id)){
        this.pending = this.pending.delete(request.id);
      }
    }
    this.emit(UPDATE, request.id);
  }
  /**
   * Clear all messages in the stack.
   */
  clearRequests(){
    this.data = this.data.clear();
    this.emit(CLEAR);
  }
  /**
   * Add a listener on the global change on the search store.
   * @param {function} cb - The callback to call when a message is pushed.
   */
  addUpdateRequestListener(cb){
    this.addListener(UPDATE, cb);
  }
  /**
   * Remove a listener on the global change on the search store.
   * @param {function} cb - The callback to called when a message is pushed.
   */
  removeUpdateRequestListener(cb){
    this.removeListener(UPDATE, cb);
  }

  /**
   * Add a listener on the global change on the search store.
   * @param {function} cb - The callback to call when a message is pushed.
   */
  addClearRequestsListener(cb){
    this.addListener(CLEAR, cb);
  }
  /**
   * Remove a listener on the global change on the search store.
   * @param {function} cb - The callback to called when a message is pushed.
   */
  removeClearRequestsListener(cb){
    this.removeListener(CLEAR, cb);
  }
  registerDispatcher(){
    var currentStore = this;
    this.dispatch = AppDispatcher.register(function(transferInfo) {
      var rawData = transferInfo.action.data;
      var type = transferInfo.action.type;
      if(!rawData.request){return;}
      switch (type) {
        case 'update':
          if(rawData.request){
            currentStore.updateRequest(rawData.request);
          }
          break;
        case 'clear':
          if(rawData.request){
            currentStore.clearRequest();
          }
          break;
      }
    });
  }
}

module.exports = RequestStore;
<commit_msg>[request] Fix store mistake on clear action<commit_after>//Dependencies.
var Immutable = require('immutable');
var CoreStore = require('../CoreStore');
var getDefinition = require('./definition');
var uuid = require('uuid').v4;
const CLEAR = 'clear';
const UPDATE = 'update';
var AppDispatcher = require('../../dispatcher');

/**
 * Class standing for the cartridge store.
 */
class RequestStore extends CoreStore {
  /**
   * Add a listener on the global change on the search store.
   * @param {object} conf - The configuration of the request store.
   */
  constructor(conf){
    conf = conf || {};
    conf.definition = conf.definition || getDefinition();
    super(conf);
    this.pending = Immutable.Map({});
    this.success = Immutable.Map({});
    this.error = Immutable.Map({});
    this.cancelled = Immutable.Map({});
  }
  /**
   * Get a message from its identifier.
   * @param {string} messageId - The message identifier.
   * @returns {object} - The requested message.
   */
  getRequest(requestId){
    if(!this.data.has(requestId)){
      return undefined;
    }
    return this.data.get(requestId);
  }
  /**
   * Get the requests by type
   * @return {object} An object with the total of request by type.
   */
  getRequests(){
    return {
      'pending': this.pending.size,
      'cancelled': this.cancelled.size,
      'success': this.success.size,
      'error': this.error.size,
      'total': this.pending.size + this.cancelled.size + this.success.size + this.error.size
    };
  }
  /**
   * Add a listener on the global change on the search store.
   * @param {object} message - The message to add.
   */
  updateRequest(request){
    request.id = request.id || `${uuid()}`;
    //If the status is supported
    if(this.definition[request.status]){
      //Update the associated collection
      this[request.status] = this[request.status].set(request.id, request);
      //Remove the associated request from pending
      if(request.status !== 'pending' && this.pending.has(request.id)){
        this.pending = this.pending.delete(request.id);
      }
    }
    this.emit(UPDATE, request.id);
  }
  /**
   * Clear all messages in the stack.
   */
  clearRequests(){
    this.data = this.data.clear();
    this.emit(CLEAR);
  }
  /**
   * Add a listener on the global change on the search store.
   * @param {function} cb - The callback to call when a message is pushed.
   */
  addUpdateRequestListener(cb){
    this.addListener(UPDATE, cb);
  }
  /**
   * Remove a listener on the global change on the search store.
   * @param {function} cb - The callback to called when a message is pushed.
   */
  removeUpdateRequestListener(cb){
    this.removeListener(UPDATE, cb);
  }

  /**
   * Add a listener on the global change on the search store.
   * @param {function} cb - The callback to call when a message is pushed.
   */
  addClearRequestsListener(cb){
    this.addListener(CLEAR, cb);
  }
  /**
   * Remove a listener on the global change on the search store.
   * @param {function} cb - The callback to called when a message is pushed.
   */
  removeClearRequestsListener(cb){
    this.removeListener(CLEAR, cb);
  }
  registerDispatcher(){
    var currentStore = this;
    this.dispatch = AppDispatcher.register(function(transferInfo) {
      var rawData = transferInfo.action.data;
      var type = transferInfo.action.type;
      if(!rawData.request){return;}
      switch (type) {
        case 'update':
          if(rawData.request){
            currentStore.updateRequest(rawData.request);
          }
          break;
        case 'clear':
          if(rawData.request){
            currentStore.clearRequests();
          }
          break;
      }
    });
  }
}

module.exports = RequestStore;
<|endoftext|>


<commit_before>/*global $, JSONEditor, ace, Storage, Logger, Utils, Rules, Rule, I18n, ChromeBootstrap, Editor, JSONF, exportRules */
/*eslint no-unused-vars: [2, { "vars": "local"}]*/
// This file is a big bag of mixed responsibilities.
// Break this into parts!
var editor = new Editor("#ruleeditor-ace");

var noticesVisible = false;

I18n.loadPages(["help", "importexport", "about", "changelog", "modalimportrules", "modalimportworkflows", "modalimportall"]);

if(Utils.debug) {
  I18n.loadPages(["logs"]);
}

ChromeBootstrap.init();

// reset notices once the user starts typing again
editor.on("change", function() {
  if(noticesVisible) {
    $("#ruleeditor .notice").hide();
    noticesVisible = false;
  }
});

// Current active tab id
var currentTabId = function() {
  var currentTab = $("#ruleeditor .tab.current");
  if(currentTab.length === 1) {
    return currentTab.data("tab-id");
  }
  return 1;
};

// Append text to the end of the rule definitions
var appendRule = function(prettyRule, responseCallback) {
  // Use
  Rules.load().then(function(rulesFunction) {
    var lines = [];
    if(rulesFunction.length > 0) {
      lines.push(",");
    }
    lines = lines.concat(prettyRule.split("\n"));
    editor.document().insertLines(editor.document().getLength() - 1, lines);

    // Prettify code a little
    editor.session().setValue(Rules.format(editor.session().getValue()), -1);
    editor.editor().scrollToRow(editor.document().getLength());
    editor.resize();
    responseCallback();
    Utils.infoMsg("Rule added on line " + (editor.document().getLength() - 1));
  });
};

// Check for freshly extracted rules and show UI
Storage.load(Utils.keys.extractedRule).then(function (extractedRule) {
  // There are extracted rules
  if (typeof extractedRule !== "undefined") {
    var $notice = $("#ruleeditor .notice.extracted-present");
    $notice.show();
    $("#ruleeditor .cmd-append-extracted").on("click", function () {
      Logger.info("[options.js] Appending extracted rules to the end of the definition");
      appendRule(extractedRule, function() {
        $notice.hide();
        Storage.delete(Utils.keys.extractedRule);
      });
    });
  }
});

// Check for rule filling errors
Storage.load(Utils.keys.errors).then(function (errorsStorage) {
  if(typeof errorsStorage !== "undefined") {
    var rule = errorsStorage.rule;
    var errors = errorsStorage.errors;
    var $notice = $("#ruleeditor .notice.form-fill-errors");
    var tableTrs = [];
    var fullMsg = false;
    errors.forEach(function (error) {
      Logger.info("[options.js] Got error " + JSONF.stringify(error) + " for rule " + JSONF.stringify(rule));
      if(typeof error.fullMessage !== "undefined") {
        // One line output
        tableTrs.push("
" + error.fullMessage + "
");
        fullMsg = true;
      } else {
        // Typically an error in a rule
        tableTrs.push("
" + error.selector + "	" + error.value + "	" + error.message + "
");
      }
    });
    $notice.find("table").append(tableTrs.join("\n"));
    if(fullMsg) {
      $notice.find("#form-filling-errors-thead").remove();
    }
    $notice.find(".rule-name").html(rule.nameClean);
    $notice.find(".rule-url").html(rule.urlClean);
    $notice.show();
    Storage.delete(Utils.keys.errors);

    // Activate the tab with the rule
    var match = rule.id.match(/^([0-9]+)/);
    if(match) {
      Logger.info("[options.js] Activating tab #" + match[1]);
      $(".tab[data-tab-id='" + match[1] + "']").trigger("click");
    }
  }
});

// Read all rules to update stats
// Also fill quickjump select
var updateTabStats = function() {
  Rules.all().then(function (rules) {
    var rulesStats = { tabCount: {}, rules: []};

    rules.forEach(function (rule) {
      // Count rules
      if (typeof rulesStats.tabCount[rule.tabId] === "undefined") {
        rulesStats.tabCount[rule.tabId] = 0;
      }
      rulesStats.tabCount[rule.tabId] += 1;
      rulesStats.rules.push({
        name: rule.nameClean,
        id: rule.id
      });
    });

    // rulesStats has now a count of all rules per tab
    Object.keys(rulesStats.tabCount).forEach(function (key) {
      $(".tab[data-tab-id='" + key + "'] .rule-count").html("(" + rulesStats.tabCount[key] + ")");
    });

    // Fill <select> rules overview
    var options = ["<option value=''>- quickjump to rule -</option>"];

    // Remove rules without names (eg. libs)
    var onlyRealRules = rulesStats.rules.filter(function (rule) {
       return typeof rule.name != "undefined";
    });

    // Create <option> tags for sorted list of rules and insert into DOM
    Utils.sortRules(onlyRealRules).forEach(function (rule) {
      options.push("<option value='" + rule.id + "'>" + rule.name + "</option>");
    });
    $("#rules-overview").html(options.join(""));
  });
};

// Save the rules
var saveRules = function(tabId) {
  var errors = Rules.syntaxCheck(editor);
  if(errors.length > 0) {
    errors.forEach(function (errorClass) {
      $("#ruleeditor .notice." + errorClass).show();
    });
    noticesVisible = true;
  }

  if(editor.cleanUp()) {
    Rules.save(editor.getValue(), tabId).then(function () {
      Utils.infoMsg("Rules saved");
      updateTabStats();
    });
  }
};

// Load the rules
var loadRules = function(tabId) {
  Storage.load(Utils.keys.rules + "-tab-" + tabId).then(function (ruleData) {
    var ruleJson = null;
    if(typeof ruleData === "undefined" || typeof ruleData.code === "undefined") {
      ruleJson = "";
    } else {
      ruleJson = ruleData.code;
    }
    editor.setValue(ruleJson, -1);
    Utils.infoMsg("Rules loaded from disc");
  });
};

// import rules from disc
var importRules = function() {
  $("#modalimportrules").show();
};

var quickJumpToRule = function() {
  var selected = $(this).find("option:selected");
  var tabId = selected.val().split("-")[0];
  var name = selected.text();

  // If the target tab is not the active one, click to trigger
  if(currentTabId().toString() !== tabId) {
    $("#ruleeditor .tab[data-tab-id=" + tabId + "]").trigger("click");
  }

  var found = editor.editor().find(name, { backwards: false, skipCurrent: false }, false);
  editor.editor().gotoLine(found.start.row, 1, false);
};

// Load data from tab and prefill editor
loadRules(currentTabId());
updateTabStats();
editor.resize();

// Button handling for "save" and "load"
$(".editor .menu").on("click", "button.save", function () {
  saveRules(currentTabId());
}).on("click", "button.reload", function () {
  loadRules(currentTabId());
}).on("click", "button.format", function () {
  editor.format(Rules);
  Utils.infoMsg("Rules formatted but not saved");
});

// Show modal import window
$(document).on("click", "button.import, .rl-button-import", importRules);

// Export all rules (for modal import dialog)
$(document).on("click", "button.export, a.cmd-export-all-rules, button.rl-button-export", exportRules);

// Support for the quickjump <select>
$("#rules-overview").on("change", quickJumpToRule);

// Event handler for notices
$(".notice.form-fill-errors").on("click", function () {
  Storage.delete(Utils.keys.errors);
  $(this).hide();
});

$(".notice.extracted-present").on("click", function () {
  Storage.delete(Utils.keys.extractedRule);
  $(this).hide();
});

$(".notice.annotations-present, .notice.error").on("click", function () {
  $(this).hide();
});

<commit_msg>add todo<commit_after>/*global $, JSONEditor, ace, Storage, Logger, Utils, Rules, Rule, I18n, ChromeBootstrap, Editor, JSONF, exportRules */
/*eslint no-unused-vars: [2, { "vars": "local"}]*/
// This file is a big bag of mixed responsibilities.
// Break this into parts!
var editor = new Editor("#ruleeditor-ace");

var noticesVisible = false;

I18n.loadPages(["help", "importexport", "about", "changelog", "modalimportrules", "modalimportworkflows", "modalimportall"]);

if(Utils.debug) {
  I18n.loadPages(["logs"]);
}

ChromeBootstrap.init();

// reset notices once the user starts typing again
editor.on("change", function() {
  if(noticesVisible) {
    $("#ruleeditor .notice").hide();
    noticesVisible = false;
  }
});

// Current active tab id
var currentTabId = function() {
  var currentTab = $("#ruleeditor .tab.current");
  if(currentTab.length === 1) {
    return currentTab.data("tab-id");
  }
  return 1;
};

// Append text to the end of the rule definitions
// TODO: use a promise here
var appendRule = function(prettyRule, responseCallback) {
  // Use
  Rules.load().then(function(rulesFunction) {
    var lines = [];
    if(rulesFunction.length > 0) {
      lines.push(",");
    }
    lines = lines.concat(prettyRule.split("\n"));
    editor.document().insertLines(editor.document().getLength() - 1, lines);

    // Prettify code a little
    editor.session().setValue(Rules.format(editor.session().getValue()), -1);
    editor.editor().scrollToRow(editor.document().getLength());
    editor.resize();
    responseCallback();
    Utils.infoMsg("Rule added on line " + (editor.document().getLength() - 1));
  });
};

// Check for freshly extracted rules and show UI
Storage.load(Utils.keys.extractedRule).then(function (extractedRule) {
  // There are extracted rules
  if (typeof extractedRule !== "undefined") {
    var $notice = $("#ruleeditor .notice.extracted-present");
    $notice.show();
    $("#ruleeditor .cmd-append-extracted").on("click", function () {
      Logger.info("[options.js] Appending extracted rules to the end of the definition");
      appendRule(extractedRule, function() {
        $notice.hide();
        Storage.delete(Utils.keys.extractedRule);
      });
    });
  }
});

// Check for rule filling errors
Storage.load(Utils.keys.errors).then(function (errorsStorage) {
  if(typeof errorsStorage !== "undefined") {
    var rule = errorsStorage.rule;
    var errors = errorsStorage.errors;
    var $notice = $("#ruleeditor .notice.form-fill-errors");
    var tableTrs = [];
    var fullMsg = false;
    errors.forEach(function (error) {
      Logger.info("[options.js] Got error " + JSONF.stringify(error) + " for rule " + JSONF.stringify(rule));
      if(typeof error.fullMessage !== "undefined") {
        // One line output
        tableTrs.push("
" + error.fullMessage + "
");
        fullMsg = true;
      } else {
        // Typically an error in a rule
        tableTrs.push("
" + error.selector + "	" + error.value + "	" + error.message + "
");
      }
    });
    $notice.find("table").append(tableTrs.join("\n"));
    if(fullMsg) {
      $notice.find("#form-filling-errors-thead").remove();
    }
    $notice.find(".rule-name").html(rule.nameClean);
    $notice.find(".rule-url").html(rule.urlClean);
    $notice.show();
    Storage.delete(Utils.keys.errors);

    // Activate the tab with the rule
    var match = rule.id.match(/^([0-9]+)/);
    if(match) {
      Logger.info("[options.js] Activating tab #" + match[1]);
      $(".tab[data-tab-id='" + match[1] + "']").trigger("click");
    }
  }
});

// Read all rules to update stats
// Also fill quickjump select
var updateTabStats = function() {
  Rules.all().then(function (rules) {
    var rulesStats = { tabCount: {}, rules: []};

    rules.forEach(function (rule) {
      // Count rules
      if (typeof rulesStats.tabCount[rule.tabId] === "undefined") {
        rulesStats.tabCount[rule.tabId] = 0;
      }
      rulesStats.tabCount[rule.tabId] += 1;
      rulesStats.rules.push({
        name: rule.nameClean,
        id: rule.id
      });
    });

    // rulesStats has now a count of all rules per tab
    Object.keys(rulesStats.tabCount).forEach(function (key) {
      $(".tab[data-tab-id='" + key + "'] .rule-count").html("(" + rulesStats.tabCount[key] + ")");
    });

    // Fill <select> rules overview
    var options = ["<option value=''>- quickjump to rule -</option>"];

    // Remove rules without names (eg. libs)
    var onlyRealRules = rulesStats.rules.filter(function (rule) {
       return typeof rule.name != "undefined";
    });

    // Create <option> tags for sorted list of rules and insert into DOM
    Utils.sortRules(onlyRealRules).forEach(function (rule) {
      options.push("<option value='" + rule.id + "'>" + rule.name + "</option>");
    });
    $("#rules-overview").html(options.join(""));
  });
};

// Save the rules
var saveRules = function(tabId) {
  var errors = Rules.syntaxCheck(editor);
  if(errors.length > 0) {
    errors.forEach(function (errorClass) {
      $("#ruleeditor .notice." + errorClass).show();
    });
    noticesVisible = true;
  }

  if(editor.cleanUp()) {
    Rules.save(editor.getValue(), tabId).then(function () {
      Utils.infoMsg("Rules saved");
      updateTabStats();
    });
  }
};

// Load the rules
var loadRules = function(tabId) {
  Storage.load(Utils.keys.rules + "-tab-" + tabId).then(function (ruleData) {
    var ruleJson = null;
    if(typeof ruleData === "undefined" || typeof ruleData.code === "undefined") {
      ruleJson = "";
    } else {
      ruleJson = ruleData.code;
    }
    editor.setValue(ruleJson, -1);
    Utils.infoMsg("Rules loaded from disc");
  });
};

// import rules from disc
var importRules = function() {
  $("#modalimportrules").show();
};

var quickJumpToRule = function() {
  var selected = $(this).find("option:selected");
  var tabId = selected.val().split("-")[0];
  var name = selected.text();

  // If the target tab is not the active one, click to trigger
  if(currentTabId().toString() !== tabId) {
    $("#ruleeditor .tab[data-tab-id=" + tabId + "]").trigger("click");
  }

  var found = editor.editor().find(name, { backwards: false, skipCurrent: false }, false);
  editor.editor().gotoLine(found.start.row, 1, false);
};

// Load data from tab and prefill editor
loadRules(currentTabId());
updateTabStats();
editor.resize();

// Button handling for "save" and "load"
$(".editor .menu").on("click", "button.save", function () {
  saveRules(currentTabId());
}).on("click", "button.reload", function () {
  loadRules(currentTabId());
}).on("click", "button.format", function () {
  editor.format(Rules);
  Utils.infoMsg("Rules formatted but not saved");
});

// Show modal import window
$(document).on("click", "button.import, .rl-button-import", importRules);

// Export all rules (for modal import dialog)
$(document).on("click", "button.export, a.cmd-export-all-rules, button.rl-button-export", exportRules);

// Support for the quickjump <select>
$("#rules-overview").on("change", quickJumpToRule);

// Event handler for notices
$(".notice.form-fill-errors").on("click", function () {
  Storage.delete(Utils.keys.errors);
  $(this).hide();
});

$(".notice.extracted-present").on("click", function () {
  Storage.delete(Utils.keys.extractedRule);
  $(this).hide();
});

$(".notice.annotations-present, .notice.error").on("click", function () {
  $(this).hide();
});

<|endoftext|>


<commit_before>// @flow
import styled from "styled-components";
import { withLayout } from "./LayoutProvider";
import { breakpoint } from "../utils";
import { applyStyle } from '../utils/styles';

const compute = name =>
  breakpoint(name, (props, name) =>
    ((divisions, size: string, shift: string, gutter) =>
      `
      ${applyStyle(size, [`width: ${size}`])};
      ${applyStyle(shift, [`margin-left: ${shift}`])};
    `)(props.divisions, props[name], props[`${name}Shift`]));

const Box = styled.div`
  box-sizing: border-box;
  display: ${props => props.noFlex ? "block" : "flex"};
  flex-direction: column;
  overflow: scroll;
  ${props => applyStyle(props.flex, [`flex: ${props.flex}`])};
  ${props => applyStyle(props.debug && props.debug.enabled, ['background: rgba(0, 0, 100, .15)', 'outline: 1px solid #fff'])};
  ${props => applyStyle(props.grow, [`flex-grow: ${props.grow === true ? "1" : props.grow}`])};
  ${props => applyStyle(props.gutter && !props.fluid, [`padding: ${props.gutter}px ${props.gutter / 2}px`])};
  ${compute("xs")}
  ${compute("sm")}
  ${compute("md")}
  ${compute("lg")}
`;

export default withLayout(Box);
<commit_msg>add overflow: auto to Box<commit_after>// @flow
import styled from "styled-components";
import { withLayout } from "./LayoutProvider";
import { breakpoint } from "../utils";
import { applyStyle } from '../utils/styles';

const compute = name =>
  breakpoint(name, (props, name) =>
    ((divisions, size: string, shift: string, gutter) =>
      `
      ${applyStyle(size, [`width: ${size}`])};
      ${applyStyle(shift, [`margin-left: ${shift}`])};
    `)(props.divisions, props[name], props[`${name}Shift`]));

const Box = styled.div`
  box-sizing: border-box;
  display: ${props => props.noFlex ? "block" : "flex"};
  flex-direction: column;
  overflow: auto;
  ${props => applyStyle(props.flex, [`flex: ${props.flex}`])};
  ${props => applyStyle(props.debug && props.debug.enabled, ['background: rgba(0, 0, 100, .15)', 'outline: 1px solid #fff'])};
  ${props => applyStyle(props.grow, [`flex-grow: ${props.grow === true ? "1" : props.grow}`])};
  ${props => applyStyle(props.gutter && !props.fluid, [`padding: ${props.gutter}px ${props.gutter / 2}px`])};
  ${compute("xs")}
  ${compute("sm")}
  ${compute("md")}
  ${compute("lg")}
`;

export default withLayout(Box);
<|endoftext|>


<commit_before>var Message = require('../models/message');

exports.create = function(req, res) {
  new Message({
    senderID: req.body.senderID,
    senderAlias: req.body.senderAlias,
    acceptorID: req.body.acceptorID,
    acceptorAlias: req.body.acceptorAlias,
    subject: req.body.subject,
    content: req.body.content
  }).save(function(err, message) {
    if (err) {
        return res.send(400, err);
    }
    res.send(message);
  });
};

exports.list = function(req, res) {
  Message.find({}, function(err, messages) {
    if (err) {
      res.send(500, err);
    }
    res.send(messages || []);
  });
};

exports.remove = function(req, res) {
  // TODO: That's a security flaw, we should also include checks if that is a mesage of the user!!!
    var delFlag = false;
    var saveFlag = false;

    Message.findOne({_id: req.params.id}, function(err, doc){

        if(doc.senderID == req.user._id){
            if(doc.delFromAcceptor == 'true'){
                delFlag=true;
            }else{
                doc.delFromSender = true;
                saveFlag = true;
            }
        }
        if(doc.acceptorID == req.user._id){
            if(doc.delFromSender == 'true'){
                delFlag = true;
            }else{
                doc.delFromAcceptor = true;
                saveFlag = true;
            }
        }
        if(saveFlag){
            doc.save(function(err, doc){
                err ? res.send(500, err) : res.send('');
            })
        }
        if(delFlag){
            doc.remove(function(err, doc) {
                err ? res.send(500, err) : res.send('');
            });
        }

    });
};
<commit_msg>is done due to the following check<commit_after>var Message = require('../models/message');

exports.create = function(req, res) {
  new Message({
    senderID: req.body.senderID,
    senderAlias: req.body.senderAlias,
    acceptorID: req.body.acceptorID,
    acceptorAlias: req.body.acceptorAlias,
    subject: req.body.subject,
    content: req.body.content
  }).save(function(err, message) {
    if (err) {
        return res.send(400, err);
    }
    res.send(message);
  });
};

exports.list = function(req, res) {
  Message.find({}, function(err, messages) {
    if (err) {
      res.send(500, err);
    }
    res.send(messages || []);
  });
};

exports.remove = function(req, res) {
    var delFlag = false;
    var saveFlag = false;

    Message.findOne({_id: req.params.id}, function(err, doc){

        if(doc.senderID == req.user._id){
            if(doc.delFromAcceptor == 'true'){
                delFlag=true;
            }else{
                doc.delFromSender = true;
                saveFlag = true;
            }
        }
        if(doc.acceptorID == req.user._id){
            if(doc.delFromSender == 'true'){
                delFlag = true;
            }else{
                doc.delFromAcceptor = true;
                saveFlag = true;
            }
        }
        if(saveFlag){
            doc.save(function(err, doc){
                err ? res.send(500, err) : res.send('');
            })
        }
        if(delFlag){
            doc.remove(function(err, doc) {
                err ? res.send(500, err) : res.send('');
            });
        }

    });
};
<|endoftext|>


<commit_before>/**
 * LICENSE WILL BE PUT AT HERE
 */
/**
 * 1.1.1 = 1*100*100 + 1*100 + 1
 * 1.2.2 = 1*100*100 + 2*100 + 3
 *
 * 1 = 0*100 +1
 */
function encode_id_with_array(opts, arr) {
	var result = 0;
	for(var z = 0; z < arr.length; z++ ) {
		result += factor(opts, arr.length - z, arr[z]);
	}

	return result;
}

/**
 * 1.1.1 = 1*100*100 + 1*100 + 1
 * 1.2.2 = 1*100*100 + 2*100 + 3
 *
 * 1 = 0*100 +1

	1,1 = 100

 */
function get_parent_id_with_array(opts, arr) {
	var result_arr = [];
	for(var z = 0; z < arr.length; z++ ) {
		result_arr.push(arr[z]);
	}

	var result;
	do {
		result_arr.pop();
		result=0;

		for(var z = 0; z < result_arr.length; z++ ) {
			result += factor(opts, result_arr.length - z, result_arr[z]);
		}
	} while(!hasNode(opts, result) && result_arr.length);
	//确认计算出的父节点id是否真的存在,若不存在向上追溯

	return result;
}

//确认id的节点是否存在 (对于不规则章节的部分处理, 例如直接从h2开始写)
function hasNode(opts, id){
	var arr = opts._header_nodes;
	for(var i = 0; i < arr.length; i++){
		if(arr[i].id == id)return true;
	}
	return false;
}

function factor(opts, count, current) {
	if(1 == count) {
		return current * 1;
	}

	//原来这里存在逻辑bug, 只是轻轻的改了一下
	//不过这里直接改用 数值计算 比 字符串拼接eval更好吧.
	var str = current;
	for(var i = count - 1;i > 0; i-- ) {
		str *= opts.step;
	}

	return str + 1;
}

;(function($) {
	/*
	 * 根据header创建目录内容
	 */
	function create_toc(opts) {
		$(opts.documment_selector).find(':header').each(function() {
			var level = parseInt(this.nodeName.substring(1), 10);

			_rename_header_content(opts,this,level);
			//if(opts.debug) console.log(this);
			//if(opts.debug) console.log('headers:'+opts._headers);
			_add_header_node(opts,$(this));
		});//end each
	}

	/*
	 * 渲染ztree
	 */
	function render_with_ztree(opts) {
		var t = $(opts._zTree);
		t = $.fn.zTree.init(t,opts.ztreeSetting,opts._header_nodes).expandAll(opts.is_expand_all);
		// alert(opts._headers * 88);
		// $(opts._zTree).height(opts._headers * 33 + 33);

		if(opts.is_posion_top == true){
			opts.ztreeStyle.top = '0px';

			if( opts.ztreeStyle.hasOwnProperty('bottom') )
				delete opts.ztreeStyle.bottom ;
		}else{
			opts.ztreeStyle.bottom = '0px';

			if( opts.ztreeStyle.hasOwnProperty('top') )
				delete opts.ztreeStyle.top;
		}

		$(opts._zTree).css(opts.ztreeStyle);
	}

	/*
	 * 将已有header编号，并重命名
	 */
	function _rename_header_content(opts ,header_obj ,level) {
		//_headrs[] 存储各级标题的序号, 然后连成 1.1.2  形式
		if(opts._headers.length == level) {
			opts._headers[level - 1]++;
		} else if(opts._headers.length > level) {
			opts._headers = opts._headers.slice(0, level);
			opts._headers[level - 1] ++;
		} else if(opts._headers.length < level) {
			while(opts._headers.length < level){
				//if(opts.debug) console.log('push 1');
				opts._headers.push(1);
			}
		}

		if(opts.is_auto_number == true) {
			//另存为的文件里会有编号，所以有编号的就不再重新替换
			if($(header_obj).text().indexOf( opts._headers.join('.') ) != -1){

			}else{
				$(header_obj).html(opts._headers.join('.') + '. ' + $(header_obj).html());
			}
		}
	}

	/*
	 * create table with head for anchor for example:
Linux基础

	 * this method can get a headable anchor
	 * add by https://github.com/chanble
	 */
	function _get_anchor_from_head(header_obj){
		var name = header_obj.html();
		var aname = name.split('.');
		var anchor = aname.pop().trim();
		return anchor;
	}

	/*
	 * 给ztree用的header_nodes增加数据
	 */
	function _add_header_node(opts, header_obj) {
		var id	= $(header_obj).attr('id');
		if (id != null)
			encode_id_with_array(opts,opts._headers);//for ztree
		var pid = get_parent_id_with_array(opts,opts._headers);//for ztree
		var anchor = id;//use_head_anchor.html#第二部分

		// 默认使用标题作为anchor
		if(opts.use_head_anchor == true){
			anchor = _get_anchor_from_head(header_obj);
		}

		// 设置锚点id
		$(header_obj).attr('id',anchor);

		log($(header_obj).text());

		opts._header_offsets.push($(header_obj).offset().top - opts.highlight_offset);

		log('h offset ='+( $(header_obj).offset().top - opts.highlight_offset ) );

		opts._header_nodes.push({
			id:id,
			pId:pid ,
			name:$(header_obj).text()||'null',//显示名称
			open:true,//默认展开的 树节点
			url:'#'+ anchor,
			target:'_self'
		});
	}

	/*
	 * 计算章节的 offset
	 * 在需要的时机再自行调用,以重算 章节偏移.
	 * 例如 图片资源加载完时, 代码段 折叠展开时 等改变章节偏移的事件发生后.
	 */
	function recalc_offset(opts){
		var old_offsets=opts._header_offsets.slice(0);
		var new_offsets=[];

		$(opts.documment_selector).find(':header').each(function(i,o) {
			new_offsets.push($(o).offset().top - opts.highlight_offset);
		});

		var isWork=old_offsets.join(',') != new_offsets.join(',');
		if(opts.debug) console.log('recalc_offset is work:', isWork );
		if(isWork){
			if(opts.debug) console.log(old_offsets);
			if(opts.debug) console.log(new_offsets);
		}

		opts._header_offsets=new_offsets;
	}

	/*
	 * 根据滚动确定当前位置，并更新ztree
	 */
	function bind_scroll_event_and_update_postion(opts) {
		var timeout;
		var old_i=0;
		var highlight_on_scroll = function(e) {
			if (timeout) {
				clearTimeout(timeout);
			}

			timeout = setTimeout(function() {
				var top = $(opts.scroll_selector).scrollTop();

				if(opts.debug) console.log('top='+top);

				var i,c = opts._header_offsets.length;
				for (i = 0 ; i < c; i++) {
					// fixed: top+5防止点击ztree的时候，出现向上抖动的情况
					if (opts._header_offsets[i] >= (top + 5) ) {
						if(opts.debug)console.log('opts._header_offsets['+ i +'] = '+opts._header_offsets[i]);

						break;
					}
				}
				//这里原来出现逻辑bug,导致最后一个标题滚不到
				//顺便加了变量缓存当前章节,避免页面一滚动就操作页面dom(只在章节改变时才操作)
				if(i!=old_i){
					old_i=i;
					$('a').removeClass('curSelectedNode');
					// 由于有root节点，所以i应该从1开始
					var obj = $('#tree_' + (i+1) + '_a').addClass('curSelectedNode');
				}

			}, opts.refresh_scroll_time);
		};

		if (opts.highlight_on_scroll) {
			$(opts.scroll_selector).bind('scroll', highlight_on_scroll);
			highlight_on_scroll();
		}
		$(window).bind('load',function(){recalc_offset(opts)});
	}

	/*
	 * 初始化
	 */
	function init_with_config(opts) {
		opts.highlight_offset = $(opts.documment_selector).offset().top;
	}

	/*
	 * 日志
	 */
	function log(str) {
		return;
		if($.fn.ztree_toc.defaults.debug == true) {
			console.log(str);
		}
	}

	$.fn.ztree_toc = function(options) {

		// 将defaults 和 options 参数合并到{}
		var opts = $.extend({},$.fn.ztree_toc.defaults,options);
		opts.debug = opts.debug & (!!(console && console.log));
		window._opts=opts;

		return this.each(function() {
			opts._zTree = $(this);

			// 初始化
			init_with_config(opts);

			// 创建table of content，获取元数据_headers
			create_toc(opts);

			// 根据_headers生成ztree
			render_with_ztree(opts);

			// 根据滚动确定当前位置，并更新ztree
			bind_scroll_event_and_update_postion(opts);
		});
		// each end
	}

	//定义默认
	$.fn.ztree_toc.defaults = {
		_zTree: null,
		_headers: [],
		_header_offsets: [],
		_header_nodes: [{ id:1, pId:0, name:"Table of Content",open:true}],
		debug: true,
		/*
		 * 使用标题作为anchor
		 * create table with head for anchor for example:
Linux基础

		 * 如果标题是唯一的，建议开启此选项，如果标题不唯一，还是使用数字吧
		 * 此选项默认是false，不开启
		 */
		use_head_anchor: false,
		scroll_selector: window,//在chrome上 $('window') 为空
		highlight_offset: 0,
		highlight_on_scroll: true,
		/*
		 * 计算滚动判断当前位置的时间，默认是50毫秒
		 */
		refresh_scroll_time: 50,
		documment_selector: 'body',
		/*
		 * ztree的位置，默认是在上部
		 */
		is_posion_top: true,
		/*
		 * 默认是否显示header编号
		 */
		is_auto_number: false,
		/*
		 * 默认是否展开全部
		 */
		is_expand_all: true,
		/*
		 * 是否对选中行，显示高亮效果
		 */
		is_highlight_selected_line: true,
		step: 100,
		ztreeStyle: {
			width:'260px',
			overflow: 'auto',
			position: 'fixed',
			'z-index': 2147483647,
			border: '0px none',
			left: '0px',
			bottom: '0px',
			// height:'100px'
		},
		ztreeSetting: {
			view: {
				dblClickExpand: false,
				showLine: true,
				showIcon: false,
				selectedMulti: false
			},
			data: {
				simpleData: {
					enable: true,
					idKey : "id",
					pIdKey: "pId",
					// rootPId: "0"
				}
			},
			callback: {
				beforeClick: function(treeId, treeNode) {
					$('a').removeClass('curSelectedNode');
					if(treeNode.id == 1){
						// TODO: when click root node
						console.log('click root table of content');
					}
					if($.fn.ztree_toc.defaults.is_highlight_selected_line == true) {
						$('#' + treeNode.id).css('color' ,'red').fadeOut("slow" ,function() {
							// Animation complete.
							$(this).show().css('color','black');
						});
					}
				},
				onRightClick: function(event, treeId, treeNode) {
					if(treeNode.id == 1){
						// TODO: when right_click root node:table content
						console.log('right_click root table of content');
					}
				}
			}
		}
	};

})(jQuery);
<commit_msg>fix for test 修复不能通过测试的问题<commit_after>/**
 * LICENSE WILL BE PUT AT HERE
 */
/**
 * 1.1.1 = 1*100*100 + 1*100 + 1
 * 1.2.2 = 1*100*100 + 2*100 + 3
 *
 * 1 = 0*100 +1
 */
function encode_id_with_array(opts, arr) {
	var result = 0;
	for(var z = 0; z < arr.length; z++ ) {
		result += factor(opts, arr.length - z, arr[z]);
	}

	return result;
}

/**
 * 1.1.1 = 1*100*100 + 1*100 + 1
 * 1.2.2 = 1*100*100 + 2*100 + 3
 *
 * 1 = 0*100 +1

	1,1 = 100

 */
function get_parent_id_with_array(opts, arr) {
	var result_arr = [];
	for(var z = 0; z < arr.length; z++ ) {
		result_arr.push(arr[z]);
	}

	var result;
	do {
		result_arr.pop();
		result=0;

		for(var z = 0; z < result_arr.length; z++ ) {
			result += factor(opts, result_arr.length - z, result_arr[z]);
		}
	} while(!hasNode(opts, result) && result_arr.length > 0);
	//确认计算出的父节点id是否真的存在,若不存在向上追溯

	return result;
}

//确认id的节点是否存在 (对于不规则章节的部分处理, 例如直接从h2开始写)
function hasNode(opts, id){
	var arr = opts._header_nodes;
	if (!arr) return true;
	for(var i = 0; i < arr.length; i++){
		if(arr[i].id == id)return true;
	}
	return false;
}

function factor(opts, count, current) {
	if(1 == count) {
		return current * 1;
	}

	//原来这里存在逻辑bug, 只是轻轻的改了一下
	//不过这里直接改用 数值计算 比 字符串拼接eval更好吧.
	var str = current * 1;
	for(var i = count - 1;i > 0; i-- ) {
		str *= opts.step;
	}

	return str;
}

;(function($) {
	/*
	 * 根据header创建目录内容
	 */
	function create_toc(opts) {
		$(opts.documment_selector).find(':header').each(function() {
			var level = parseInt(this.nodeName.substring(1), 10);

			_rename_header_content(opts,this,level);
			//if(opts.debug) console.log(this);
			//if(opts.debug) console.log('headers:'+opts._headers);
			_add_header_node(opts,$(this));
		});//end each
	}

	/*
	 * 渲染ztree
	 */
	function render_with_ztree(opts) {
		var t = $(opts._zTree);
		t = $.fn.zTree.init(t,opts.ztreeSetting,opts._header_nodes).expandAll(opts.is_expand_all);
		// alert(opts._headers * 88);
		// $(opts._zTree).height(opts._headers * 33 + 33);

		if(opts.is_posion_top == true){
			opts.ztreeStyle.top = '0px';

			if( opts.ztreeStyle.hasOwnProperty('bottom') )
				delete opts.ztreeStyle.bottom ;
		}else{
			opts.ztreeStyle.bottom = '0px';

			if( opts.ztreeStyle.hasOwnProperty('top') )
				delete opts.ztreeStyle.top;
		}

		$(opts._zTree).css(opts.ztreeStyle);
	}

	/*
	 * 将已有header编号，并重命名
	 */
	function _rename_header_content(opts ,header_obj ,level) {
		//_headrs[] 存储各级标题的序号, 然后连成 1.1.2  形式
		if(opts._headers.length == level) {
			opts._headers[level - 1]++;
		} else if(opts._headers.length > level) {
			opts._headers = opts._headers.slice(0, level);
			opts._headers[level - 1] ++;
		} else if(opts._headers.length < level) {
			while(opts._headers.length < level){
				//if(opts.debug) console.log('push 1');
				opts._headers.push(1);
			}
		}

		if(opts.is_auto_number == true) {
			//另存为的文件里会有编号，所以有编号的就不再重新替换
			if($(header_obj).text().indexOf( opts._headers.join('.') ) != -1){

			}else{
				$(header_obj).html(opts._headers.join('.') + '. ' + $(header_obj).html());
			}
		}
	}

	/*
	 * create table with head for anchor for example:
Linux基础

	 * this method can get a headable anchor
	 * add by https://github.com/chanble
	 */
	function _get_anchor_from_head(header_obj){
		var name = header_obj.html();
		var aname = name.split('.');
		var anchor = aname.pop().trim();
		return anchor;
	}

	/*
	 * 给ztree用的header_nodes增加数据
	 */
	function _add_header_node(opts, header_obj) {
		var id	= $(header_obj).attr('id');
		if (id != null)
			encode_id_with_array(opts,opts._headers);//for ztree
		var pid = get_parent_id_with_array(opts,opts._headers);//for ztree
		var anchor = id;//use_head_anchor.html#第二部分

		// 默认使用标题作为anchor
		if(opts.use_head_anchor == true){
			anchor = _get_anchor_from_head(header_obj);
		}

		// 设置锚点id
		$(header_obj).attr('id',anchor);

		log($(header_obj).text());

		opts._header_offsets.push($(header_obj).offset().top - opts.highlight_offset);

		log('h offset ='+( $(header_obj).offset().top - opts.highlight_offset ) );

		opts._header_nodes.push({
			id:id,
			pId:pid ,
			name:$(header_obj).text()||'null',//显示名称
			open:true,//默认展开的 树节点
			url:'#'+ anchor,
			target:'_self'
		});
	}

	/*
	 * 计算章节的 offset
	 * 在需要的时机再自行调用,以重算 章节偏移.
	 * 例如 图片资源加载完时, 代码段 折叠展开时 等改变章节偏移的事件发生后.
	 */
	function recalc_offset(opts){
		var old_offsets=opts._header_offsets.slice(0);
		var new_offsets=[];

		$(opts.documment_selector).find(':header').each(function(i,o) {
			new_offsets.push($(o).offset().top - opts.highlight_offset);
		});

		var isWork=old_offsets.join(',') != new_offsets.join(',');
		if(opts.debug) console.log('recalc_offset is work:', isWork );
		if(isWork){
			if(opts.debug) console.log(old_offsets);
			if(opts.debug) console.log(new_offsets);
		}

		opts._header_offsets=new_offsets;
	}

	/*
	 * 根据滚动确定当前位置，并更新ztree
	 */
	function bind_scroll_event_and_update_postion(opts) {
		var timeout;
		var old_i=0;
		var highlight_on_scroll = function(e) {
			if (timeout) {
				clearTimeout(timeout);
			}

			timeout = setTimeout(function() {
				var top = $(opts.scroll_selector).scrollTop();

				if(opts.debug) console.log('top='+top);

				var i,c = opts._header_offsets.length;
				for (i = 0 ; i < c; i++) {
					// fixed: top+5防止点击ztree的时候，出现向上抖动的情况
					if (opts._header_offsets[i] >= (top + 5) ) {
						if(opts.debug)console.log('opts._header_offsets['+ i +'] = '+opts._header_offsets[i]);

						break;
					}
				}
				//这里原来出现逻辑bug,导致最后一个标题滚不到
				//顺便加了变量缓存当前章节,避免页面一滚动就操作页面dom(只在章节改变时才操作)
				if(i!=old_i){
					old_i=i;
					$('a').removeClass('curSelectedNode');
					// 由于有root节点，所以i应该从1开始
					var obj = $('#tree_' + (i+1) + '_a').addClass('curSelectedNode');
				}

			}, opts.refresh_scroll_time);
		};

		if (opts.highlight_on_scroll) {
			$(opts.scroll_selector).bind('scroll', highlight_on_scroll);
			highlight_on_scroll();
		}
		$(window).bind('load',function(){recalc_offset(opts)});
	}

	/*
	 * 初始化
	 */
	function init_with_config(opts) {
		opts.highlight_offset = $(opts.documment_selector).offset().top;
	}

	/*
	 * 日志
	 */
	function log(str) {
		return;
		if($.fn.ztree_toc.defaults.debug == true) {
			console.log(str);
		}
	}

	$.fn.ztree_toc = function(options) {

		// 将defaults 和 options 参数合并到{}
		var opts = $.extend({},$.fn.ztree_toc.defaults,options);
		opts.debug = opts.debug & (!!(console && console.log));
		window._opts=opts;

		return this.each(function() {
			opts._zTree = $(this);

			// 初始化
			init_with_config(opts);

			// 创建table of content，获取元数据_headers
			create_toc(opts);

			// 根据_headers生成ztree
			render_with_ztree(opts);

			// 根据滚动确定当前位置，并更新ztree
			bind_scroll_event_and_update_postion(opts);
		});
		// each end
	}

	//定义默认
	$.fn.ztree_toc.defaults = {
		_zTree: null,
		_headers: [],
		_header_offsets: [],
		_header_nodes: [{ id:1, pId:0, name:"Table of Content",open:true}],
		debug: true,
		/*
		 * 使用标题作为anchor
		 * create table with head for anchor for example:
Linux基础

		 * 如果标题是唯一的，建议开启此选项，如果标题不唯一，还是使用数字吧
		 * 此选项默认是false，不开启
		 */
		use_head_anchor: false,
		scroll_selector: window,//在chrome上 $('window') 为空
		highlight_offset: 0,
		highlight_on_scroll: true,
		/*
		 * 计算滚动判断当前位置的时间，默认是50毫秒
		 */
		refresh_scroll_time: 50,
		documment_selector: 'body',
		/*
		 * ztree的位置，默认是在上部
		 */
		is_posion_top: true,
		/*
		 * 默认是否显示header编号
		 */
		is_auto_number: false,
		/*
		 * 默认是否展开全部
		 */
		is_expand_all: true,
		/*
		 * 是否对选中行，显示高亮效果
		 */
		is_highlight_selected_line: true,
		step: 100,
		ztreeStyle: {
			width:'260px',
			overflow: 'auto',
			position: 'fixed',
			'z-index': 2147483647,
			border: '0px none',
			left: '0px',
			bottom: '0px',
			// height:'100px'
		},
		ztreeSetting: {
			view: {
				dblClickExpand: false,
				showLine: true,
				showIcon: false,
				selectedMulti: false
			},
			data: {
				simpleData: {
					enable: true,
					idKey : "id",
					pIdKey: "pId",
					// rootPId: "0"
				}
			},
			callback: {
				beforeClick: function(treeId, treeNode) {
					$('a').removeClass('curSelectedNode');
					if(treeNode.id == 1){
						// TODO: when click root node
						console.log('click root table of content');
					}
					if($.fn.ztree_toc.defaults.is_highlight_selected_line == true) {
						$('#' + treeNode.id).css('color' ,'red').fadeOut("slow" ,function() {
							// Animation complete.
							$(this).show().css('color','black');
						});
					}
				},
				onRightClick: function(event, treeId, treeNode) {
					if(treeNode.id == 1){
						// TODO: when right_click root node:table content
						console.log('right_click root table of content');
					}
				}
			}
		}
	};

})(jQuery);
<|endoftext|>