<commit_before>/**
 * @file MaterialDropdownSelect component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import DropdownSelect from '../DropdownSelect';
import MaterialProvider from '../MaterialProvider';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import SelectMode from '../_statics/SelectMode';

class MaterialDropdownSelect extends Component {

    static SelectMode = SelectMode;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: props.value,
            isFocus: false
        };

        this.triggerChangeHandler = ::this.triggerChangeHandler;
        this.closePopup = ::this.closePopup;

    }

    triggerChangeHandler(value) {
        this.setState({
            value
        }, () => {
            const {onChange} = this.props;
            onChange && onChange(value);
        });
    }

    closePopup() {
        this.refs.dropdownSelect && this.refs.dropdownSelect.closePopup();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value !== this.state.value) {
            this.setState({
                value: nextProps.value
            });
        }
    }

    render() {

        const {
                className, style, theme, label, isLabelAnimate, disabled, required, selectMode,
                ...restProps
            } = this.props,
            {value} = this.state,

            wrapperClassName = classNames('material-dropdown-select', {
                [className]: className
            });

        return (
            <MaterialProvider className={wrapperClassName}
                              style={style}
                              theme={theme}
                              label={label}
                              isLabelAnimate={isLabelAnimate}
                              hasValue={selectMode === SelectMode.MULTI_SELECT ? value && value.length > 0 : !!value}
                              disabled={disabled}
                              required={required}>
                <DropdownSelect {...restProps}
                                ref="dropdownSelect"
                                value={value}
                                selectMode={selectMode}
                                disabled={disabled}
                                onChange={this.triggerChangeHandler}/>
            </MaterialProvider>
        );

    }
};

MaterialDropdownSelect.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The class name of the popup element.
     */
    popupClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Override the styles of the popup element.
     */
    popupStyle: PropTypes.object,

    /**
     * The theme.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    /**
     * The name of the dropDownSelect.
     */
    name: PropTypes.string,

    /**
     * The label of the text field.
     */
    label: PropTypes.any,

    /**
     * The animate of the text field.
     */
    isLabelAnimate: PropTypes.bool,

    /**
     * The value of the dropDownSelect.
     */
    value: PropTypes.any,

    /**
     * The placeholder of the dropDownSelect.
     */
    placeholder: PropTypes.string,

    rightIconCls: PropTypes.string,

    /**
     * The options data.
     */
    data: PropTypes.oneOfType([

        // not grouped
        PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({

            /**
             * The CSS class name of the list button.
             */
            className: PropTypes.string,

            /**
             * Override the styles of the list button.
             */
            style: PropTypes.object,

            /**
             * The theme of the list button.
             */
            theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

            /**
             * The text value of the list button.Type can be string or number.
             */
            value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * The desc value of the list button. Type can be string or number.
             */
            desc: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * If true, the list button will be disabled.
             */
            disabled: PropTypes.bool,

            /**
             * If true,the button will be have loading effect.
             */
            isLoading: PropTypes.bool,

            /**
             * If true,the element's ripple effect will be disabled.
             */
            disableTouchRipple: PropTypes.bool,

            /**
             * Use this property to display an icon. It will display on the left.
             */
            iconCls: PropTypes.string,

            /**
             * Use this property to display an icon. It will display on the right.
             */
            rightIconCls: PropTypes.string,

            /**
             * You can create a complicated renderer callback instead of value and desc prop.
             */
            renderer: PropTypes.func,

            /**
             * Callback function fired when a list item touch-tapped.
             */
            onTouchTap: PropTypes.func

        }), PropTypes.string, PropTypes.number])),

        // grouped
        PropTypes.array

    ]).isRequired,

    /**
     * The invalid message of dropDownSelect.
     */
    invalidMsg: PropTypes.string,

    /**
     * If true,the dropDownSelect will be disabled.
     */
    disabled: PropTypes.bool,

    /**
     * The mode of listItem.Can be normal,checkbox.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The value field name in data. (default: "value")
     */
    valueField: PropTypes.string,

    /**
     * The display field name in data. (default: "text")
     */
    displayField: PropTypes.string,

    /**
     * The description field name in data. (default: "desc")
     */
    descriptionField: PropTypes.string,

    /**
     * The message of the dropDownSelect.
     */
    infoMsg: PropTypes.string,

    /**
     * Use this function to format the options's text.
     */
    textFormat: PropTypes.func,

    /**
     * If true,the drop-down box automatically closed after selection.
     */
    autoClose: PropTypes.bool,

    /**
     * If true,the drop-down box will have search input.
     */
    useFilter: PropTypes.bool,

    useSelectAll: PropTypes.bool,

    /**
     * The message of no matching option.
     */
    noMatchedMsg: PropTypes.string,

    /**
     * If true,the drop-down box will be have group selection.
     */
    isGrouped: PropTypes.bool,

    required: PropTypes.bool,

    shouldPreventContainerScroll: PropTypes.bool,

    /**
     * Callback function fired when the button is touch-tapped.
     */
    onItemTouchTap: PropTypes.func,

    /**
     * Callback function fired when the popup is closed.
     */
    onClosePopup: PropTypes.func,

    /**
     * Callback function fired when a menu item is selected.
     */
    onChange: PropTypes.func,

    onWheel: PropTypes.func

};

MaterialDropdownSelect.defaultProps = {

    className: null,
    popupClassName: null,
    style: null,
    popupStyle: null,
    theme: Theme.DEFAULT,

    name: null,
    label: null,
    isLabelAnimate: true,
    value: null,
    placeholder: 'Please select ...',
    rightIconCls: 'fas fa-angle-down',
    data: [],
    invalidMsg: null,
    disabled: false,
    selectMode: SelectMode.SINGLE_SELECT,

    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',

    infoMsg: null,
    autoClose: true,
    useFilter: false,
    useSelectAll: false,
    noMatchedMsg: null,
    isGrouped: false,
    required: false,

    shouldPreventContainerScroll: true

};

export default MaterialDropdownSelect;<commit_msg>update MaterialDropdownSelect<commit_after>/**
 * @file MaterialDropdownSelect component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import DropdownSelect from '../DropdownSelect';
import MaterialProvider from '../MaterialProvider';
import Theme from '../Theme';

import Util from '../_vendors/Util';
import SelectMode from '../_statics/SelectMode';

class MaterialDropdownSelect extends Component {

    static SelectMode = SelectMode;
    static Theme = Theme;
    static Position = DropdownSelect.Position;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            value: props.value,
            isFocus: false
        };

        this.triggerChangeHandler = ::this.triggerChangeHandler;
        this.closePopup = ::this.closePopup;

    }

    triggerChangeHandler(value) {
        this.setState({
            value
        }, () => {
            const {onChange} = this.props;
            onChange && onChange(value);
        });
    }

    closePopup() {
        this.refs.dropdownSelect && this.refs.dropdownSelect.closePopup();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.value !== this.state.value) {
            this.setState({
                value: nextProps.value
            });
        }
    }

    render() {

        const {
                className, style, theme, label, isLabelAnimate, disabled, required, selectMode,
                ...restProps
            } = this.props,
            {value} = this.state,

            wrapperClassName = classNames('material-dropdown-select', {
                [className]: className
            });

        return (
            <MaterialProvider className={wrapperClassName}
                              style={style}
                              theme={theme}
                              label={label}
                              isLabelAnimate={isLabelAnimate}
                              hasValue={selectMode === SelectMode.MULTI_SELECT ? value && value.length > 0 : !!value}
                              disabled={disabled}
                              required={required}>
                <DropdownSelect {...restProps}
                                ref="dropdownSelect"
                                value={value}
                                selectMode={selectMode}
                                disabled={disabled}
                                onChange={this.triggerChangeHandler}/>
            </MaterialProvider>
        );

    }
};

MaterialDropdownSelect.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * The class name of the popup element.
     */
    popupClassName: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Override the styles of the popup element.
     */
    popupStyle: PropTypes.object,

    /**
     * The theme.
     */
    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    position: PropTypes.oneOf(Util.enumerateValue(DropdownSelect.Position)),

    /**
     * The name of the dropDownSelect.
     */
    name: PropTypes.string,

    /**
     * The label of the text field.
     */
    label: PropTypes.any,

    /**
     * The animate of the text field.
     */
    isLabelAnimate: PropTypes.bool,

    /**
     * The value of the dropDownSelect.
     */
    value: PropTypes.any,

    /**
     * The placeholder of the dropDownSelect.
     */
    placeholder: PropTypes.string,

    rightIconCls: PropTypes.string,

    /**
     * The options data.
     */
    data: PropTypes.oneOfType([

        // not grouped
        PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape({

            /**
             * The CSS class name of the list button.
             */
            className: PropTypes.string,

            /**
             * Override the styles of the list button.
             */
            style: PropTypes.object,

            /**
             * The theme of the list button.
             */
            theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

            /**
             * The text value of the list button.Type can be string or number.
             */
            value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * The desc value of the list button. Type can be string or number.
             */
            desc: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

            /**
             * If true, the list button will be disabled.
             */
            disabled: PropTypes.bool,

            /**
             * If true,the button will be have loading effect.
             */
            isLoading: PropTypes.bool,

            /**
             * If true,the element's ripple effect will be disabled.
             */
            disableTouchRipple: PropTypes.bool,

            /**
             * Use this property to display an icon. It will display on the left.
             */
            iconCls: PropTypes.string,

            /**
             * Use this property to display an icon. It will display on the right.
             */
            rightIconCls: PropTypes.string,

            /**
             * You can create a complicated renderer callback instead of value and desc prop.
             */
            renderer: PropTypes.func,

            /**
             * Callback function fired when a list item touch-tapped.
             */
            onTouchTap: PropTypes.func

        }), PropTypes.string, PropTypes.number])),

        // grouped
        PropTypes.array

    ]).isRequired,

    /**
     * The invalid message of dropDownSelect.
     */
    invalidMsg: PropTypes.string,

    /**
     * If true,the dropDownSelect will be disabled.
     */
    disabled: PropTypes.bool,

    /**
     * The mode of listItem.Can be normal,checkbox.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The value field name in data. (default: "value")
     */
    valueField: PropTypes.string,

    /**
     * The display field name in data. (default: "text")
     */
    displayField: PropTypes.string,

    /**
     * The description field name in data. (default: "desc")
     */
    descriptionField: PropTypes.string,

    /**
     * The message of the dropDownSelect.
     */
    infoMsg: PropTypes.string,

    /**
     * Use this function to format the options's text.
     */
    textFormat: PropTypes.func,

    /**
     * If true,the drop-down box automatically closed after selection.
     */
    autoClose: PropTypes.bool,

    /**
     * If true,the drop-down box will have search input.
     */
    useFilter: PropTypes.bool,

    useSelectAll: PropTypes.bool,

    /**
     * The message of no matching option.
     */
    noMatchedMsg: PropTypes.string,

    /**
     * If true,the drop-down box will be have group selection.
     */
    isGrouped: PropTypes.bool,

    required: PropTypes.bool,

    shouldPreventContainerScroll: PropTypes.bool,

    /**
     * Callback function fired when the button is touch-tapped.
     */
    onItemTouchTap: PropTypes.func,

    /**
     * Callback function fired when the popup is closed.
     */
    onClosePopup: PropTypes.func,

    /**
     * Callback function fired when a menu item is selected.
     */
    onChange: PropTypes.func,

    onWheel: PropTypes.func

};

MaterialDropdownSelect.defaultProps = {

    className: null,
    popupClassName: null,
    style: null,
    popupStyle: null,
    theme: Theme.DEFAULT,

    position: DropdownSelect.Position.LEFT,
    name: null,
    label: null,
    isLabelAnimate: true,
    value: null,
    placeholder: 'Please select ...',
    rightIconCls: 'fas fa-angle-down',
    data: [],
    invalidMsg: null,
    disabled: false,
    selectMode: SelectMode.SINGLE_SELECT,

    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',

    infoMsg: null,
    autoClose: true,
    useFilter: false,
    useSelectAll: false,
    noMatchedMsg: null,
    isGrouped: false,
    required: false,

    shouldPreventContainerScroll: true

};

export default MaterialDropdownSelect;<|endoftext|>


<commit_before>(function () {

  var button;

  var styles = [
    "http://localhost:8080/towtruck.css"
  ];

  // FIXME: these should all get combined for a production release:
  var scripts = [
    "http://localhost:8080/libs/jquery-1.8.3.min.js",
    "http://localhost:8080/libs/underscore-1.4.3.min.js",
    "http://localhost:8080/util.js",
    "http://localhost:8080/element-finder.js",
    "http://localhost:8080/channels.js",
    "http://localhost:8080/towtruck-runner.js",
    "http://localhost:8080/chat.js",
    "http://localhost:8080/tracker.js",
    "http://localhost:8080/libs/walkabout.js/walkabout.js"
    //"http://localhost:8080/libs/sharejs/src/client/microevent.js",
    //"http://localhost:8080/libs/sharejs/src/types/helpers.js",
    //"http://localhost:8080/libs/sharejs/src/client/textarea.js",
    //"http://localhost:8080/libs/sharejs/src/client/cm.js",
    //"http://localhost:8080/libs/sharejs/src/types/text.js",
    //"http://localhost:8080/libs/sharejs/src/types/text-api.js"
  ];

  var selfScript = "http://localhost:8080/towtruck.js";

  // FIXME: I think there's an event that would be called before load?
  window.addEventListener("load", function () {
    var control = document.getElementById("towtruck-starter");
    // FIXME: not sure where to put the control if the page doesn't have
    // a specific place in mind?
    if (! control) {
      return;
    }
    button = document.createElement("button");
    button.innerHTML = "Start TowTruck";
    button.addEventListener("click", startTowTruck, false);
    control.appendChild(button);
  }, false);

  function addStyle(url) {
    var link = document.createElement("link");
    link.setAttribute("rel", "stylesheet");
    // FIXME: remove cache buster:
    link.href = url + "?" + Date.now();
    document.head.appendChild(link);
  }

  function addScript(url) {
    var script = document.createElement("script");
    // FIXME: remove cache buster:
    script.src = url + "?" + Date.now();
    document.head.appendChild(script);
  }

  var startTowTruck = window.startTowTruck = function () {
    if (typeof TowTruck !== "undefined") {
      TowTruck.start();
      return;
    }
    // A sort of signal to towtruck-runner.js to tell it to actually
    // start itself (i.e., put up a UI and try to activate)
    if (! window._startTowTruckImmediately) {
      window._startTowTruckImmediately = true;
    }
    styles.forEach(addStyle);
    var callbacks = [];
    window._TowTruckOnLoad = function (callback) {
      callbacks.push(callback);
    };
    var start = window._TowTruck_notify_script = function (name) {
      var index = 0;
      if (name) {
        for (var i=0; i<scripts.length; i++) {
          if (scripts[i].replace(/.*\//, "") == name + ".js") {
            index = i + 1;
            break;
          }
        }
      }
      if (index >= scripts.length) {
        delete window._TowTruck_notify_script;
        callbacks.forEach(function (c) {
          c();
        });
        delete window._TowTruckOnLoad;
      } else {
        var tag = document.createElement("script");
        tag.src = scripts[index] + "?cache=" + Date.now();
        document.head.appendChild(tag);
      }
    };
    start();
  };

  startTowTruck.hubBase = "http://localhost:8080";

  startTowTruck.bookmarklet = function () {
    var s = "window._TowTruckBookmarklet = true;";
    s += "s=document.createElement('script');";
    s += "s.src=" + JSON.stringify(selfScript) + ";";
    s += "document.head.appendChild(s);";
    s = "(function () {" + s + "})();void(0)";
    return "javascript:" + encodeURIComponent(s);
  };

  function onload() {
    var hash = location.hash.replace(/^#/, "");
    if (hash.search(/&towtruck-/) === 0) {
      var shareId = hash.substr(hash.search(/&towtruck-/));
      shareId = shareId.substr(("&towtruck-").length);
      shareId = shareId.replace(/&.*/, "");
      window._startTowTruckImmediately = shareId;
      console.log("starting", shareId);
      startTowTruck();
    }
    if (window._TowTruckBookmarklet) {
      delete window._TowTruckBookmarklet;
      startTowTruck();
    }
  }

  if (document.readyState == "complete") {
    onload();
  } else {
    window.addEventListener("load", onload, false);
  }

})();
<commit_msg>properly initialize towtruck when startTowTruck() is called more than once in a single page session (i.e., after closing and restarting)<commit_after>(function () {

  var button;

  var styles = [
    "http://localhost:8080/towtruck.css"
  ];

  // FIXME: these should all get combined for a production release:
  var scripts = [
    "http://localhost:8080/libs/jquery-1.8.3.min.js",
    "http://localhost:8080/libs/underscore-1.4.3.min.js",
    "http://localhost:8080/util.js",
    "http://localhost:8080/element-finder.js",
    "http://localhost:8080/channels.js",
    "http://localhost:8080/towtruck-runner.js",
    "http://localhost:8080/chat.js",
    "http://localhost:8080/tracker.js",
    "http://localhost:8080/libs/walkabout.js/walkabout.js"
    //"http://localhost:8080/libs/sharejs/src/client/microevent.js",
    //"http://localhost:8080/libs/sharejs/src/types/helpers.js",
    //"http://localhost:8080/libs/sharejs/src/client/textarea.js",
    //"http://localhost:8080/libs/sharejs/src/client/cm.js",
    //"http://localhost:8080/libs/sharejs/src/types/text.js",
    //"http://localhost:8080/libs/sharejs/src/types/text-api.js"
  ];

  var selfScript = "http://localhost:8080/towtruck.js";

  // FIXME: I think there's an event that would be called before load?
  window.addEventListener("load", function () {
    var control = document.getElementById("towtruck-starter");
    // FIXME: not sure where to put the control if the page doesn't have
    // a specific place in mind?
    if (! control) {
      return;
    }
    button = document.createElement("button");
    button.innerHTML = "Start TowTruck";
    button.addEventListener("click", startTowTruck, false);
    control.appendChild(button);
  }, false);

  function addStyle(url) {
    var link = document.createElement("link");
    link.setAttribute("rel", "stylesheet");
    // FIXME: remove cache buster:
    link.href = url + "?" + Date.now();
    document.head.appendChild(link);
  }

  function addScript(url) {
    var script = document.createElement("script");
    // FIXME: remove cache buster:
    script.src = url + "?" + Date.now();
    document.head.appendChild(script);
  }

  var startTowTruck = window.startTowTruck = function () {
    if (typeof TowTruck !== "undefined") {
      TowTruck.isClient = false;
      TowTruck.init();
      TowTruck.start();
      return;
    }
    // A sort of signal to towtruck-runner.js to tell it to actually
    // start itself (i.e., put up a UI and try to activate)
    if (! window._startTowTruckImmediately) {
      window._startTowTruckImmediately = true;
    }
    styles.forEach(addStyle);
    var callbacks = [];
    window._TowTruckOnLoad = function (callback) {
      callbacks.push(callback);
    };
    var start = window._TowTruck_notify_script = function (name) {
      var index = 0;
      if (name) {
        for (var i=0; i<scripts.length; i++) {
          if (scripts[i].replace(/.*\//, "") == name + ".js") {
            index = i + 1;
            break;
          }
        }
      }
      if (index >= scripts.length) {
        delete window._TowTruck_notify_script;
        callbacks.forEach(function (c) {
          c();
        });
        delete window._TowTruckOnLoad;
      } else {
        var tag = document.createElement("script");
        tag.src = scripts[index] + "?cache=" + Date.now();
        document.head.appendChild(tag);
      }
    };
    start();
  };

  startTowTruck.hubBase = "http://localhost:8080";

  startTowTruck.bookmarklet = function () {
    var s = "window._TowTruckBookmarklet = true;";
    s += "s=document.createElement('script');";
    s += "s.src=" + JSON.stringify(selfScript) + ";";
    s += "document.head.appendChild(s);";
    s = "(function () {" + s + "})();void(0)";
    return "javascript:" + encodeURIComponent(s);
  };

  function onload() {
    var hash = location.hash.replace(/^#/, "");
    if (hash.search(/&towtruck-/) === 0) {
      var shareId = hash.substr(hash.search(/&towtruck-/));
      shareId = shareId.substr(("&towtruck-").length);
      shareId = shareId.replace(/&.*/, "");
      window._startTowTruckImmediately = shareId;
      console.log("starting", shareId);
      startTowTruck();
    }
    if (window._TowTruckBookmarklet) {
      delete window._TowTruckBookmarklet;
      startTowTruck();
    }
  }

  if (document.readyState == "complete") {
    onload();
  } else {
    window.addEventListener("load", onload, false);
  }

})();
<|endoftext|>


<commit_before>angular.module('angular-jwt.authManager', [])
  .provider('authManager', function () {

    this.$get = function ($rootScope, $injector, $location, jwtHelper, jwtInterceptor, jwtOptions) {

      var config = jwtOptions.getConfig();

      function invokeToken(tokenGetter) {
        var token = null;
        if (Array.isArray(tokenGetter)) {
          token = $injector.invoke(tokenGetter, this, {options: null});
        } else {
          token = tokenGetter();
        }
        return token;
      }

      function invokeRedirector(redirector) {
        if (Array.isArray(redirector) || angular.isFunction(redirector)) {
          return $injector.invoke(redirector, config, {});
        } else {
          throw new Error('unauthenticatedRedirector must be a function');
        }
      }

      function isAuthenticated() {
        var token = invokeToken(config.tokenGetter);
        if (token) {
          return !jwtHelper.isTokenExpired(token);
        }
      }

      $rootScope.isAuthenticated = false;

      function authenticate() {
        $rootScope.isAuthenticated = true;
      }

      function unauthenticate() {
        $rootScope.isAuthenticated = false;
      }

      function validateToken() {
        var token = invokeToken(config.tokenGetter);
        if (token) {
          if (!jwtHelper.isTokenExpired(token)) {
            authenticate();
          } else {
            $rootScope.$broadcast('tokenHasExpired', token);
          }
        }
      }

      function checkAuthOnRefresh() {
        if ($injector.has('$transitions')) {
          var $transitions = $injector.get('$transitions');
          $transitions.onStart({}, validateToken);
        } else {
          $rootScope.$on('$locationChangeStart', validateToken);
        }
      }

      function redirectWhenUnauthenticated() {
        $rootScope.$on('unauthenticated', function () {
          invokeRedirector(config.unauthenticatedRedirector);
          unauthenticate();
        });
      }

      function verifyRoute(event, next) {
        if (!next) {
          return false;
        }

        var routeData = (next.$$route) ? next.$$route : next.data;

        if (routeData && routeData.requiresLogin === true && !isAuthenticated()) {
          event.preventDefault();
          invokeRedirector(config.unauthenticatedRedirector);
        }
      }

      function verifyState(transition) {
        var route = transition.to();
          if (route && route.data && route.data.requiresLogin === true && !isAuthenticated()) {
            invokeRedirector(config.unauthenticatedRedirector);
            return false;
          }
      }

      if ($injector.has('$transitions')) {
        var $transitions = $injector.get('$transitions');
        $transitions.onStart({}, verifyState);
      } else {
        var eventName = ($injector.has('$state')) ? '$stateChangeStart' : '$routeChangeStart';
        $rootScope.$on(eventName, verifyRoute);
      }

      return {
        authenticate: authenticate,
        unauthenticate: unauthenticate,
        getToken: function(){ return invokeToken(config.tokenGetter); },
        redirect: function() { return invokeRedirector(config.unauthenticatedRedirector); },
        checkAuthOnRefresh: checkAuthOnRefresh,
        redirectWhenUnauthenticated: redirectWhenUnauthenticated,
        isAuthenticated: isAuthenticated
      }
    }
  });
<commit_msg>Make verify state return new target if redirect required<commit_after>angular.module('angular-jwt.authManager', [])
  .provider('authManager', function () {

    this.$get = function ($rootScope, $injector, $location, jwtHelper, jwtInterceptor, jwtOptions) {

      var config = jwtOptions.getConfig();

      function invokeToken(tokenGetter) {
        var token = null;
        if (Array.isArray(tokenGetter)) {
          token = $injector.invoke(tokenGetter, this, {options: null});
        } else {
          token = tokenGetter();
        }
        return token;
      }

      function invokeRedirector(redirector) {
        if (Array.isArray(redirector) || angular.isFunction(redirector)) {
          return $injector.invoke(redirector, config, {});
        } else {
          throw new Error('unauthenticatedRedirector must be a function');
        }
      }

      function isAuthenticated() {
        var token = invokeToken(config.tokenGetter);
        if (token) {
          return !jwtHelper.isTokenExpired(token);
        }
      }

      $rootScope.isAuthenticated = false;

      function authenticate() {
        $rootScope.isAuthenticated = true;
      }

      function unauthenticate() {
        $rootScope.isAuthenticated = false;
      }

      function validateToken() {
        var token = invokeToken(config.tokenGetter);
        if (token) {
          if (!jwtHelper.isTokenExpired(token)) {
            authenticate();
          } else {
            $rootScope.$broadcast('tokenHasExpired', token);
          }
        }
      }

      function checkAuthOnRefresh() {
        if ($injector.has('$transitions')) {
          var $transitions = $injector.get('$transitions');
          $transitions.onStart({}, validateToken);
        } else {
          $rootScope.$on('$locationChangeStart', validateToken);
        }
      }

      function redirectWhenUnauthenticated() {
        $rootScope.$on('unauthenticated', function () {
          invokeRedirector(config.unauthenticatedRedirector);
          unauthenticate();
        });
      }

      function verifyRoute(event, next) {
        if (!next) {
          return false;
        }

        var routeData = (next.$$route) ? next.$$route : next.data;

        if (routeData && routeData.requiresLogin === true && !isAuthenticated()) {
          event.preventDefault();
          invokeRedirector(config.unauthenticatedRedirector);
        }
      }

      function verifyState(transition) {
        var route = transition.to();
        var $state = transition.router.stateService;
          if (route && route.data && route.data.requiresLogin === true && !isAuthenticated()) {
            return $state.target(config.loginPath);
          }
      }

      if ($injector.has('$transitions')) {
        var $transitions = $injector.get('$transitions');
        $transitions.onStart({}, verifyState);
      } else {
        var eventName = ($injector.has('$state')) ? '$stateChangeStart' : '$routeChangeStart';
        $rootScope.$on(eventName, verifyRoute);
      }

      return {
        authenticate: authenticate,
        unauthenticate: unauthenticate,
        getToken: function(){ return invokeToken(config.tokenGetter); },
        redirect: function() { return invokeRedirector(config.unauthenticatedRedirector); },
        checkAuthOnRefresh: checkAuthOnRefresh,
        redirectWhenUnauthenticated: redirectWhenUnauthenticated,
        isAuthenticated: isAuthenticated
      }
    }
  });
<|endoftext|>


<commit_before>import React, { useMemo, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import R from 'ramda';

import { useFacebookLogin } from 'hooks/login';
import authStatus from '../../../constants/authStatus';
import styles from './SubmissionBlock.module.css';

const isAuthStatusConnected = R.compose(
  R.equals(authStatus.CONNECTED),
  auth => auth.get('status'),
);

const SubmissionBlock = ({ onSubmit }) => {
  const auth = useSelector(R.prop('auth'));
  const login = useFacebookLogin();
  const hasLoggedIn = useMemo(() => isAuthStatusConnected(auth), [auth]);
  const btnText = (hasLoggedIn ? '' : '以  f  認證，') + '送出資料並解鎖';
  const handleSubmit = useCallback(async () => {
    if (hasLoggedIn) {
      await onSubmit();
    } else {
      await login();
    }
  }, [hasLoggedIn, login, onSubmit]);
  return (

      <button className={styles.button} onClick={handleSubmit}>
        {btnText}
      </button>

        我分享的是真實資訊，並遵守中華民國法令，以及本站
        <Link className={styles.link} to="/user-terms" target="_blank">
          使用者條款
        </Link>

  );
};

SubmissionBlock.propTypes = {
  onSubmit: PropTypes.func.isRequired,
};

export default SubmissionBlock;
<commit_msg>Refactor: 面試經驗表單 login 方式更新＋加上發文留言規則 (#966)<commit_after>import React, { useCallback } from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';

import { useLogin } from 'hooks/login';
import styles from './SubmissionBlock.module.css';

const SubmissionBlock = ({ onSubmit }) => {
  const [isLoggedIn, login] = useLogin();
  const btnText = (isLoggedIn ? '' : '登入帳號，以') + '送出資料並解鎖';
  const handleSubmit = useCallback(async () => {
    if (isLoggedIn) {
      await onSubmit();
    } else {
      login();
    }
  }, [isLoggedIn, login, onSubmit]);
  return (

      <button className={styles.button} onClick={handleSubmit}>
        {btnText}
      </button>

        我分享的是真實資訊，並遵守中華民國法令，以及本站
        <Link className={styles.link} to="/user-terms" target="_blank">
          使用者條款
        </Link>
        以及
        <Link className={styles.link} to="/guidelines" target="_blank">
          發文留言規則
        </Link>

  );
};

SubmissionBlock.propTypes = {
  onSubmit: PropTypes.func.isRequired,
};

export default SubmissionBlock;
<|endoftext|>


<commit_before>import React from 'react';
import MarketingFeatureItem from './MarketingFeatureItem';

const localMessages = {

  globalCollectionsTitle: { id: 'marketing.globalCollections.title', defaultMessage: 'Search with Global Coverage' },
  globalCollectionsDescription: { id: 'marketing.globalCollections.description', defaultMessage: '
Media Cloud supports searching individual media sources, or across media sources grouped into collections. We have collections covering top media sources in over 100 countries, and add more all the time. Media Cloud also lets you search by language, including various levels of support for English, Spanish, Arabic, Japanese, and other languages. Our Source Manager tool gives you an overview of what content we have in our database.
' },

  attentionTitle: { id: 'marketing.attention.title', defaultMessage: 'Track Attention Over Time' },
  attentionDescription: { id: 'marketing.attention.description', defaultMessage: '
Media Cloud shows you attention to an issue over time to help you understand how much it is covered. Our data can reveal key events that cause spikes in coverage and conversation. Plateaus can reveal stable, "normal", levels of attention to compare against. You can download all our charts and the underlying aggregated data.
' },
/*
  influenceTitle: { id: 'marketing.influence.title', defaultMessage: 'Find Influential Sources and Stories' },
  influenceDescription: { id: 'marketing.influence.description', defaultMessage: '
Ranking media by social shares and cross-linking patterns can reveal influential sources and stories that drive narratives about an issue. Media Cloud can gather bit.ly clicks, Facebook shares, media inlinks and outlinks, and Twitter shares. You can can also simply download lists of stories with URLs to drive your own custom analysis. Due to copyright restrictions Media Cloud can\'t share the full content of stories in our database.
' },
*/
  framingTitle: { id: 'marketing.framing.title', defaultMessage: 'Identify How an Issue is Talked About' },
  framingDescription: { id: 'marketing.framing.description', defaultMessage: '
Examine the words used to talk about an issue in order to pinpoint differing media narratives. Media Cloud can show word clouds, word counts, bri-grams, word trees, word embeddings, and more to help you narrow in on the language used.
' },

  mapTitle: { id: 'marketing.map.title', defaultMessage: 'Map Geographic Coverage' },
  mapDescription: { id: 'marketing.map.description', defaultMessage: '
We geocode all our stories to identify the countries and states they are about. Media Cloud\'s maps can help you narrow in on the places that talk about your issue the most, or identify issue "deserts" where it isn\'t talked about at all.
' },

};

const MarketingFeatureList = () => (

    <MarketingFeatureItem
      titleMsg={localMessages.globalCollectionsTitle}
      contentMsg={localMessages.globalCollectionsDescription}
      imageName={'global-collections-2x.png'}
    />
    <MarketingFeatureItem
      titleMsg={localMessages.attentionTitle}
      contentMsg={localMessages.attentionDescription}
      imageName={'attention-2x.png'}
      imageOnLeft
    />
    {/*
        <MarketingFeatureItem
          titleMsg={localMessages.influenceTitle}
          contentMsg={localMessages.influenceDescription}
          imageName={'influence-2x.png'}
        />
    */}
    <MarketingFeatureItem
      titleMsg={localMessages.framingTitle}
      contentMsg={localMessages.framingDescription}
      imageName={'framing-2x.png'}
      imageOnLeft
    />
    <MarketingFeatureItem
      titleMsg={localMessages.mapTitle}
      contentMsg={localMessages.mapDescription}
      imageName={'mapping-2x.png'}
    />

);

export default
  MarketingFeatureList;
<commit_msg>more work on explorer homepage marketing copy and background #992<commit_after>import React from 'react';
import MarketingFeatureItem from './MarketingFeatureItem';

const localMessages = {

  globalCollectionsTitle: { id: 'marketing.globalCollections.title', defaultMessage: 'Search with Global Coverage' },
  globalCollectionsDescription: { id: 'marketing.globalCollections.description', defaultMessage: '
Media Cloud supports searching individual media sources, or across media sources grouped into collections. We have collections covering top media sources in over 100 countries, and add more all the time. Media Cloud also lets you search by language, including various levels of support for English, Spanish, Arabic, Japanese, and other languages. Our Source Manager tool gives you an overview of what content we have in our database.
' },

  attentionTitle: { id: 'marketing.attention.title', defaultMessage: 'Track Attention Over Time' },
  attentionDescription: { id: 'marketing.attention.description', defaultMessage: '
Media Cloud shows you attention to an issue over time to help you understand how much it is covered. Our data can reveal key events that cause spikes in coverage and conversation. Plateaus can reveal stable, "normal", levels of attention to compare against. You can download all our charts and the underlying aggregated data.
' },
/*
  influenceTitle: { id: 'marketing.influence.title', defaultMessage: 'Find Influential Sources and Stories' },
  influenceDescription: { id: 'marketing.influence.description', defaultMessage: '
Ranking media by social shares and cross-linking patterns can reveal influential sources and stories that drive narratives about an issue. Media Cloud can gather bit.ly clicks, Facebook shares, media inlinks and outlinks, and Twitter shares. You can can also simply download lists of stories with URLs to drive your own custom analysis. Due to copyright restrictions Media Cloud can\'t share the full content of stories in our database.
' },
*/
  framingTitle: { id: 'marketing.framing.title', defaultMessage: 'Identify How an Issue is Talked About' },
  framingDescription: { id: 'marketing.framing.description', defaultMessage: '
Examine the words used to talk about an issue in order to pinpoint differing media narratives. Media Cloud can show word clouds, word counts, bri-grams, word trees, word embeddings, and more to help you narrow in on the language used.
' },

  mapTitle: { id: 'marketing.map.title', defaultMessage: 'Map Geographic Coverage' },
  mapDescription: { id: 'marketing.map.description', defaultMessage: '
We geocode all our stories to identify the countries and states they are about. Media Cloud\'s maps can help you narrow in on the places that talk about your issue the most, or identify issue "deserts" where it isn\'t talked about at all.
' },

};

const MarketingFeatureList = () => (

    <MarketingFeatureItem
      titleMsg={localMessages.globalCollectionsTitle}
      contentMsg={localMessages.globalCollectionsDescription}
      imageName={'global-collections-2x.png'}
    />
    <MarketingFeatureItem
      titleMsg={localMessages.attentionTitle}
      contentMsg={localMessages.attentionDescription}
      imageName={'attention-2x.png'}
      imageOnLeft
    />
    {/*
        <MarketingFeatureItem
          titleMsg={localMessages.influenceTitle}
          contentMsg={localMessages.influenceDescription}
          imageName={'influence-2x.png'}
        />
    */}
    <MarketingFeatureItem
      titleMsg={localMessages.framingTitle}
      contentMsg={localMessages.framingDescription}
      imageName={'framing-2x.png'}
    />
    <MarketingFeatureItem
      titleMsg={localMessages.mapTitle}
      contentMsg={localMessages.mapDescription}
      imageName={'mapping-2x.png'}
      imageOnLeft
    />

);

export default
  MarketingFeatureList;
<|endoftext|>


<commit_before>import React from 'react';
import styled from 'styled-components';
import {Link, TitleSection,FileStatus} from 'components';
import {size, palette, font} from 'styled-theme';
import {
  Card,
  CardActions,
  CardHeader,
  CardMedia,
  CardTitle,
  CardText
} from 'material-ui/Card';
import {Grid, Row, Col} from 'react-flexbox-grid';
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton';
import Badge from 'material-ui/Badge';
import Comment from 'material-ui/svg-icons/communication/comment';

const Wrapper = styled.div `
  .img-media{
    text-align: center;
    img{
      height: 100%;
      width: 100%;
    }
  }
  .options{
    padding: 0px 20px 0px 0px;
  }

.card-title{
  font-size: ${font('xxs')} !important;
	color: ${palette('basescale', 2)} !important;
  font-weight: 500;
}

`

class FileCardHorizontal extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    return (
      <Wrapper>
        <Link to={`/file/summary/${this.props.record.id}`}>
          <Paper>
            <Row>
              <Col xs={12} sm={4} md={4} lg={4} className="img-media">

              </Col>
              <Col xs={12} sm={8} md={8} lg={8} className="paper-padding-1">

                  <TitleSection className="padding-bottom-1 card-title">{this.props.record.name}</TitleSection>
                  <FlatButton className="btn-option align-left" fullWidth={true}>
                    <Comment/> {this.props.record.comment}
                  </FlatButton>

                    Lorem ipsum dolor sit amet, consectetur piscing elipiscing elipiscing eliadipiscing elit. Morbi luctus leo non sapien tempus, ac cursus lectus tristique. Donec vitae mattis ante. Donec vitae mattis ante

                  <FileStatus />

              </Col>
            </Row>
          </Paper>
        </Link>
      </Wrapper>
    )
  }
}

export default FileCardHorizontal;
<commit_msg>Horizontal card styles<commit_after>import React from 'react';
import styled from 'styled-components';
import {Link, TitleSection,FileStatus} from 'components';
import {size, palette, font} from 'styled-theme';
import {
  Card,
  CardActions,
  CardHeader,
  CardMedia,
  CardTitle,
  CardText
} from 'material-ui/Card';
import {Grid, Row, Col} from 'react-flexbox-grid';
import Paper from 'material-ui/Paper';
import FlatButton from 'material-ui/FlatButton';
import Badge from 'material-ui/Badge';
import Comment from 'material-ui/svg-icons/communication/comment';

const Wrapper = styled.div `
  .img-media{
    text-align: center;
    img{
      height: auto;
      max-width: 100%;
    }
  }
  .options{
    padding: 0px 20px 0px 0px;
  }

.card-title{
  font-size: ${font('xxs')} !important;
	color: ${palette('basescale', 2)} !important;
  font-weight: 500;
}

`

class FileCardHorizontal extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    return (
      <Wrapper>
        <Link to={`/file/summary/${this.props.record.id}`}>
          <Paper>
            <Row>
              <Col xs={12} sm={4} md={4} lg={4} className="img-media">
                <img src={`https://s3.amazonaws.com/sib-resources/images/catalogo/miniatura/png/t-anfibios.png`}/>
              </Col>
              <Col xs={12} sm={8} md={8} lg={8} className="paper-padding-1">

                  <TitleSection className="padding-bottom-1 card-title">{this.props.record.name}</TitleSection>
                  <FlatButton className="btn-option align-left" fullWidth={true}>
                    <Comment/> {this.props.record.comment}
                  </FlatButton>

                    Lorem ipsum dolor sit amet, consectetur piscing elipiscing elipiscing eliadipiscing elit. Morbi luctus leo non sapien tempus, ac cursus lectus tristique. Donec vitae mattis ante. Donec vitae mattis ante

                  <FileStatus />

              </Col>
            </Row>
          </Paper>
        </Link>
      </Wrapper>
    )
  }
}

export default FileCardHorizontal;
<|endoftext|>


<commit_before>describe('Angular.js \'help\' Routes', function() {

  var route;

  // excuted before each "it" is run
  beforeEach(function() {

    // load the module
    module('help');

    // inject dependencies
    inject(function($route) {
      route = $route;
    });

  });

  /* only to check if injection work fine */
  it('should be defined', function() {

    // assertions
    expect(route).toBeDefined();

  });

  describe('Routes Map', function() {

    describe('location \'/help\'', function() {

      it('should be defined', function() {

        // assertions
        expect(route.routes['/help']).toBeDefined();

      });

      it('should map to controller HelpCtrl as vm', function() {

        // assertions
        expect(route.routes['/help'].controller).toBe('HelpCtrl as vm');

      });

      it('should map to templateUrl app/help/template.html', function() {

        // assertions
        expect(route.routes['/help'].templateUrl).toEqual('app/help/template.html');

      });

    });

  }); //--- end: Routes Map

});
<commit_msg>src/app/help unit test's code style update #32<commit_after>describe('Angular.js \'help\' Routes', function() {

  var route;

  // excuted before each "it" is run
  beforeEach(function() {

    // load the module
    module('help');

    // inject dependencies
    inject(function($route) {
      route = $route;
    });

  });

  /* only to check if injection work fine */
  it('should be defined', function() {

    // assertions
    expect(route).toBeDefined();

  });

  describe('Routes Map', function() {

    describe('location \'/help\'', function() {

      it('should be defined', function() {

        // assertions
        expect(route.routes['/help']).toBeDefined();

      });

      it('should map to controller HelpCtrl as vm', function() {

        var check = route.routes['/help'];

        // assertions
        expect(check.controller).toBe('HelpCtrl');
        expect(check.controllerAs).toBe('vm');

      });

      it('should map to templateUrl app/help/template.html', function() {

        // assertions
        expect(route.routes['/help'].templateUrl).toEqual('app/help/template.html');

      });

    });

  }); //--- end: Routes Map

});
<|endoftext|>


<commit_before>const ipc = require('electron').ipcMain;
const watchlistParser = require('../../page_parser').watchlist;
const Promise = require('bluebird');
const util = require('util');
const utils = require('../utils');

const SET_TO_CURRENT = "?format=json&type=reminder&title=reminder_this";
const SET_FINISHED = "?format=json&type=reminder&title=reminder_finish";

function WatchlistHandler(app, sessionHandler) {
    this.session_handler = sessionHandler;
    this.cache = require('../db')('watchlist-cache');
    this.app = app;
    this.settings = require('../settings');
    this.lastCheck = 0;
}

WatchlistHandler.prototype.loadWatchlist = function() {
    return this.session_handler.openRequest(PROXER_BASE_URL + PROXER_PATHS.WATCHLIST)
        .then(watchlistParser.parseWatchlist);
};

WatchlistHandler.prototype.checkUpdates = function() {
    const self = this;
    LOG.info("Checking for new watchlist updates");
    this.lastCheck = new Date().getTime();
    this.loadWatchlist().then(function(result) {
        const old = self.cache.find({ type: 'watchlist-cache' });
        if(!old) {
            self.cache.push({
                type: 'watchlist-cache',
                anime: result.anime,
                manga: result.manga
            });
            return result;
        }

        const updates = {};
        updates.anime = utils.getOnlineDiff(old.anime, result.anime);
        updates.manga = utils.getOnlineDiff(old.manga, result.manga);
        self.cache.chain().find({ type: 'watchlist-cache' }).merge({ anime: result.anime, manga: result.manga }).value();
        return updates;
    }).then(function(updates) {
        Object.keys(updates).forEach(function(type) {
            updates[type].forEach(function(update) {
                LOG.verbose('Sending watchlist update for ' + update.name);
                self.app.notifyWindow('new-' + type + '-ep', update);
            });
        });
    });
};

WatchlistHandler.prototype.updateEntry = function(id, ep, sub) {
    return this.session_handler.openRequest(PROXER_BASE_URL + util.format(PROXER_PATHS.WATCH_ANIME, id, ep, sub) + SET_TO_CURRENT)
        .then(watchlistParser.parseUpdateReponse).then(function(msg) {
            return {
                success: true,
                msg: msg.msg
            };
        }).catch(function(e) {
            return {
                success: false,
                msg: "Not Found"
            };
        });
};

WatchlistHandler.prototype.markFinished = function(id, ep, sub) {
    return this.session_handler.openRequest(PROXER_BASE_URL + util.format(PROXER_PATHS.WATCH_ANIME, id, ep, sub) + SET_FINISHED)
        .then(watchlistParser.parseFinishResponse).then(function(msg) {
            return {
                success: true,
                msg: msg.msg
            };
        }).catch(function(e) {
            return {
                success: false,
                msg: "Not Found"
            };
        });
};

WatchlistHandler.prototype.deleteEntry = function(entry) {
    return this.session_handler.openRequest(PROXER_BASE_URL + PROXER_PATHS.DELETE_WATCHLIST + entry)
        .then(watchlistParser.parseDeleteResponse).then(function(msg) {
            if(msg.error == 1) {
                throw "Could not update watchlist";
            } else {
                return msg;
            }
        });
};

WatchlistHandler.prototype.register = function() {
    const self = this;
    ipc.on('watchlist', function(event) {
        self.loadWatchlist().then(function(result) {
            event.sender.send('watchlist', result);
        });
    });

    ipc.on('watchlist-update', function(event) {
        self.checkUpdates();
    });

    ipc.on('add-watchlist', function(event, id, ep, sub) {
        self.updateEntry(id, ep, sub).then(function(result) {
            event.sender.send('add-watchlist', result);
        });
    });

    ipc.on('delete-watchlist', function(event, entry) {
        self.deleteEntry(entry).then(function(res) {
            res.entry = entry;
            event.sender.send('delete-watchlist', res);
        });
    });

    ipc.on('finish-watchlist', function(event, id, ep, sub) {
        self.markFinished(id, ep, sub).then(function(result) {
            event.sender.send('finish-watchlist', result);
        });
    });

    this.watchLoop();
};

WatchlistHandler.prototype.watchLoop = function() {
    const self = this;
    setTimeout(function() {
        const time = self.settings.getWatchlistSettings().check_interval;
        if(new Date().getTime() - self.lastCheck > time * 60000 - 5000) {
            self.checkUpdates();
        }

        self.watchLoop();
    }, 30000);
};

module.exports = WatchlistHandler;
<commit_msg>Don't just display everything from the watchlist on first startup<commit_after>const ipc = require('electron').ipcMain;
const watchlistParser = require('../../page_parser').watchlist;
const Promise = require('bluebird');
const util = require('util');
const utils = require('../utils');

const SET_TO_CURRENT = "?format=json&type=reminder&title=reminder_this";
const SET_FINISHED = "?format=json&type=reminder&title=reminder_finish";

function WatchlistHandler(app, sessionHandler) {
    this.session_handler = sessionHandler;
    this.cache = require('../db')('watchlist-cache');
    this.app = app;
    this.settings = require('../settings');
    this.lastCheck = 0;
}

WatchlistHandler.prototype.loadWatchlist = function() {
    return this.session_handler.openRequest(PROXER_BASE_URL + PROXER_PATHS.WATCHLIST)
        .then(watchlistParser.parseWatchlist);
};

WatchlistHandler.prototype.checkUpdates = function() {
    const self = this;
    LOG.info("Checking for new watchlist updates");
    this.lastCheck = new Date().getTime();
    this.loadWatchlist().then(function(result) {
        const old = self.cache.find({ type: 'watchlist-cache' });
        if(!old) {
            self.cache.push({
                type: 'watchlist-cache',
                anime: result.anime,
                manga: result.manga
            });

            const onlineFilter = entry => entry.status;

            return {
                anime: result.anime.filter(onlineFilter),
                manga: result.manga.filter(onlineFilter)
            };
        }

        const updates = {};
        updates.anime = utils.getOnlineDiff(old.anime, result.anime);
        updates.manga = utils.getOnlineDiff(old.manga, result.manga);
        self.cache.chain().find({ type: 'watchlist-cache' }).merge({ anime: result.anime, manga: result.manga }).value();
        return updates;
    }).then(function(updates) {
        Object.keys(updates).forEach(function(type) {
            updates[type].forEach(function(update) {
                LOG.verbose('Sending watchlist update for ' + update.name);
                self.app.notifyWindow('new-' + type + '-ep', update);
            });
        });
    });
};

WatchlistHandler.prototype.updateEntry = function(id, ep, sub) {
    return this.session_handler.openRequest(PROXER_BASE_URL + util.format(PROXER_PATHS.WATCH_ANIME, id, ep, sub) + SET_TO_CURRENT)
        .then(watchlistParser.parseUpdateReponse).then(function(msg) {
            return {
                success: true,
                msg: msg.msg
            };
        }).catch(function(e) {
            return {
                success: false,
                msg: "Not Found"
            };
        });
};

WatchlistHandler.prototype.markFinished = function(id, ep, sub) {
    return this.session_handler.openRequest(PROXER_BASE_URL + util.format(PROXER_PATHS.WATCH_ANIME, id, ep, sub) + SET_FINISHED)
        .then(watchlistParser.parseFinishResponse).then(function(msg) {
            return {
                success: true,
                msg: msg.msg
            };
        }).catch(function(e) {
            return {
                success: false,
                msg: "Not Found"
            };
        });
};

WatchlistHandler.prototype.deleteEntry = function(entry) {
    return this.session_handler.openRequest(PROXER_BASE_URL + PROXER_PATHS.DELETE_WATCHLIST + entry)
        .then(watchlistParser.parseDeleteResponse).then(function(msg) {
            if(msg.error == 1) {
                throw "Could not update watchlist";
            } else {
                return msg;
            }
        });
};

WatchlistHandler.prototype.register = function() {
    const self = this;
    ipc.on('watchlist', function(event) {
        self.loadWatchlist().then(function(result) {
            event.sender.send('watchlist', result);
        });
    });

    ipc.on('watchlist-update', function(event) {
        self.checkUpdates();
    });

    ipc.on('add-watchlist', function(event, id, ep, sub) {
        self.updateEntry(id, ep, sub).then(function(result) {
            event.sender.send('add-watchlist', result);
        });
    });

    ipc.on('delete-watchlist', function(event, entry) {
        self.deleteEntry(entry).then(function(res) {
            res.entry = entry;
            event.sender.send('delete-watchlist', res);
        });
    });

    ipc.on('finish-watchlist', function(event, id, ep, sub) {
        self.markFinished(id, ep, sub).then(function(result) {
            event.sender.send('finish-watchlist', result);
        });
    });

    this.watchLoop();
};

WatchlistHandler.prototype.watchLoop = function() {
    const self = this;
    setTimeout(function() {
        const time = self.settings.getWatchlistSettings().check_interval;
        if(new Date().getTime() - self.lastCheck > time * 60000 - 5000) {
            self.checkUpdates();
        }

        self.watchLoop();
    }, 30000);
};

module.exports = WatchlistHandler;
<|endoftext|>


<commit_before>/*!
 * viewport
 * Version: 0.0.1
 * Date: 2016/7/21
 * https://github.com/Nuintun/viewport
 *
 * Original Author: http://www.jsbug.com/lab/samples/viewport/
 *
 * This is licensed under the MIT License (MIT).
 * For details, see: https://github.com/Nuintun/viewport/blob/master/LICENSE
 */

'use strict';

var $ = require('jquery');
var is = require('./is');

// id expando
var expando = 0;

/**
 * patch the threshold like css
 * - 1            ==> top: 1, right: 1, bottom: 1, left: 1
 * - [1]          ==> top: 1, right: 1, bottom: 1, left: 1
 * - [1, 2]       ==> top: 1, right: 2, bottom: 1, left: 2
 * - [1, 2, 3]    ==> top: 1, right: 2, bottom: 3, left: 2
 * - [1, 2, 3, 4] ==> top: 1, right: 2, bottom: 3, left: 4
 * @param threshold
 * @param absolute
 * @returns {*}
 */
function patchThreshold(threshold, absolute){
  if (is.number(threshold) && !is.nan(threshold) && !is.infinite(threshold)) {
    if (absolute) {
      threshold = Math.abs(threshold);
    }

    threshold = [threshold, threshold, threshold, threshold];
  } else if (is.array(threshold)) {
    var value;
    var set = [];
    var length = threshold.length;

    for (var i = 0; i < length; i++) {
      if (set.length < 4) {
        value = threshold[i];

        if (is.number(value) && !is.nan(value) && !is.infinite(value)) {
          set.push(absolute ? Math.abs(value) : value);
        }
      } else {
        break;
      }
    }

    switch (set.length) {
      case 0:
        threshold = [0, 0, 0, 0];
        break;
      case 1:
        threshold = [set[0], set[0], set[0], set[0]];
        break;
      case 2:
        threshold = [set[0], set[1], set[0], set[1]];
        break;
      case 3:
        threshold = [set[0], set[1], set[2], set[1]];
        break;
      default:
        threshold = set;
        break;
    }
  } else {
    threshold = [0, 0, 0, 0];
  }

  return threshold;
}

/**
 * patch the viewport if it is the window object
 * @param viewport
 * @returns {*}
 */
function patchViewport(viewport){
  if (window !== window && is.element(viewport)) {
    throw new Error('Viewport must be window or a HTMLElement');
  }

  return viewport === window
    ? (document.compatMode == 'CSS1Compat' ? document.documentElement : document.body)
    : viewport;
}

/**
 * Viewport
 * @param viewport
 * @param options
 * @constructor
 */
function Viewport(viewport, options){
  var context = this;

  context.events = {};
  context.id = expando++;
  context.viewport = $(patchViewport(viewport));

  context.__initOptions(options);
  context.__findTarget();
  context.__init();
}

/**
 * @type {{
 *   __init: Viewport.__init,
 *   __changeViewport: Viewport.__changeViewport,
 *   __initOptions: Viewport.__initOptions,
 *   __findTarget: Viewport.__findTarget,
 *   __filterTargetInViewport: Viewport.__filterTargetInViewport,
 *   on: Viewport.on, off: Viewport.off,
 *   emit: Viewport.emit,
 *   refresh: Viewport.refresh,
 *   destroy: Viewport.destroy
 * }}
 */
Viewport.prototype = {
  __init: function (){
    // delay trigger the scroll or resize event.
    var timer;
    var context = this;
    var id = context.id;
    var options = context.options;
    var viewport = context.viewport;
    var scrollTop = viewport.scrollTop();
    var scrollLeft = viewport.scrollLeft();
    var namespace = '.viewport-' + id;

    viewport.on(
      'scroll' + namespace + ' resize' + namespace,
      function (){
        clearTimeout(timer);

        timer = setTimeout(function (){
          // trigger the viewchange event internally.
          var event = context.__changeViewport(scrollTop, scrollLeft);

          // cahce scroll position
          scrollTop = event.scrollTop;
          scrollLeft = event.scrollLeft;
        }, options.delay);
      }
    );

    // init event
    this.__changeViewport(0, 0);
  },
  __changeViewport: function (vertical, horizontal){
    var context = this;
    var options = context.options;
    var viewport = context.viewport;
    var thresholdBorderReaching = options.thresholdBorderReaching;

    if (!viewport.is(':visible')) return;

    var width = viewport.innerWidth();
    var height = viewport.innerHeight();
    var scrollWidth = viewport[0].scrollWidth;
    var scrollHeight = viewport[0].scrollHeight;

    // event
    var event = {};

    // scrollbar position
    event.scrollTop = viewport.scrollTop();
    event.scrollLeft = viewport.scrollLeft();
    event.offsetY = event.scrollTop - vertical;
    event.offsetX = event.scrollLeft - horizontal;

    // event type
    event.type = 'viewchange';

    // target
    event.target = context.__filterTargetInViewport(width, height);

    // calculate viewport border reaching detail infos
    event.top = event.scrollTop - thresholdBorderReaching[0] <= 0;
    event.right = width + event.scrollLeft + thresholdBorderReaching[1] >= scrollWidth;
    event.bottom = height + event.scrollTop + thresholdBorderReaching[2] >= scrollHeight;
    event.left = event.scrollLeft - thresholdBorderReaching[3] <= 0;

    // emit view change event
    context.emit(event.type, event);

    // return scrollbar position
    return event;
  },
  __initOptions: function (options){
    options = $.extend({
      delay: 150,
      target: null,
      threshold: 0,
      skipHidden: true,
      thresholdBorderReaching: 0
    }, options);

    options.threshold = patchThreshold(options.threshold);
    options.thresholdBorderReaching = patchThreshold(options.thresholdBorderReaching, true);

    this.options = options;
  },
  __findTarget: function (){
    var context = this;
    var options = context.options;
    var target = options.target;
    var viewport = context.viewport;

    if (is.string(target)) {
      target = viewport.find(target);
    } else if (is.element(target) && $.contains(viewport[0], target)) {
      target = $(target);
    } else if (target instanceof $) {
      var element = null;

      target.each(function (index, value){
        if ($.contains(viewport[0], value)) {
          if (!element) {
            element = $(value);
          } else {
            element.add(value);
          }
        }
      });

      target = element;
    } else {
      target = null;
    }

    context.target = target;
  },
  __filterTargetInViewport: function (width, height){
    var rect;
    var result = [];
    var context = this;
    var target = context.target;

    // target is null
    if (target === null) return result;

    var options = context.options;
    var threshold = options.threshold;
    var skipHidden = options.skipHidden;

    // get viewport height and width
    var viewport = context.viewport;

    // adjust the offsetTop and offsetLeft
    var viewportRect = viewport[0].getBoundingClientRect();
    var offsetTop = viewportRect.top + Math.round((parseInt(viewport.css('border-top-width')) || 0));
    var offsetLeft = viewportRect.left + Math.round((parseInt(viewport.css('border-left-width')) || 0));

    // filter elements by their rect info
    for (var i = 0; i < target.length; i++) {
      rect = target[i].getBoundingClientRect();

      // hidden element
      if (rect.top == 0 && rect.bottom == 0 && rect.left == 0 && rect.right == 0) {
        if (!skipHidden) {
          result.push(target[i]);
        }
      } else {
        // visible element
        var top = rect.top - offsetTop;
        var bottom = rect.bottom - offsetTop;
        var left = rect.left - offsetLeft;
        var right = rect.right - offsetLeft;

        // adjust position
        if (
          !(top - threshold[0] >= height
          || right + threshold[1] <= 0
          || bottom + threshold[2] <= 0
          || left - threshold[3] >= width)
        ) {
          result.push(target[i]);
        }
      }
    }

    return result;
  },
  on: function (event, handler){
    var context = this;

    context.events[event] = context.events[event]
      || $.Callbacks('memory stopOnFalse');

    context.events[event].add(handler);

    return context;
  },
  off: function (event, handler){
    var context = this;

    switch (arguments.length) {
      case 0:
        context.events = {};
        break;
      case 1:
        delete context.events[event];
        break;
      default:
        context.events[event] && context.events[event].remove(handler);
        break;
    }

    return context;
  },
  emit: function (event){
    var context = this;
    var data = [].slice.call(arguments, 1);

    context.events[event] = context.events[event]
      || $.Callbacks('memory stopOnFalse');

    this.events[event].fireWith(context, data);

    return context;
  },
  refresh: function (){
    this.__findTarget();

    return this;
  },
  destroy: function (){
    var context = this;
    var viewport = context.viewport;
    var namespace = '.viewport-' + context.id;

    viewport.off('scroll' + namespace);
    viewport.off('resize' + namespace);
  }
};

module.exports = Viewport;
<commit_msg>update files<commit_after>/*!
 * viewport
 * Version: 0.0.1
 * Date: 2016/7/21
 * https://github.com/Nuintun/viewport
 *
 * Original Author: http://www.jsbug.com/lab/samples/viewport/
 *
 * This is licensed under the MIT License (MIT).
 * For details, see: https://github.com/Nuintun/viewport/blob/master/LICENSE
 */

'use strict';

var $ = require('jquery');
var is = require('./is');

// id expando
var expando = 0;

/**
 * patch the threshold like css
 * - 1            ==> top: 1, right: 1, bottom: 1, left: 1
 * - [1]          ==> top: 1, right: 1, bottom: 1, left: 1
 * - [1, 2]       ==> top: 1, right: 2, bottom: 1, left: 2
 * - [1, 2, 3]    ==> top: 1, right: 2, bottom: 3, left: 2
 * - [1, 2, 3, 4] ==> top: 1, right: 2, bottom: 3, left: 4
 * @param threshold
 * @param absolute
 * @returns {*}
 */
function patchThreshold(threshold, absolute){
  if (is.number(threshold) && !is.nan(threshold) && !is.infinite(threshold)) {
    if (absolute) {
      threshold = Math.abs(threshold);
    }

    threshold = [threshold, threshold, threshold, threshold];
  } else if (is.array(threshold)) {
    var value;
    var set = [];
    var length = threshold.length;

    for (var i = 0; i < length; i++) {
      if (set.length < 4) {
        value = threshold[i];

        if (is.number(value) && !is.nan(value) && !is.infinite(value)) {
          set.push(absolute ? Math.abs(value) : value);
        }
      } else {
        break;
      }
    }

    switch (set.length) {
      case 0:
        threshold = [0, 0, 0, 0];
        break;
      case 1:
        threshold = [set[0], set[0], set[0], set[0]];
        break;
      case 2:
        threshold = [set[0], set[1], set[0], set[1]];
        break;
      case 3:
        threshold = [set[0], set[1], set[2], set[1]];
        break;
      default:
        threshold = set;
        break;
    }
  } else {
    threshold = [0, 0, 0, 0];
  }

  return threshold;
}

/**
 * patch the viewport if it is the window object
 * @param viewport
 * @returns {*}
 */
function patchViewport(viewport){
  if (window !== window && is.element(viewport)) {
    throw new Error('Viewport must be window or a HTMLElement');
  }

  return viewport === window
    ? (document.compatMode == 'CSS1Compat' ? document.documentElement : document.body)
    : viewport;
}

/**
 * Viewport
 * @param viewport
 * @param options
 * @constructor
 */
function Viewport(viewport, options){
  var context = this;

  context.events = {};
  context.id = expando++;
  context.viewport = $(patchViewport(viewport));

  // init
  context.__initOptions(options);
  context.__findTarget();
  context.__init();
}

/**
 * @type {{
 *   __init: Viewport.__init,
 *   __changeViewport: Viewport.__changeViewport,
 *   __initOptions: Viewport.__initOptions,
 *   __findTarget: Viewport.__findTarget,
 *   __filterTargetInViewport: Viewport.__filterTargetInViewport,
 *   on: Viewport.on, off: Viewport.off,
 *   emit: Viewport.emit,
 *   refresh: Viewport.refresh,
 *   destroy: Viewport.destroy
 * }}
 */
Viewport.prototype = {
  __init: function (){
    // delay trigger the scroll or resize event.
    var timer;
    var context = this;
    var id = context.id;
    var options = context.options;
    var viewport = context.viewport;
    var scrollTop = viewport.scrollTop();
    var scrollLeft = viewport.scrollLeft();
    var namespace = '.viewport-' + id;

    viewport.on(
      'scroll' + namespace + ' resize' + namespace,
      function (){
        clearTimeout(timer);

        timer = setTimeout(function (){
          // trigger the viewchange event internally.
          var event = context.__changeViewport(scrollTop, scrollLeft);

          // cahce scroll position
          scrollTop = event.scrollTop;
          scrollLeft = event.scrollLeft;
        }, options.delay);
      }
    );

    // init event
    this.__changeViewport(0, 0);
  },
  __changeViewport: function (vertical, horizontal){
    var context = this;
    var options = context.options;
    var viewport = context.viewport;
    var thresholdBorderReaching = options.thresholdBorderReaching;

    if (!viewport.is(':visible')) return;

    var width = viewport.innerWidth();
    var height = viewport.innerHeight();
    var scrollWidth = viewport[0].scrollWidth;
    var scrollHeight = viewport[0].scrollHeight;

    // event
    var event = {};

    // scrollbar position
    event.scrollTop = viewport.scrollTop();
    event.scrollLeft = viewport.scrollLeft();
    event.offsetY = event.scrollTop - vertical;
    event.offsetX = event.scrollLeft - horizontal;

    // event type
    event.type = 'viewchange';

    // target
    event.target = context.__filterTargetInViewport(width, height);

    // calculate viewport border reaching detail infos
    event.top = event.scrollTop - thresholdBorderReaching[0] <= 0;
    event.right = width + event.scrollLeft + thresholdBorderReaching[1] >= scrollWidth;
    event.bottom = height + event.scrollTop + thresholdBorderReaching[2] >= scrollHeight;
    event.left = event.scrollLeft - thresholdBorderReaching[3] <= 0;

    // emit view change event
    context.emit(event.type, event);

    // return scrollbar position
    return event;
  },
  __initOptions: function (options){
    options = $.extend({
      delay: 150,
      target: null,
      threshold: 0,
      skipHidden: true,
      thresholdBorderReaching: 0
    }, options);

    options.threshold = patchThreshold(options.threshold);
    options.thresholdBorderReaching = patchThreshold(options.thresholdBorderReaching, true);

    this.options = options;
  },
  __findTarget: function (){
    var context = this;
    var options = context.options;
    var target = options.target;
    var viewport = context.viewport;

    if (is.string(target)) {
      target = viewport.find(target);
    } else if (is.element(target) && $.contains(viewport[0], target)) {
      target = $(target);
    } else if (target instanceof $) {
      var element = null;

      target.each(function (index, value){
        if ($.contains(viewport[0], value)) {
          if (!element) {
            element = $(value);
          } else {
            element.add(value);
          }
        }
      });

      target = element;
    } else {
      target = null;
    }

    context.target = target;
  },
  __filterTargetInViewport: function (width, height){
    var rect;
    var result = [];
    var context = this;
    var target = context.target;

    // target is null
    if (target === null) return result;

    var options = context.options;
    var threshold = options.threshold;
    var skipHidden = options.skipHidden;

    // get viewport height and width
    var viewport = context.viewport;

    // adjust the offsetTop and offsetLeft
    var viewportRect = viewport[0].getBoundingClientRect();
    var offsetTop = viewportRect.top + Math.round((parseInt(viewport.css('border-top-width')) || 0));
    var offsetLeft = viewportRect.left + Math.round((parseInt(viewport.css('border-left-width')) || 0));

    // filter elements by their rect info
    for (var i = 0; i < target.length; i++) {
      rect = target[i].getBoundingClientRect();

      // hidden element
      if (rect.top == 0 && rect.bottom == 0 && rect.left == 0 && rect.right == 0) {
        if (!skipHidden) {
          result.push(target[i]);
        }
      } else {
        // visible element
        var top = rect.top - offsetTop;
        var bottom = rect.bottom - offsetTop;
        var left = rect.left - offsetLeft;
        var right = rect.right - offsetLeft;

        // adjust position
        if (
          !(top - threshold[0] >= height
          || right + threshold[1] <= 0
          || bottom + threshold[2] <= 0
          || left - threshold[3] >= width)
        ) {
          result.push(target[i]);
        }
      }
    }

    return result;
  },
  on: function (event, handler){
    var context = this;

    context.events[event] = context.events[event]
      || $.Callbacks('memory stopOnFalse');

    context.events[event].add(handler);

    return context;
  },
  off: function (event, handler){
    var context = this;

    switch (arguments.length) {
      case 0:
        context.events = {};
        break;
      case 1:
        delete context.events[event];
        break;
      default:
        context.events[event] && context.events[event].remove(handler);
        break;
    }

    return context;
  },
  emit: function (event){
    var context = this;
    var data = [].slice.call(arguments, 1);

    context.events[event] = context.events[event]
      || $.Callbacks('memory stopOnFalse');

    this.events[event].fireWith(context, data);

    return context;
  },
  refresh: function (){
    this.__findTarget();

    return this;
  },
  destroy: function (){
    var context = this;
    var viewport = context.viewport;
    var namespace = '.viewport-' + context.id;

    viewport.off('scroll' + namespace);
    viewport.off('resize' + namespace);
  }
};

module.exports = Viewport;
<|endoftext|>


<commit_before>import { roundBalance } from '../../common/tools';
import { info } from '../broadcast';
import { observer as globalObserver } from '../../../common/utils/observer';

const balanceStr = '';

export default Engine =>
    class Balance extends Engine {
        observeBalance() {
            this.listen('balance', r => {
                const {
                    balance: { balance: b, currency },
                } = r;

                const balance = roundBalance({ currency, balance: b });
                const balanceStr = `${balance} ${currency}`;

                globalObserver.setState({ balance, currency });

                info({ accountID: this.accountInfo.loginid, balance: balanceStr });
            });
        }
        // eslint-disable-next-line class-methods-use-this
        getBalance(type) {
            const { scope } = this.store.getState();
            const currency = globalObserver.getState('currency');
            let balance = globalObserver.getState('balance');

            // Deduct trade `amount` in this scope for correct value in `balance`-block
            if (scope === 'BEFORE_PURCHASE') {
                balance = roundBalance({
                    balance: Number(balance) - this.tradeOptions.amount,
                    currency,
                });
            }

            const balanceStr = `${balance} ${currency}`;

            return type === 'STR' ? balanceStr : Number(balance);
        }
    };
<commit_msg>Remove unused variable<commit_after>import { roundBalance } from '../../common/tools';
import { info } from '../broadcast';
import { observer as globalObserver } from '../../../common/utils/observer';

export default Engine =>
    class Balance extends Engine {
        observeBalance() {
            this.listen('balance', r => {
                const {
                    balance: { balance: b, currency },
                } = r;

                const balance = roundBalance({ currency, balance: b });
                const balanceStr = `${balance} ${currency}`;

                globalObserver.setState({ balance, currency });

                info({ accountID: this.accountInfo.loginid, balance: balanceStr });
            });
        }
        // eslint-disable-next-line class-methods-use-this
        getBalance(type) {
            const { scope } = this.store.getState();
            const currency = globalObserver.getState('currency');
            let balance = globalObserver.getState('balance');

            // Deduct trade `amount` in this scope for correct value in `balance`-block
            if (scope === 'BEFORE_PURCHASE') {
                balance = roundBalance({
                    balance: Number(balance) - this.tradeOptions.amount,
                    currency,
                });
            }

            const balanceStr = `${balance} ${currency}`;

            return type === 'STR' ? balanceStr : Number(balance);
        }
    };
<|endoftext|>


<commit_before>/**
 * Created by ElyDeLaCruz on 11/18/2014.
 */
require('sjljs');

// Import base task proxy to extend
var TaskProxy = require('../TaskProxy'),
    path = require('path'),
    fs = require('fs'),
    ssh = require('ssh2');

module.exports = TaskProxy.extend("DeployProxy", {

    registerGulpTask: function (taskPrefix, targets, gulp, wrangler) {
        gulp.task('deploy' + (taskPrefix || ""), function () {
            var target;
            Object.keys(targets).forEach(function (key) {
                target = targets[key];
                console.log('Now deploying "' + key + '" files');
                target.forEach(function (item) {
                    console.log(item[0], ' => ', item[1]);
                });
            });

        });
    },

    registerBundle: function (bundle, gulp, wrangler) {

        // Task string separator
        var separator = wrangler.getTaskStrSeparator(),
            targets = this.getSrcForBundle(bundle, wrangler);

        console.log('Dumping deploy targets here: ', targets);

        this.registerGulpTask(':global', targets, gulp, wrangler);

    }, // end of `registerBundle`

    regsiterBundles: function (bundles, gulp, wrangler) {

    },

    getSrcForBundle: function (bundle, wrangler) {
        var self = this,
            srcs = {},
            allowedFileTypes = wrangler.tasks.deploy.allowedFileTypes,

            // dummy entry
            selectedServerEntry = {
                paths: {
                    js: '/public/js',
                    css: '/public/css',
                    html: '/public/html',
                    md: '/public/'
                }
            };

        if (this.isBundleValidForTask()) {
            return srcs;
        }

        // Set file type arrays
        allowedFileTypes.forEach(function (fileType) {
            var hasDeployOtherFiles = bundle.has('deploy.otherFiles.' + fileType),
                hasFilesFileType = bundle.has('files.' + fileType),
                deployPath, localPath;

            // Check if bundle has files [js, css, allowed file types etc.]
            if (hasFilesFileType) {

                // Initialize storage array
                srcs[fileType] = [];

                // Build local src path
                deployPath = path.join(wrangler.tasks.minify[fileType + 'BuildPath'],
                    bundle.options.name + '.' + fileType);

                // Build deploy src path
                localPath = path.join(selectedServerEntry.paths[fileType],
                    bundle.options.name + '.' + fileType);

                // Push array map entry
                srcs[fileType].push([localPath, deployPath]);
            }

            // Check allowedFileType in deploy.otherFiles key
            if (hasDeployOtherFiles) {

                // Push array map entry
                srcs[fileType] = self.mapFileArrayToDeployArrayMap(
                    bundle.options.deploy.otherFiles[fileType], fileType,
                        selectedServerEntry, wrangler);
            }
        });

        return srcs;

    },

    mapFileArrayToDeployArrayMap: function (fileArray, fileType,
                                            selectedServerEntry, wrangler) {
        return fileArray.map(function (item) {
            var retVal;
            if (selectedServerEntry.paths[fileType]) {
                retVal = [item, path.join(selectedServerEntry.paths[fileType],
                    path.basename(item))];
            }
            else {
                retVal = [item, item];
            }

            return retVal;
        });
    },

    isBundleValidForTask: function (bundle) {
        return bundle && (
                bundle.has('files')
                || (bundle.has('requirejs') || bundle.has('browserify'))
                || bundle.has('deploy.otherFiles') );
    }

}); // end of export
<commit_msg>Removed is bundle valid check to regsterBundle method.<commit_after>/**
 * Created by ElyDeLaCruz on 11/18/2014.
 */
require('sjljs');

// Import base task proxy to extend
var TaskProxy = require('../TaskProxy'),
    path = require('path'),
    fs = require('fs'),
    ssh = require('ssh2');

module.exports = TaskProxy.extend("DeployProxy", {

    registerGulpTask: function (taskPrefix, targets, gulp, wrangler) {
        gulp.task('deploy' + (taskPrefix || ""), function () {
            var target;
            Object.keys(targets).forEach(function (key) {
                target = targets[key];
                console.log('Now deploying "' + key + '" files');
                target.forEach(function (item) {
                    console.log(item[0], ' => ', item[1]);
                });
            });

        });
    },

    registerBundle: function (bundle, gulp, wrangler) {

        // If bundle is not valid for task, bail
        if (!this.isBundleValidForTask(bundle)) {
            return;
        }

        // Task string separator
        var separator = wrangler.getTaskStrSeparator(),
            targets = this.getSrcForBundle(bundle, wrangler);

        this.registerGulpTask(':global', targets, gulp, wrangler);

    }, // end of `registerBundle`

    regsiterBundles: function (bundles, gulp, wrangler) {

    },

    getSrcForBundle: function (bundle, wrangler) {
        var self = this,
            srcs = {},
            allowedFileTypes = wrangler.tasks.deploy.allowedFileTypes,

            // dummy entry
            selectedServerEntry = {
                paths: {
                    js: '/public/js',
                    css: '/public/css',
                    html: '/public/html',
                    md: '/public/'
                }
            };

        // Set file type arrays
        allowedFileTypes.forEach(function (fileType) {
            var hasDeployOtherFiles = bundle.has('deploy.otherFiles.' + fileType),
                hasFilesFileType = bundle.has('files.' + fileType),
                deployPath, localPath;

            // Check if bundle has files [js, css, allowed file types etc.]
            if (hasFilesFileType) {

                // Initialize storage array
                srcs[fileType] = [];

                // Build local src path
                deployPath = path.join(wrangler.tasks.minify[fileType + 'BuildPath'],
                    bundle.options.name + '.' + fileType);

                // Build deploy src path
                localPath = path.join(selectedServerEntry.paths[fileType],
                    bundle.options.name + '.' + fileType);

                // Push array map entry
                srcs[fileType].push([localPath, deployPath]);
            }

            // Check allowedFileType in deploy.otherFiles key
            if (hasDeployOtherFiles) {

                // Push array map entry
                srcs[fileType] = self.mapFileArrayToDeployArrayMap(
                    bundle.options.deploy.otherFiles[fileType], fileType,
                        selectedServerEntry, wrangler);
            }
        });

        return srcs;

    },

    mapFileArrayToDeployArrayMap: function (fileArray, fileType,
                                            selectedServerEntry, wrangler) {
        return fileArray.map(function (item) {
            var retVal;
            if (selectedServerEntry.paths[fileType]) {
                retVal = [item, path.join(selectedServerEntry.paths[fileType],
                    path.basename(item))];
            }
            else {
                retVal = [item, item];
            }

            return retVal;
        });
    },

    isBundleValidForTask: function (bundle) {
        return bundle && (
                bundle.has('files')
                || (bundle.has('requirejs') || bundle.has('browserify'))
                || bundle.has('deploy.otherFiles') );
    }

}); // end of export
<|endoftext|>