<commit_before>const addComma        = require('../../../common/currency').addComma;
const localize        = require('../../../../_common/localize').localize;
const isCallputspread = require('../callputspread').isCallputspread;

const HighchartUI = (() => {
    let common_time_style,
        common_spot_style,
        txt,
        chart_options;

    const initLabels = () => {
        common_time_style = 'margin-bottom: 3px; margin-left: 10px; height: 0; width: 20px; border: 0; border-bottom: 2px; border-color: #e98024; display: inline-block;';
        common_spot_style = 'margin-left: 10px; display: inline-block; border-radius: 6px;';
    };

    const getLabels = (option) => {
        if (!common_time_style || !common_spot_style) {
            initLabels();
        }
        switch (option) {
            case 'start_time':
                return `<div style="${common_time_style} border-style: solid;"></div> ${localize('Start time')} `;
            case 'entry_spot':
                return `<div style="${common_spot_style} border: 3px solid orange; width: 4px; height: 4px;"></div> ${localize('Entry spot')} `;
            case 'exit_spot':
                return `<div style="${common_spot_style} background-color: orange; width:10px; height: 10px;"></div> ${localize('Exit spot')} `;
            case 'end_time':
                return `<div style="${common_time_style} border-style: dashed;"></div> ${localize('End time')} `;
            case 'delay':
                return `<span class="chart-delay"> ${localize('Charting for this underlying is delayed')} </span>`;
            case 'payout_range':
                return `<span class="chart-payout-range"> ${localize('Payout range')} </span>`;
            default:
                return null;
        }
    };

    const setLabels = (chart_delayed, contract_type) => {
        // display a guide for clients to know how we are marking entry and exit spots
        txt = (chart_delayed ? getLabels('delay') : '') +
            getLabels('start_time') +
            (history ? getLabels('entry_spot') + getLabels('exit_spot') : '') +
            getLabels('end_time') +
            (isCallputspread(contract_type) ? getLabels('payout_range') : '');
    };

    const setChartOptions = (params) => {
        const display_decimals = params.decimals.split('.')[1].length || 3;
        chart_options = {
            chart: {
                backgroundColor: null, /* make background transparent */
                height         : Math.max(params.height, 450),
                renderTo       : params.el,
                animation      : false,
                marginLeft     : 30,
                marginRight    : params.marginRight || 30,
                events         : {
                    redraw: params.redrawHandler,
                },
            },
            title: {
                text : params.title,
                style: { fontSize: '16px' },
            },
            credits: { enabled: false },
            tooltip: {
                xDateFormat  : (params.is_jp_client ? '%Y/%m/%d, %H:%M:%S' : '%A, %b %e, %H:%M:%S GMT'),
                valueDecimals: display_decimals,
            },
            subtitle: {
                text   : txt,
                useHTML: true,
            },
            xAxis: {
                labels: { overflow: 'justify', format: '{value:%H:%M:%S}' },
            },
            yAxis: {
                opposite: false,
                labels  : {
                    align: 'left',
                    formatter() {
                        return addComma(this.value.toFixed(display_decimals));
                    },
                },
                maxPadding: 0.05,
                minPadding: 0.05,
            },
            series: [{
                type : params.type,
                name : params.title,
                data : params.data,
                // zones are used to display color of the line
                zones: [{
                    // make the line grey until it reaches entry time or start time if entry spot time is not yet known
                    value: params.entry_time,
                    color: '#ccc',
                }, {
                    // make the line default color until exit time is reached
                    value: params.exit_time,
                    color: '',
                }, {
                    // make the line grey again after trade ended
                    color: '#ccc',
                }],
                zoneAxis      : 'x',
                cropThreshold : Infinity,
                softThreshold : false,
                turboThreshold: Infinity,
                connectNulls  : true,
            }],
            exporting  : { enabled: false },
            plotOptions: {
                line: {
                    marker: { radius: 2, enabled: true },
                },
                candlestick: {
                    lineColor  : 'black',
                    color      : 'red',
                    upColor    : 'green',
                    upLineColor: 'black',
                    shadow     : true,
                },
            },
            rangeSelector: { enabled: false },
        };
        if (params.user_sold) {
            chart_options.series[0].zones.pop();
        }
    };

    const getHighchartOptions = is_jp_client => (
        {
            // use comma as separator instead of space
            lang  : { thousandsSep: ',' },
            global: {
                timezoneOffset: is_jp_client ? -9 * 60 : 0, // Converting chart time to JST.
            },
        }
    );

    const replaceExitLabelWithSell = (subtitle) => {
        const subtitle_length = subtitle.childNodes.length;
        const textnode        = document.createTextNode(` ${localize('Sell time')} `);
        for (let i = 0; i < subtitle_length; i++) {
            const item = subtitle.childNodes[i];
            if (/End time/.test(item.nodeValue)) {
                subtitle.replaceChild(textnode, item);
            }
        }
    };

    const getPlotlineOptions = (params, type) => {
        const is_plotx = type === 'x';
        const options  = {
            value    : params.value,
            id       : params.id || (is_plotx ? params.value : params.label),
            label    : { text: params.label || '' },
            color    : params.color || (is_plotx ? '#e98024' : 'green'),
            zIndex   : is_plotx ? 2 : 1,
            width    : params.width || 2,
            dashStyle: params.dashStyle || 'Solid',
        };

        if (is_plotx) {
            options.label.x = params.textLeft ? -15 : 5;
        } else {
            options.label.y = params.textBottom ? 15 : -5;
            options.label.align = 'center';
        }

        return options;
    };

    const showError = (type, message) => {
        $('#analysis_live_chart').html($('<p/>', { class: 'error-msg', text: (type === 'missing' ? localize('Ticks history returned an empty array.') : message) }));
    };

    const getMarkerObject = (type) => {
        const color = type === 'entry' ? 'white' : 'orange';
        return { fillColor: color, lineColor: 'orange', lineWidth: 3, radius: 4, states: { hover: { fillColor: color, lineColor: 'orange', lineWidth: 3, radius: 4 } } };
    };

    return {
        setLabels,
        setChartOptions,
        getHighchartOptions,
        replaceExitLabelWithSell,
        getPlotlineOptions,
        showError,
        getMarkerObject,
        getChartOptions: () => chart_options,
    };
})();

module.exports = HighchartUI;
<commit_msg>sort imports<commit_after>const isCallputspread = require('../callputspread').isCallputspread;
const addComma        = require('../../../common/currency').addComma;
const localize        = require('../../../../_common/localize').localize;

const HighchartUI = (() => {
    let common_time_style,
        common_spot_style,
        txt,
        chart_options;

    const initLabels = () => {
        common_time_style = 'margin-bottom: 3px; margin-left: 10px; height: 0; width: 20px; border: 0; border-bottom: 2px; border-color: #e98024; display: inline-block;';
        common_spot_style = 'margin-left: 10px; display: inline-block; border-radius: 6px;';
    };

    const getLabels = (option) => {
        if (!common_time_style || !common_spot_style) {
            initLabels();
        }
        switch (option) {
            case 'start_time':
                return `<div style="${common_time_style} border-style: solid;"></div> ${localize('Start time')} `;
            case 'entry_spot':
                return `<div style="${common_spot_style} border: 3px solid orange; width: 4px; height: 4px;"></div> ${localize('Entry spot')} `;
            case 'exit_spot':
                return `<div style="${common_spot_style} background-color: orange; width:10px; height: 10px;"></div> ${localize('Exit spot')} `;
            case 'end_time':
                return `<div style="${common_time_style} border-style: dashed;"></div> ${localize('End time')} `;
            case 'delay':
                return `<span class="chart-delay"> ${localize('Charting for this underlying is delayed')} </span>`;
            case 'payout_range':
                return `<span class="chart-payout-range"> ${localize('Payout range')} </span>`;
            default:
                return null;
        }
    };

    const setLabels = (chart_delayed, contract_type) => {
        // display a guide for clients to know how we are marking entry and exit spots
        txt = (chart_delayed ? getLabels('delay') : '') +
            getLabels('start_time') +
            (history ? getLabels('entry_spot') + getLabels('exit_spot') : '') +
            getLabels('end_time') +
            (isCallputspread(contract_type) ? getLabels('payout_range') : '');
    };

    const setChartOptions = (params) => {
        const display_decimals = params.decimals.split('.')[1].length || 3;
        chart_options = {
            chart: {
                backgroundColor: null, /* make background transparent */
                height         : Math.max(params.height, 450),
                renderTo       : params.el,
                animation      : false,
                marginLeft     : 30,
                marginRight    : params.marginRight || 30,
                events         : {
                    redraw: params.redrawHandler,
                },
            },
            title: {
                text : params.title,
                style: { fontSize: '16px' },
            },
            credits: { enabled: false },
            tooltip: {
                xDateFormat  : (params.is_jp_client ? '%Y/%m/%d, %H:%M:%S' : '%A, %b %e, %H:%M:%S GMT'),
                valueDecimals: display_decimals,
            },
            subtitle: {
                text   : txt,
                useHTML: true,
            },
            xAxis: {
                labels: { overflow: 'justify', format: '{value:%H:%M:%S}' },
            },
            yAxis: {
                opposite: false,
                labels  : {
                    align: 'left',
                    formatter() {
                        return addComma(this.value.toFixed(display_decimals));
                    },
                },
                maxPadding: 0.05,
                minPadding: 0.05,
            },
            series: [{
                type : params.type,
                name : params.title,
                data : params.data,
                // zones are used to display color of the line
                zones: [{
                    // make the line grey until it reaches entry time or start time if entry spot time is not yet known
                    value: params.entry_time,
                    color: '#ccc',
                }, {
                    // make the line default color until exit time is reached
                    value: params.exit_time,
                    color: '',
                }, {
                    // make the line grey again after trade ended
                    color: '#ccc',
                }],
                zoneAxis      : 'x',
                cropThreshold : Infinity,
                softThreshold : false,
                turboThreshold: Infinity,
                connectNulls  : true,
            }],
            exporting  : { enabled: false },
            plotOptions: {
                line: {
                    marker: { radius: 2, enabled: true },
                },
                candlestick: {
                    lineColor  : 'black',
                    color      : 'red',
                    upColor    : 'green',
                    upLineColor: 'black',
                    shadow     : true,
                },
            },
            rangeSelector: { enabled: false },
        };
        if (params.user_sold) {
            chart_options.series[0].zones.pop();
        }
    };

    const getHighchartOptions = is_jp_client => (
        {
            // use comma as separator instead of space
            lang  : { thousandsSep: ',' },
            global: {
                timezoneOffset: is_jp_client ? -9 * 60 : 0, // Converting chart time to JST.
            },
        }
    );

    const replaceExitLabelWithSell = (subtitle) => {
        const subtitle_length = subtitle.childNodes.length;
        const textnode        = document.createTextNode(` ${localize('Sell time')} `);
        for (let i = 0; i < subtitle_length; i++) {
            const item = subtitle.childNodes[i];
            if (/End time/.test(item.nodeValue)) {
                subtitle.replaceChild(textnode, item);
            }
        }
    };

    const getPlotlineOptions = (params, type) => {
        const is_plotx = type === 'x';
        const options  = {
            value    : params.value,
            id       : params.id || (is_plotx ? params.value : params.label),
            label    : { text: params.label || '' },
            color    : params.color || (is_plotx ? '#e98024' : 'green'),
            zIndex   : is_plotx ? 2 : 1,
            width    : params.width || 2,
            dashStyle: params.dashStyle || 'Solid',
        };

        if (is_plotx) {
            options.label.x = params.textLeft ? -15 : 5;
        } else {
            options.label.y = params.textBottom ? 15 : -5;
            options.label.align = 'center';
        }

        return options;
    };

    const showError = (type, message) => {
        $('#analysis_live_chart').html($('<p/>', { class: 'error-msg', text: (type === 'missing' ? localize('Ticks history returned an empty array.') : message) }));
    };

    const getMarkerObject = (type) => {
        const color = type === 'entry' ? 'white' : 'orange';
        return { fillColor: color, lineColor: 'orange', lineWidth: 3, radius: 4, states: { hover: { fillColor: color, lineColor: 'orange', lineWidth: 3, radius: 4 } } };
    };

    return {
        setLabels,
        setChartOptions,
        getHighchartOptions,
        replaceExitLabelWithSell,
        getPlotlineOptions,
        showError,
        getMarkerObject,
        getChartOptions: () => chart_options,
    };
})();

module.exports = HighchartUI;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'

import styles from './index.css'

const Tooltip = ({ children, content }) => (

      {content}

    {children}

)

Tooltip.propTypes = {
  children: PropTypes.any.isRequired,
  content: PropTypes.any.isRequired
}

export { Tooltip as default }
<commit_msg>feat(Tooltip): support a tagName prop<commit_after>import React, { PropTypes } from 'react'

import styles from './index.css'

const Tooltip = ({ children, content, tagName: Component = 'span' }) => (
  <Component className={styles.container}>

      {content}

    {children}
  </Component>
)

Tooltip.propTypes = {
  children: PropTypes.any.isRequired,
  content: PropTypes.any.isRequired,
  tagName: PropTypes.string
}

export { Tooltip as default }
<|endoftext|>


<commit_before>'use strict';

// ------- Imports -------------------------------------------------------------

const logger = require('winston');
const amqp = require('amqplib');

// ------- Internal imports ----------------------------------------------------

const BlinkConnectionError = require('../../../errors/BlinkConnectionError');

// ------- Class ---------------------------------------------------------------

class RabbitMQConnectionManager {
  constructor(amqpConfig, clientDescription = false, reconnectManager = false) {
    this.amqpConfig = amqpConfig;
    this.clientDescription = clientDescription;
    this.connection = false;
    this.channel = false;

    // Inject reconnect manager.
    this.reconnectManager = reconnectManager;

    // Expose function by binding it to object context.
    this.createActiveChannel = this.createActiveChannel.bind(this);
  }

  async connect() {
    if (!this.reconnectManager) {
      // No reconnection logic provided, just try once and return the result.
      return this.createActiveChannel();
    }

    // Manage automatic reconnect:
    // 1. Enable automatic reconnects on first connection.
    const result = this.reconnectManager.reconnect(this.createActiveChannel);
    if (!result) {
      // Even thought reconnect manager will try until it succeed,
      // it could receive an interruption signal to stop trying.
      // In this case, the result will be false.
      return false;
    }
    // 2. Enable automatic reconnects on channel or connection failures.
    // RabbitMQ is notorious for killing your channels for obvious reasons,
    // and we want the connection to be persistent.
    // Also, useful for living through RabbitMQ restarts.
    this.connection.on('error', (error) => {
      RabbitMQConnectionManager.logFailure(error);
    })
    this.channel.on('error', (error) => {
      RabbitMQConnectionManager.logFailure(error);
    })

    this.connection.on('close', () => {
      this.connection = false;
      this.channel = false;
      this.reconnectManager.reconnect(this.createActiveChannel)
    });
    this.channel.on('close', () => {
      // Todo: queue operations?
      this.channel = false;
      this.reconnectManager.reconnect(this.createActiveChannel)
    });
  }

  /**
   * Establish RabbitMQ connection.
   *
   * RabbitMQ connection consist of two parts:
   * - Persistent AMQP connection though TCP/IP
   * - Lightweight channels within the TCP connection
   *
   * Multiple channels are used when there's a need
   * to have multiple inependent connections to AMQP broker.
   *
   * Blink shouldn't need more than one RabbitMQ link, so only one channel
   * within one connection will be managed.
   *
   * @return {bool} Result
   */
  async createActiveChannel() {
    // Establish new RabbitMQ TCP/IP connection.
    let connection;
    try {
      connection = await this.establishTCPConnection();
    } catch (error) {
      RabbitMQConnectionManager.logFailure(error);
      return false;
    }
    // TODO: make sure we can mock that.
    this.connection = connection;

    // Create new communication channel within the connection.
    let channel;
    try {
      channel = await this.createChannelInTCPConnection();
    } catch (error) {
      RabbitMQConnectionManager.logFailure(error);
      return false;
    }

    RabbitMQConnectionManager.logSuccess(channel);
    this.channel = channel;
    return true;
  }

  async disconnect() {
    if (this.reconnectManager) {
      await this.reconnectManager.interrupt();
    }
    await this.channel.close();
    await this.connection.close();
    return true;
  }

  getActiveChannel() {
    return this.channel;
  }

  async establishTCPConnection() {
    // Create AMQP connection.
    let connection;
    try {
      connection = await amqp.connect(
        this.amqpConfig,
        this.getClientProperties(),
      );
    } catch (error) {
      // Will throw an error on malformed URI, network problems or other issues.
      // For now, just rethrow wrapped error.
      throw new BlinkConnectionError(`Connectiod failed: ${error}`);
    }

    // Just in case.
    if (!connection) {
      throw new BlinkConnectionError('Unexpected connection null pointer');
    }
    return connection;
  }

  async createChannelInTCPConnection() {
    let channel;
    try {
      // TODO: consider ConfirmChannel?
      channel = await this.connection.createChannel();
    } catch (error) {
      // May fail if there are no more channels available
      // (i.e., if there are already `channelMax` channels open).
      throw new BlinkConnectionError(`Channel creation failed: ${error}`);
    }

    // Just in case.
    if (!channel) {
      throw new BlinkConnectionError('Unexpected channel null pointer');
    }
    return channel;
  }

  getClientProperties() {
    // Additional connection properties to make debugging easier.
    let clientDescription;
    if (!this.clientDescription) {
      clientDescription = {
        name: 'Blink-AMQP',
        version: '0.0.0',
      };
    } else {
      clientDescription = this.clientDescription;
    }

    return {
      clientProperties: { app: clientDescription },
    };
  }

  toString() {
    if (!this.connection || !this.channel) {
      return 'Not connected';
    }
    // Todo: log actual amqpconfig?
    return JSON.stringify(RabbitMQConnectionManager.getNetworkData(this.getActiveChannel()));
  }

  static logSuccess(channel) {
    const networkData = RabbitMQConnectionManager.getNetworkData(channel);
    logger.debug('AMQP channel created', {
      code: 'amqp_channel_created',
      amqp_local: `${networkData.localAddress}:${networkData.localPort}`,
      amqp_remote: `${networkData.remoteAddress}:${networkData.remotePort}`,
      // TODO: dyno
    });
  }

  static logFailure(error) {
    logger.error(`AMQP channel failed: ${error.message}`, {
      code: 'amqp_channel_failed',
    });
  }

  static getNetworkData(channel) {
    // Instance of Duplex.
    const socket = channel.connection.stream;
    return {
      localAddress: socket.localAddress,
      localPort: socket.localPort,
      remoteAddress: socket.remoteAddress,
      remotePort: socket.remotePort,
    };
  }
}

// ------- Exports -------------------------------------------------------------

module.exports = RabbitMQConnectionManager;

// ------- End -----------------------------------------------------------------
<commit_msg>Basic channel/connection autorecovery, bug: reestablishes two channels<commit_after>'use strict';

// ------- Imports -------------------------------------------------------------

const logger = require('winston');
const amqp = require('amqplib');

// ------- Internal imports ----------------------------------------------------

const BlinkConnectionError = require('../../../errors/BlinkConnectionError');

// ------- Class ---------------------------------------------------------------

class RabbitMQConnectionManager {
  constructor(amqpConfig, clientDescription = false, reconnectManager = false) {
    this.amqpConfig = amqpConfig;
    this.clientDescription = clientDescription;
    this.connection = false;
    this.channel = false;

    // Inject reconnect manager.
    this.reconnectManager = reconnectManager;

    // Expose function by binding it to object context.
    this.createActiveChannel = this.createActiveChannel.bind(this);
  }

  async connect() {
    if (!this.reconnectManager) {
      // No reconnection logic provided, just try once and return the result.
      return this.createActiveChannel();
    }

    // Manage automatic reconnect:
    // 1. Enable automatic reconnects on first connection.
    const result = await this.reconnectManager.reconnect(this.createActiveChannel);
    if (!result) {
      // Even thought reconnect manager will try until it succeed,
      // it could receive an interruption signal to stop trying.
      // In this case, the result will be false.
      return false;
    }
    // 2. Enable automatic reconnects on channel or connection failures.
    // RabbitMQ is notorious for killing your channels for obvious reasons,
    // and we want the connection to be persistent.
    // Also, useful for living through RabbitMQ restarts.
    this.channel.on('error', (error) => {
      RabbitMQConnectionManager.logFailure(error);
    })
    this.connection.on('error', (error) => {
      RabbitMQConnectionManager.logFailure(error);
    })
    this.channel.on('close', () => {
      // Todo: queue operations?
      // this.channel = false;
      this.reconnectManager.reconnect(this.createActiveChannel)
      console.dir('channel closed', { colors: true, showHidden: true });
    });

    this.connection.on('close', () => {
      // this.connection = false;
      // this.channel = false;
      this.reconnectManager.reconnect(this.createActiveChannel)
      console.dir('connection closed', { colors: true, showHidden: true });
    });
  }

  /**
   * Establish RabbitMQ connection.
   *
   * RabbitMQ connection consist of two parts:
   * - Persistent AMQP connection though TCP/IP
   * - Lightweight channels within the TCP connection
   *
   * Multiple channels are used when there's a need
   * to have multiple inependent connections to AMQP broker.
   *
   * Blink shouldn't need more than one RabbitMQ link, so only one channel
   * within one connection will be managed.
   *
   * @return {bool} Result
   */
  async createActiveChannel() {
    // Establish new RabbitMQ TCP/IP connection.
    let connection;
    try {
      connection = await this.establishTCPConnection();
    } catch (error) {
      RabbitMQConnectionManager.logFailure(error);
      return false;
    }
    // TODO: make sure we can mock that.
    this.connection = connection;

    // Create new communication channel within the connection.
    let channel;
    try {
      channel = await this.createChannelInTCPConnection();
    } catch (error) {
      RabbitMQConnectionManager.logFailure(error);
      return false;
    }

    RabbitMQConnectionManager.logSuccess(channel);
    this.channel = channel;
    return true;
  }

  async disconnect() {
    if (this.reconnectManager) {
      await this.reconnectManager.interrupt();
    }
    await this.channel.close();
    await this.connection.close();
    return true;
  }

  getActiveChannel() {
    return this.channel;
  }

  async establishTCPConnection() {
    // Create AMQP connection.
    let connection;
    try {
      connection = await amqp.connect(
        this.amqpConfig,
        this.getClientProperties(),
      );
    } catch (error) {
      // Will throw an error on malformed URI, network problems or other issues.
      // For now, just rethrow wrapped error.
      throw new BlinkConnectionError(`Connectiod failed: ${error}`);
    }

    // Just in case.
    if (!connection) {
      throw new BlinkConnectionError('Unexpected connection null pointer');
    }
    return connection;
  }

  async createChannelInTCPConnection() {
    let channel;
    try {
      // TODO: consider ConfirmChannel?
      channel = await this.connection.createChannel();
    } catch (error) {
      // May fail if there are no more channels available
      // (i.e., if there are already `channelMax` channels open).
      throw new BlinkConnectionError(`Channel creation failed: ${error}`);
    }

    // Just in case.
    if (!channel) {
      throw new BlinkConnectionError('Unexpected channel null pointer');
    }
    return channel;
  }

  getClientProperties() {
    // Additional connection properties to make debugging easier.
    let clientDescription;
    if (!this.clientDescription) {
      clientDescription = {
        name: 'Blink-AMQP',
        version: '0.0.0',
      };
    } else {
      clientDescription = this.clientDescription;
    }

    return {
      clientProperties: { app: clientDescription },
    };
  }

  toString() {
    if (!this.connection || !this.channel) {
      return 'Not connected';
    }
    // Todo: log actual amqpconfig?
    return JSON.stringify(RabbitMQConnectionManager.getNetworkData(this.getActiveChannel()));
  }

  static logSuccess(channel) {
    const networkData = RabbitMQConnectionManager.getNetworkData(channel);
    logger.debug('AMQP channel created', {
      code: 'amqp_channel_created',
      amqp_local: `${networkData.localAddress}:${networkData.localPort}`,
      amqp_remote: `${networkData.remoteAddress}:${networkData.remotePort}`,
      // TODO: dyno
    });
  }

  static logFailure(error) {
    logger.error(`AMQP channel failed: ${error.message}`, {
      code: 'amqp_channel_failed',
    });
  }

  static getNetworkData(channel) {
    // Instance of Duplex.
    const socket = channel.connection.stream;
    return {
      localAddress: socket.localAddress,
      localPort: socket.localPort,
      remoteAddress: socket.remoteAddress,
      remotePort: socket.remotePort,
    };
  }
}

// ------- Exports -------------------------------------------------------------

module.exports = RabbitMQConnectionManager;

// ------- End -----------------------------------------------------------------
<|endoftext|>


<commit_before>// namespace
var MPLAY = MPLAY || {};

(function() {
	"use_strict";

	var textureList = [
		"/static/gnovel/res/textures/ui/BG_filter_syllabus.png",
		"/static/gnovel/res/textures/ui/phone.png",
		"/static/gnovel/res/textures/backgrounds/restaurant.png",
		"/static/gnovel/res/textures/ui/phone_inbox.png",
		"/static/gnovel/res/textures/backgrounds/restaurant scene with ryan.png",
		"/static/gnovel/res/textures/backgrounds/restaurant.png",
		"/static/gnovel/res/textures/wallet for bar.png",
		"/static/gnovel/res/textures/ui/speech bubble-indicator_wDots.png",
		"/static/gnovel/res/textures/char/sad ryan.png",

	];

	var resList = [
		"/static/gnovel/res/font/SFToontime.ttf",
		"/static/gnovel/res/font/SFToontimeBold.ttf",
		"/static/gnovel/res/font/SFToontimeBoldItalic.ttf",
	];

	MPLAY._getTextureList = function() {
		return textureList;
	};

	MPLAY._getResourceList = function() {
		return textureList;
	};

}());<commit_msg>res list does not return correct list<commit_after>// namespace
var MPLAY = MPLAY || {};

(function() {
	"use_strict";

	var textureList = [
		"/static/gnovel/res/textures/ui/BG_filter_syllabus.png",
		"/static/gnovel/res/textures/ui/phone.png",
		"/static/gnovel/res/textures/backgrounds/restaurant.png",
		"/static/gnovel/res/textures/ui/phone_inbox.png",
		"/static/gnovel/res/textures/backgrounds/restaurant scene with ryan.png",
		"/static/gnovel/res/textures/backgrounds/restaurant.png",
		"/static/gnovel/res/textures/wallet for bar.png",
		"/static/gnovel/res/textures/ui/speech bubble-indicator_wDots.png",
		"/static/gnovel/res/textures/char/sad ryan.png",

	];

	var resList = [
		"/static/gnovel/res/font/SFToontime.ttf",
		"/static/gnovel/res/font/SFToontimeBold.ttf",
		"/static/gnovel/res/font/SFToontimeBoldItalic.ttf",
	];

	MPLAY._getTextureList = function() {
		return textureList;
	};

	MPLAY._getResourceList = function() {
		return resList;
	};

}());<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import hamburgerSvg from './hamburger.svg'
import { media } from '../utils/style'

const Wrapper = styled.div`
    display: none;
    ${media.mobile`
        display: flex;
    `}
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    background-color: white;
    height: 50px;
    z-index: 2;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
`

const NavItem = styled.div`
    cursor: pointer;
`

const NavItemImg = styled.img`
    margin: 10px 20px;
    cursor: pointer;
`

class Navigation extends React.Component {

    render() {
        return (
            <Wrapper>
                <NavItem>
                    <a onClick={this.props.onClickMenu} >
                    <NavItemImg
                    src={hamburgerSvg} alt="menu" />
                    </a>
                </NavItem>
            </Wrapper>
        )
    }
}

Navigation.propTypes = {
    onClickMenu: PropTypes.func.isRequired,
}

export default Navigation
<commit_msg>revmoe a tag<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import hamburgerSvg from './hamburger.svg'
import { media } from '../utils/style'

const Wrapper = styled.div`
    display: none;
    ${media.mobile`
        display: flex;
    `}
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    background-color: white;
    height: 50px;
    z-index: 2;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
`

const NavItem = styled.div`
    cursor: pointer;
`

const NavItemImg = styled.img`
    margin: 10px 20px;
    cursor: pointer;
`

class Navigation extends React.Component {

    render() {
        return (
            <Wrapper>
                <NavItem onClick={this.props.onClickMenu}>
                    <NavItemImg
                    src={hamburgerSvg} alt="menu" />
                </NavItem>
            </Wrapper>
        )
    }
}

Navigation.propTypes = {
    onClickMenu: PropTypes.func.isRequired,
}

export default Navigation
<|endoftext|>


<commit_before>import React, { Component } from 'react';

class TodaysTodo extends Component {
  render(){
    return(

        <input name="todays-todo" type="checkbox" className="toggle"/>
        {this.props.todo.content}
        <button type="button" className="delete">X</button>

    );
  };
}

export default TodaysTodo;
<commit_msg>[02] completed 여부에 따라 completed 클래스를 추가할 때, 추가하지 않아야하는 경우에 false로 추가되는 것을 공백으로 수정합니다<commit_after>import React, { Component } from 'react';

class TodaysTodo extends Component {
  render(){
    return(

        <input name="todays-todo" type="checkbox" className="toggle"/>
        {this.props.todo.content}
        <button type="button" className="delete">X</button>

    );
  };
}

export default TodaysTodo;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import mqtt from 'mqtt';
import { BASE_TOPIC, METHOD_REGEX } from '../../constants';

import Room from '../Room';

import './App.css';

export default class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      showHeatMap: false,
      sensors: [
        { temperature: 20, position: 1, id: 14 },
        { temperature: 40, position: 15, id: 15 },
      ],
    };
  }

  publishMessage = (method, message) => {
    console.log(`[Sent] Method: ${method} | Message: ${message}`);
    this.client.publish(`${BASE_TOPIC}/${method}`, message);
  }

  updateSensors = (sensors, sensor) => {
    let isNewSensor = true;

    const updatedSensors = sensors.map((s) => {
      if (s.id === sensor.id) {
        isNewSensor = false;
        return sensor;
      }
      return s;
    });

    if (isNewSensor) {
      updatedSensors.push(sensor);
    }

    return updatedSensors;
  }

  handleMessage = (topic, message) => {
    // match method
    const method = topic.match(METHOD_REGEX)[1];
    const parsedMessage = JSON.parse(message);
    const { id } = parsedMessage;
    console.log(`[Received] Method: ${method} | Message:`, parsedMessage);

    switch (method) {
      // receive update from a sensor
      case 'update':
        const updatedSensors = this.updateSensors(this.state.sensors, parsedMessage);
        this.setState({ sensors: updatedSensors });
        break;
      // a new sensor requests to be registered
      case 'requestRegistration':
        this.publishMessage('acceptRegistration', id);
        break;
      default:
    }
  }

  handleShowHeatMapChange = (event) => {
    this.setState({showHeatMap: !this.state.showHeatMap});
  }

  componentDidMount() {
    this.client = mqtt.connect('mqtt://test.mosca.io');
    this.client.on('connect', () => {
      this.client.subscribe(`${BASE_TOPIC}/update`);
      this.client.subscribe(`${BASE_TOPIC}/requestRegistration`);
    });

    this.client.on('message', this.handleMessage);
  }

  render() {
    const { sensors, showHeatMap } = this.state;
    return (

          Show heatmap
          <input id="ShowHeatMap" type="checkbox" onChange={this.handleShowHeatMapChange} />

        <Room sensors={sensors} showHeatMap={showHeatMap} publishMessage={this.publishMessage}/>

    );
  }
}
<commit_msg>Remove test sensors<commit_after>import React, { Component } from 'react';
import mqtt from 'mqtt';
import { BASE_TOPIC, METHOD_REGEX } from '../../constants';

import Room from '../Room';

import './App.css';

export default class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      showHeatMap: false,
      sensors: [],
    };
  }

  publishMessage = (method, message) => {
    console.log(`[Sent] Method: ${method} | Message: ${message}`);
    this.client.publish(`${BASE_TOPIC}/${method}`, message);
  }

  updateSensors = (sensors, sensor) => {
    let isNewSensor = true;

    const updatedSensors = sensors.map((s) => {
      if (s.id === sensor.id) {
        isNewSensor = false;
        return sensor;
      }
      return s;
    });

    if (isNewSensor) {
      updatedSensors.push(sensor);
    }

    return updatedSensors;
  }

  handleMessage = (topic, message) => {
    // match method
    const method = topic.match(METHOD_REGEX)[1];
    const parsedMessage = JSON.parse(message);
    const { id } = parsedMessage;
    console.log(`[Received] Method: ${method} | Message:`, parsedMessage);

    switch (method) {
      // receive update from a sensor
      case 'update':
        const updatedSensors = this.updateSensors(this.state.sensors, parsedMessage);
        this.setState({ sensors: updatedSensors });
        break;
      // a new sensor requests to be registered
      case 'requestRegistration':
        this.publishMessage('acceptRegistration', id);
        break;
      default:
    }
  }

  handleShowHeatMapChange = (event) => {
    this.setState({showHeatMap: !this.state.showHeatMap});
  }

  componentDidMount() {
    this.client = mqtt.connect('mqtt://test.mosca.io');
    this.client.on('connect', () => {
      this.client.subscribe(`${BASE_TOPIC}/update`);
      this.client.subscribe(`${BASE_TOPIC}/requestRegistration`);
    });

    this.client.on('message', this.handleMessage);
  }

  render() {
    const { sensors, showHeatMap } = this.state;
    return (

          Show heatmap
          <input id="ShowHeatMap" type="checkbox" onChange={this.handleShowHeatMapChange} />

        <Room sensors={sensors} showHeatMap={showHeatMap} publishMessage={this.publishMessage}/>

    );
  }
}
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import * as FirebaseActions from '../firebaseFunctions';
import cookie from 'react-cookie';
import {Pie} from 'react-chartjs-2';

class Dashboard extends Component {

	constructor() {
		super();

		this.retrieveAuditHistory = this.retrieveAuditHistory.bind(this);
		this.renderAudit = this.renderAudit.bind(this);
		this.renderAuditHistory = this.renderAuditHistory.bind(this);
		this.retrieveCourseHistory = this.retrieveCourseHistory.bind(this);
		this.renderCourse = this.renderCourse.bind(this);
		this.renderCourseHistory = this.renderCourseHistory.bind(this);
		this.retrieveUserSpace = this.retrieveUserSpace.bind(this);
		this.updatePieChart = this.updatePieChart.bind(this);

		this.state = {
			courseHistory: [],
			courses: [],
			courseInitialized: true,
			auditHistory: [],
			audits: [],
			auditInitialized: true,
			chartClass: 'hide',
			chartData:{
				labels:[
					'Completed',
					'Uncompleted'
				],
				datasets:[
					{
						data: [0,0],
						backgroundColor:[
							'#0ef729',
							'#f92020'
						],
						hoverBackgroundColor:[
							'#0ef729',
							'#f92020'
						]
					}
				]
			},
			chartOptions:{
				mantainAspectRatio: false,
				responsive: true
			}
		};
	}

	componentDidMount(){
		const props = this.props;
		//if we're not signed in, then we need to re-auth, or redirect to the login page.
		props.checkAuth('Dashboard');
		this.retrieveUserSpace();
		this.updatePieChart();
	}

	retrieveUserSpace() {
		let outerThis = this;
		FirebaseActions.userSpace(cookie.load('TOKEN'), function(response){
			let userSpace = response.userSpace;
			if (userSpace.Courses.initialized) {
				let courseList = [];
				let courses = response.userSpace.Courses;
				for (let course in courses) {
					if (courses.hasOwnProperty(course) && course !== 'initialized') {
						courseList.push(courses[course]);
					}
				}
				outerThis.setState({
					courses: courseList,
				});
				outerThis.retrieveCourseHistory();
			} else {
				outerThis.setState({
					courseInitialized: userSpace.Courses.initialized
				});
			}
			if (userSpace.Audits.initialized) {
				let auditsList = [];
				let audits = response.userSpace.Audits;
				for (let audit in audits) {
					if (audits.hasOwnProperty(audit) && audit !== 'initialized') {
						audits[audit].name = audit;
						auditsList.push(audits[audit]);
					}
				}
				outerThis.setState({
					audits: auditsList,
				});
				outerThis.retrieveAuditHistory();
			} else {
				outerThis.setState({
					auditInitialized: response.userSpace.Audits.initialized
				});
			}
		});
	}

	retrieveAuditHistory() {
		if (this.state.auditInitialized) {
			let auditList = [];
			let maxHist = 3;
			let hist = 0;
			for (let audit in this.state.audits) {
				if (this.state.audits.hasOwnProperty(audit) && hist < maxHist) {
					auditList.push(this.renderAudit(this.state.audits[audit]));
					hist ++;
				}
			}
			this.setState({
				auditHistory: auditList,
			});
		}
	}

	renderAudit(audit) {
		const auditInfo = (

{audit.name}

		);
		return auditInfo;
	}

	// This only starts the request for now, it does not get a response
	runAudit() {
		let auditRequest = new Request('/run/audit', {method: 'POST', credentials: 'same-origin'});
		fetch(auditRequest).then((response) => response.json()).then((response) => {
			console.log('The audit is donion-rings', response);
			if (response.Success) {
				window.location.href=response.auditLink;
			}
		});
	}

	renderAuditHistory() {
		if (this.state.auditInitialized) {
			let temp = this.state.auditHistory.slice();
			if (this.state.auditHistory) {
				temp.push(<button key="btn" className="btn" onClick={this.runAudit} style={{marginTop:'15px'}}>Run Another Audit</button>);
			}
			const exists = (

Your most recent audit

						{this.state.auditHistory.length ? temp : '...' }

			);
			return exists;
		} else {
			const notExists = (

You have not run any audits yet!

					<button className="btn" onClick={this.runAudit}>Run Audit</button>

			);
			return notExists;
		}
	}

	retrieveCourseHistory() {
		if (this.state.courseInitialized) {
			let courseList = [];
			let maxHist = 3;
			let hist = 0;
			for (let course in this.state.courses) {
				if (this.state.courses.hasOwnProperty(course) && hist < maxHist) {
					courseList.push(this.renderCourse(this.state.courses[course]));
					hist ++;
				}
			}
			this.setState({
				courseHistory: courseList,
			});
		}
	}

	renderCourse(course) {
		const courseInfo = (

{course.name}

		);
		return courseInfo;
	}

	renderCourseHistory() {
		if (this.state.courseInitialized) {
			const exists = (

Your most recent courses

						{this.state.courseHistory.length ? this.state.courseHistory : '...' }

			);
			return exists;
		} else {
			const notExists = (

You have not taken any courses yet!

					Add Courses

			);
			return notExists;
		}
	}

	updatePieChart(){
		let oldChartData = this.state.chartData;
		let dashboardRef = this;
		FirebaseActions.getCreditsTaken(cookie.load('TOKEN'), function(credsTaken){
			FirebaseActions.getTotalCredits(function(credsTotal){
				let credsRemaining = credsTotal - credsTaken;
				oldChartData.datasets[0].data[0] = credsTaken;
				if(credsRemaining<0){
					oldChartData.datasets[0].data[1] = 0;
				}else{
					oldChartData.datasets[0].data[1] = credsRemaining;
				}
				dashboardRef.setState({
					chartClass: '',
					chartData: oldChartData
				});

			});
		});
	}

	render() {
		return (

Overall Degree Completion

										<Pie data={this.state.chartData} options={this.state.chartOptions} redraw/>

Courses

									{this.renderCourseHistory()}

Audits

									{this.renderAuditHistory()}

);
	}
}

Dashboard.contextTypes = {
	router: React.PropTypes.object
};

Dashboard.PropTypes = {
	checkAuth: React.PropTypes.func
};

export default Dashboard;
<commit_msg>fixed dashboard mobile issue<commit_after>import React, {Component} from 'react';
import * as FirebaseActions from '../firebaseFunctions';
import cookie from 'react-cookie';
import {Pie} from 'react-chartjs-2';

class Dashboard extends Component {

	constructor() {
		super();

		this.retrieveAuditHistory = this.retrieveAuditHistory.bind(this);
		this.renderAudit = this.renderAudit.bind(this);
		this.renderAuditHistory = this.renderAuditHistory.bind(this);
		this.retrieveCourseHistory = this.retrieveCourseHistory.bind(this);
		this.renderCourse = this.renderCourse.bind(this);
		this.renderCourseHistory = this.renderCourseHistory.bind(this);
		this.retrieveUserSpace = this.retrieveUserSpace.bind(this);
		this.updatePieChart = this.updatePieChart.bind(this);

		this.state = {
			courseHistory: [],
			courses: [],
			courseInitialized: true,
			auditHistory: [],
			audits: [],
			auditInitialized: true,
			chartClass: 'hide',
			chartData:{
				labels:[
					'Completed',
					'Uncompleted'
				],
				datasets:[
					{
						data: [0,0],
						backgroundColor:[
							'#0ef729',
							'#f92020'
						],
						hoverBackgroundColor:[
							'#0ef729',
							'#f92020'
						]
					}
				]
			},
			chartOptions:{
				mantainAspectRatio: false,
				responsive: true
			}
		};
	}

	componentDidMount(){
		const props = this.props;
		//if we're not signed in, then we need to re-auth, or redirect to the login page.
		props.checkAuth('Dashboard');
		this.retrieveUserSpace();
		this.updatePieChart();
	}

	retrieveUserSpace() {
		let outerThis = this;
		FirebaseActions.userSpace(cookie.load('TOKEN'), function(response){
			let userSpace = response.userSpace;
			if (userSpace.Courses.initialized) {
				let courseList = [];
				let courses = response.userSpace.Courses;
				for (let course in courses) {
					if (courses.hasOwnProperty(course) && course !== 'initialized') {
						courseList.push(courses[course]);
					}
				}
				outerThis.setState({
					courses: courseList,
				});
				outerThis.retrieveCourseHistory();
			} else {
				outerThis.setState({
					courseInitialized: userSpace.Courses.initialized
				});
			}
			if (userSpace.Audits.initialized) {
				let auditsList = [];
				let audits = response.userSpace.Audits;
				for (let audit in audits) {
					if (audits.hasOwnProperty(audit) && audit !== 'initialized') {
						audits[audit].name = audit;
						auditsList.push(audits[audit]);
					}
				}
				outerThis.setState({
					audits: auditsList,
				});
				outerThis.retrieveAuditHistory();
			} else {
				outerThis.setState({
					auditInitialized: response.userSpace.Audits.initialized
				});
			}
		});
	}

	retrieveAuditHistory() {
		if (this.state.auditInitialized) {
			let auditList = [];
			let maxHist = 3;
			let hist = 0;
			for (let audit in this.state.audits) {
				if (this.state.audits.hasOwnProperty(audit) && hist < maxHist) {
					auditList.push(this.renderAudit(this.state.audits[audit]));
					hist ++;
				}
			}
			this.setState({
				auditHistory: auditList,
			});
		}
	}

	renderAudit(audit) {
		const auditInfo = (

{audit.name}

		);
		return auditInfo;
	}

	// This only starts the request for now, it does not get a response
	runAudit() {
		let auditRequest = new Request('/run/audit', {method: 'POST', credentials: 'same-origin'});
		fetch(auditRequest).then((response) => response.json()).then((response) => {
			console.log('The audit is donion-rings', response);
			if (response.Success) {
				window.location.href=response.auditLink;
			}
		});
	}

	renderAuditHistory() {
		if (this.state.auditInitialized) {
			let temp = this.state.auditHistory.slice();
			if (this.state.auditHistory) {
				temp.push(<button key="btn" className="btn" onClick={this.runAudit} style={{marginTop:'15px'}}>Run Another Audit</button>);
			}
			const exists = (

Your most recent audit

						{this.state.auditHistory.length ? temp : '...' }

			);
			return exists;
		} else {
			const notExists = (

You have not run any audits yet!

					<button className="btn" onClick={this.runAudit}>Run Audit</button>

			);
			return notExists;
		}
	}

	retrieveCourseHistory() {
		if (this.state.courseInitialized) {
			let courseList = [];
			let maxHist = 3;
			let hist = 0;
			for (let course in this.state.courses) {
				if (this.state.courses.hasOwnProperty(course) && hist < maxHist) {
					courseList.push(this.renderCourse(this.state.courses[course]));
					hist ++;
				}
			}
			this.setState({
				courseHistory: courseList,
			});
		}
	}

	renderCourse(course) {
		const courseInfo = (

{course.name}

		);
		return courseInfo;
	}

	renderCourseHistory() {
		if (this.state.courseInitialized) {
			const exists = (

Your most recent courses

						{this.state.courseHistory.length ? this.state.courseHistory : '...' }

			);
			return exists;
		} else {
			const notExists = (

You have not taken any courses yet!

					Add Courses

			);
			return notExists;
		}
	}

	updatePieChart(){
		let oldChartData = this.state.chartData;
		let dashboardRef = this;
		FirebaseActions.getCreditsTaken(cookie.load('TOKEN'), function(credsTaken){
			FirebaseActions.getTotalCredits(function(credsTotal){
				let credsRemaining = credsTotal - credsTaken;
				oldChartData.datasets[0].data[0] = credsTaken;
				if(credsRemaining<0){
					oldChartData.datasets[0].data[1] = 0;
				}else{
					oldChartData.datasets[0].data[1] = credsRemaining;
				}
				dashboardRef.setState({
					chartClass: '',
					chartData: oldChartData
				});

			});
		});
	}

	render() {
		return (

Overall Degree Completion

										<Pie data={this.state.chartData} options={this.state.chartOptions} redraw/>

Courses

								{this.renderCourseHistory()}

Audits

								{this.renderAuditHistory()}

);
	}
}

Dashboard.contextTypes = {
	router: React.PropTypes.object
};

Dashboard.PropTypes = {
	checkAuth: React.PropTypes.func
};

export default Dashboard;
<|endoftext|>


<commit_before>// @flow
import React from 'react';
import { paper, Point } from 'paper';

import type { SeatsMap } from '../reducers/types';
import type { SeatData } from '../types';

import { toSeatData } from '../conversions';
import Seat from './Seat';

type Props = {
  seats: SeatsMap,

  onSelectSeat: (seat: SeatData) => void,
}

export default class Floorplan extends React.Component {

  props: Props;
  view: paper.view;

  seats: Seat[];
  update: () => void;

  constructor(props: Props) {
    super(props);
    this.update = this.update.bind(this);
  }

  componentDidMount() {
    const canvas = this.refs.canvas;

    // Setup canvas
    canvas.width = 960;
    canvas.height = 540;
    paper.setup(canvas);

    // view bindings
    this.view = paper.view;
    this.view.autoUpdate = false;
    this.view.onMouseDrag = (e) => this.translateCamera(e);

    // HARDCODED: center the view for our mocked seats
    this.view.center = new Point(1175, 371);

    // Render the seats based on the loaded data.
    this.seats = [];
    for (const id in this.props.seats) {
      const seatdata = this.props.seats[id];
      const seat = new Seat(seatdata.x, seatdata.y);

      seat.onSelect = () => this.handleSelectSeat(id);

      this.seats.push(seat);
    }

    this.update();
  }

  translateCamera(event: Object) {
    const delta = event.delta;

    // smoothen transition
    delta.length /= 2;

    // inverts the scroll from the drag direction
    this.view.center = this.view.center.add(new Point(-delta.x, -delta.y));

    event.preventDefault()
  }

  update() {
    // hide seats that are not in the view
    this.seats.forEach((seat) => {
      seat.visible = seat.position.isInside(this.view.bounds);
    });

    this.view.update();

    requestAnimationFrame(this.update);
  }

  handleSelectSeat(id: string) {
    const seatState = this.props.seats[id];
    this.props.onSelectSeat(toSeatData(seatState));
  }

  render() {
    return (
      <canvas ref="canvas" />
    );
  }
}
<commit_msg>Remove the constant update loop.<commit_after>// @flow
import React from 'react';
import { paper, Point } from 'paper';

import type { SeatsMap } from '../reducers/types';
import type { SeatData } from '../types';

import { toSeatData } from '../conversions';
import Seat from './Seat';

type Props = {
  seats: SeatsMap,

  onSelectSeat: (seat: SeatData) => void,
}

export default class Floorplan extends React.Component {

  props: Props;
  view: paper.view;

  seats: Seat[];
  update: () => void;

  constructor(props: Props) {
    super(props);
    this.update = this.update.bind(this);
  }

  componentDidMount() {
    const canvas = this.refs.canvas;

    // Setup canvas
    canvas.width = 960;
    canvas.height = 540;
    paper.setup(canvas);

    // view bindings
    this.view = paper.view;
    this.view.autoUpdate = false;
    this.view.onMouseDrag = (e) => this.translateCamera(e);

    // HARDCODED: center the view for our mocked seats
    this.view.center = new Point(1175, 371);

    // Render the seats based on the loaded data.
    this.seats = [];
    for (const id in this.props.seats) {
      const seatdata = this.props.seats[id];
      const seat = new Seat(seatdata.x, seatdata.y);

      seat.onSelect = () => this.handleSelectSeat(id);

      this.seats.push(seat);
    }

    this.update();
  }

  translateCamera(event: Object) {
    const delta = event.delta;

    // smoothen transition
    delta.length /= 2;

    // inverts the scroll from the drag direction
    this.view.center = this.view.center.add(new Point(-delta.x, -delta.y));

    event.preventDefault()
    this.update();
  }

  update() {
    requestAnimationFrame(() => {
      // hide seats that are not in the view
      this.seats.forEach((seat) => {
        seat.visible = seat.position.isInside(this.view.bounds);
      });

      this.view.update();
    });
  }

  handleSelectSeat(id: string) {
    const seatState = this.props.seats[id];
    this.props.onSelectSeat(toSeatData(seatState));
  }

  render() {
    return (
      <canvas ref="canvas" />
    );
  }
}
<|endoftext|>


<commit_before>import React, { Children, cloneElement, Component } from 'react'
import PropTypes from 'prop-types'

import Alert from './Alert'
import Submitted from './Submitted'

import { includes } from 'lodash'

export default class Form extends Component {
  static propTypes = {
    action: PropTypes.any,
    children: PropTypes.any,
    id: PropTypes.string,
    register: PropTypes.func,
    store: PropTypes.object,
    submit: PropTypes.func,
    submittedElement: PropTypes.any,
  }

  state = {
    exited: this.props.store[this.props.id] && this.props.store[this.props.id].submitted,
  }

  componentDidMount() {
    this.props.register(this.props.id)
  }

  componentWillReceiveProps(nextProps) {
    const form = nextProps.store[nextProps.id]
    if (form && form.submitted && !this.state.exited) {
      this.exitAnimation()
    }
  }

  exitAnimation() {
    TweenMax.to(this.form, 0.5, {
      opacity: 0,
      delay: 1,
      onComplete: () => {
        this.setState({ exited: true })
      },
    })
  }

  inputs = []
  static htmlTags =['input', 'div', 'h1', 'h2', 'h3', 'p']

  onSubmit = (event) => {
    event.preventDefault()
    let valid = true
    this.inputs.forEach(input => {
      if (!input.isValid()) valid = false
    })
    if (valid) {
      if (this.props.action) this.form.submit()
      else this.props.submit(this.props.id, this.props.store[this.props.id])
    }
  }

  get children() {
    const { children, id } = this.props
    return Children.map(children, (child, key) => {
      if (Form.htmlTags.indexOf(child.type) > -1) return child
      return cloneElement(child, { formId: id, key, ref: this.refInputs })
    })
  }

  refInputs = (c) => {
    if (c && c.getWrappedInstance) {
      const instance = c.getWrappedInstance()
      if (instance.isInput && !includes(this.inputs, instance)) this.inputs.push(instance)
    }
  }

  render() {
    const { id, store, submittedElement } = this.props
    const { exited } = this.state
    return (

        {store[id] && store[id].error && <Alert>{store[id].error.ErrorText}</Alert>}
        {!exited && <form
          acceptCharset='UTF-8'
          action={this.props.action}
          encType='multipart/form-data'
          method='post'
          noValidate
          onSubmit={this.onSubmit}
          ref={c => { this.form = c }}
        >
          {this.children}
        </form>}
        {exited && submittedElement && <Submitted>{submittedElement}</Submitted>}

    )
  }
}
<commit_msg>add id and name to form<commit_after>import React, { Children, cloneElement, Component } from 'react'
import PropTypes from 'prop-types'

import Alert from './Alert'
import Submitted from './Submitted'

import { includes } from 'lodash'

export default class Form extends Component {
  static propTypes = {
    action: PropTypes.any,
    children: PropTypes.any,
    id: PropTypes.string,
    register: PropTypes.func,
    store: PropTypes.object,
    submit: PropTypes.func,
    submittedElement: PropTypes.any,
  }

  state = {
    exited: this.props.store[this.props.id] && this.props.store[this.props.id].submitted,
  }

  componentDidMount() {
    this.props.register(this.props.id)
  }

  componentWillReceiveProps(nextProps) {
    const form = nextProps.store[nextProps.id]
    if (form && form.submitted && !this.state.exited) {
      this.exitAnimation()
    }
  }

  exitAnimation() {
    TweenMax.to(this.form, 0.5, {
      opacity: 0,
      delay: 1,
      onComplete: () => {
        this.setState({ exited: true })
      },
    })
  }

  inputs = []
  static htmlTags =['input', 'div', 'h1', 'h2', 'h3', 'p']

  onSubmit = (event) => {
    event.preventDefault()
    let valid = true
    this.inputs.forEach(input => {
      if (!input.isValid()) valid = false
    })
    if (valid) {
      if (this.props.action) this.form.submit()
      else this.props.submit(this.props.id, this.props.store[this.props.id])
    }
  }

  get children() {
    const { children, id } = this.props
    return Children.map(children, (child, key) => {
      if (Form.htmlTags.indexOf(child.type) > -1) return child
      return cloneElement(child, { formId: id, key, ref: this.refInputs })
    })
  }

  refInputs = (c) => {
    if (c && c.getWrappedInstance) {
      const instance = c.getWrappedInstance()
      if (instance.isInput && !includes(this.inputs, instance)) this.inputs.push(instance)
    }
  }

  render() {
    const { id, store, submittedElement } = this.props
    const { exited } = this.state
    return (

        {store[id] && store[id].error && <Alert>{store[id].error.ErrorText}</Alert>}
        {!exited && <form
          acceptCharset='UTF-8'
          action={this.props.action}
          encType='multipart/form-data'
          id={this.props.id}
          method='post'
          name={this.props.id}
          noValidate
          onSubmit={this.onSubmit}
          ref={c => { this.form = c }}
        >
          {this.children}
        </form>}
        {exited && submittedElement && <Submitted>{submittedElement}</Submitted>}

    )
  }
}
<|endoftext|>


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

import { iconClass } from './util';
import { prefixable } from '../../decorators';

export const Icon = (props) => {
  const { sprite, icon, title, circle, background, size, div, prefix } = props;
  const backgroundClass = !background ? `icon-${sprite}-${iconClass(sprite, icon)}` : `icon-${background}`;

  const sldsClasses = [
    { icon_container: true },
    { 'icon_container--circle': circle },
    { [`${backgroundClass}`]: true },
  ];

  const WrapperElement = div ? 'div' : 'span';

  return (
    <WrapperElement className={prefix(sldsClasses, props)} title={title}>
      <IconSVG sprite={sprite} icon={icon} size={size} />
      {title}
    </WrapperElement>
  );
};

Icon.propTypes = {
  /**
   * the prefix function from the prefixable HOC
   */
  prefix: React.PropTypes.func,
  sprite: React.PropTypes.oneOf(['action', 'custom', 'doctype', 'standard', 'utility']).isRequired,
  icon: React.PropTypes.string.isRequired,
  title: React.PropTypes.string,
  circle: React.PropTypes.bool,
  div: React.PropTypes.bool,
  background: React.PropTypes.string,
  size: React.PropTypes.oneOf(['x-small', 'small', 'medium', 'large']),
};

export default prefixable(Icon);
<commit_msg>Fix support of custom background on icons<commit_after>import React from 'react';
import IconSVG from './IconSVG';

import { iconClass } from './util';
import { prefixable } from '../../decorators';

export const Icon = (props) => {
  const { sprite, icon, title, circle, background, size, div, prefix } = props;
  const backgroundClass = !background ? `icon-${sprite}-${iconClass(sprite, icon)}` : `icon-${background}`;

  const sldsClasses = [
    { icon_container: true },
    { 'icon_container--circle': circle },
    { [`${backgroundClass}`]: true },
  ];

  const WrapperElement = div ? 'div' : 'span';

  return (
    <WrapperElement className={prefix(sldsClasses, props)} title={title}>
      <IconSVG sprite={sprite} icon={icon} size={size} background={background} />
      {title}
    </WrapperElement>
  );
};

Icon.propTypes = {
  /**
   * the prefix function from the prefixable HOC
   */
  prefix: React.PropTypes.func,
  sprite: React.PropTypes.oneOf(['action', 'custom', 'doctype', 'standard', 'utility']).isRequired,
  icon: React.PropTypes.string.isRequired,
  title: React.PropTypes.string,
  circle: React.PropTypes.bool,
  div: React.PropTypes.bool,
  background: React.PropTypes.string,
  size: React.PropTypes.oneOf(['x-small', 'small', 'medium', 'large']),
};

export default prefixable(Icon);
<|endoftext|>


<commit_before>import React from 'react';

import ViewLayer from './ViewLayer';

export default class LayerList extends React.Component {
  constructor(props) {
    super(props);
    this.ids = [];
  }
  componentDidMount() {
    console.log(this.ids);
  }
  render() {
    return this.props.viewLayerDataList.map(data => {
      const {id} = data;
      delete data.id;
      return (
        <ViewLayer
          ref={ref => this.ids.push({id, ViewLayer: ref})}
          key={id}
          {...data}
        />
      );
    });
  }
}
<commit_msg>Revert "LayerList が任意の ViewLayer にアクセスできるようにした。"<commit_after>import React from 'react';

import ViewLayer from './ViewLayer';

export default function LayerList({viewLayerDataList}) {
  return viewLayerDataList.map(data => {
    const {id} = data;
    delete data.id;
    return <ViewLayer key={id} {...data} />;
  });
}
<|endoftext|>


<commit_before>import React from 'react';
import { Card, CardActions, CardHeader, CardText } from 'material-ui/Card';
import FormatQuote from 'material-ui/svg-icons/editor/format-quote';
import FlatButton from 'material-ui/FlatButton';

const cardStyles = {
  maxWidth: 900,
  margin: '0 auto'
};

const headerStyles = {
  textAlign: 'right',
  margin: '0 auto'
};

const QuoteCard = props => (
  <Card style={cardStyles}>
    <CardText>
      <FormatQuote />
      {props.text}
    </CardText>
    <CardHeader
      title={`- ${props.author}`}
      style={headerStyles}
    />
    <CardActions>
      <FlatButton
        primary
        label="Tweet"
        onTouchTap={props.onTweetClick}
      />
      <FlatButton
        secondary
        label="Show another"
        onTouchTap={props.onGetNewQuote}
      />
    </CardActions>
  </Card>
);

QuoteCard.propTypes = {
  text: React.PropTypes.string,
  author: React.PropTypes.string,
  onTweetClick: React.PropTypes.func,
  onGetNewQuote: React.PropTypes.func
};

export default QuoteCard;
<commit_msg>Experimenting with card look<commit_after>import React from 'react';
import { Card, CardActions, CardHeader, CardText } from 'material-ui/Card';
import FormatQuote from 'material-ui/svg-icons/editor/format-quote';
import RaisedButton from 'material-ui/RaisedButton';

const cardStyles = {
  maxWidth: 600,
  margin: '0 auto'
};

const headerStyles = {
  margin: '0 auto'
};

const QuoteCard = props => (
  <Card style={cardStyles}>
    <CardHeader
      title={`Quote by ${props.author}`}
      style={headerStyles}
    />
    <CardText>
      <FormatQuote />
      {props.text}
    </CardText>
    <CardActions>
      <RaisedButton
        primary
        label="Tweet"
        onTouchTap={props.onTweetClick}
      />
      <RaisedButton
        label="Show another"
        onTouchTap={props.onGetNewQuote}
      />
    </CardActions>
  </Card>
);

QuoteCard.propTypes = {
  text: React.PropTypes.string,
  author: React.PropTypes.string,
  onTweetClick: React.PropTypes.func,
  onGetNewQuote: React.PropTypes.func
};

export default QuoteCard;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { combineReducers } from 'redux';
import { connect } from 'react-redux';
import createBrowserHistory from 'history/createBrowserHistory';
import { IntlProvider } from 'react-intl';
import queryString from 'query-string';
import { ApolloProvider } from 'react-apollo';

import initialReducers from '../../initialReducers';
import enhanceReducer from '../../enhanceReducer';
import createApolloClient from '../../createApolloClient';
import { setSinglePlugin, setBindings, setOkapiToken } from '../../okapiActions';
import { loadTranslations, checkOkapiSession } from '../../loginServices';
import { getQueryResourceKey } from '../../locationService';
import Stripes from '../../Stripes';
import RootWithIntl from '../../RootWithIntl';

import './Root.css';

import { modules } from 'stripes-config'; // eslint-disable-line

class Root extends Component {
  constructor(...args) {
    super(...args);
    this.reducers = { ...initialReducers };
    this.epics = {};
    this.withOkapi = this.props.okapi.withoutOkapi !== true;

    const appModule = modules.app.find(m => window.location.pathname.startsWith(m.route) && m.queryResource);

    if (appModule) {
      this.queryResourceStateKey = getQueryResourceKey(appModule);
    }
  }

  getChildContext() {
    return { addReducer: this.addReducer, addEpic: this.addEpic };
  }

  componentWillMount() {
    const { okapi, store, locale } = this.props;
    if (this.withOkapi) checkOkapiSession(okapi.url, store, okapi.tenant);
    // TODO: remove this after we load locale and translations at start from a public endpoint
    loadTranslations(store, locale);
  }

  shouldComponentUpdate(nextProps) {
    return !this.withOkapi || nextProps.okapiReady;
  }

  addReducer = (key, reducer) => {
    if (this.queryResourceStateKey === key) {
      const originalReducer = reducer;
      const initialQueryObject = queryString.parse(window.location.search);
      // eslint-disable-next-line no-param-reassign
      reducer = (state = Object.values(initialQueryObject).length ? initialQueryObject : undefined, action) => originalReducer(state, action);
    }

    if (this.reducers[key] === undefined) {
      this.reducers[key] = reducer;
      this.props.store.replaceReducer(enhanceReducer(combineReducers({ ...this.reducers })));
      return true;
    }
    return false;
  }

  addEpic = (key, epic) => {
    if (this.epics[key] === undefined) {
      this.epics[key] = epic;
      this.props.epics.add(epic);
      return true;
    }
    return false;
  }

  render() {
    const { logger, store, epics, config, okapi, actionNames, token, disableAuth, currentUser, currentPerms, locale, plugins, bindings, discovery, translations, history } = this.props;

    if (!translations) return (<div />);

    const stripes = new Stripes({
      logger,
      store,
      epics,
      config,
      okapi,
      withOkapi: this.withOkapi,
      setToken: (val) => { store.dispatch(setOkapiToken(val)); },
      actionNames,
      locale,
      setLocale: (val) => { loadTranslations(store, val); },
      plugins: plugins || {},
      setSinglePlugin: (key, value) => { store.dispatch(setSinglePlugin(key, value)); },
      bindings,
      setBindings: (val) => { store.dispatch(setBindings(val)); },
      discovery,
      user: {
        user: currentUser,
        perms: currentPerms,
      },
      connect(X) { return X; },
    });

    return (
      <ApolloProvider client={createApolloClient(okapi)}>
        <IntlProvider locale={locale} key={locale} messages={translations}>
          <RootWithIntl stripes={stripes} token={token} disableAuth={disableAuth} history={history} />
        </IntlProvider>
      </ApolloProvider>
    );
  }
}

Root.childContextTypes = {
  addReducer: PropTypes.func,
  addEpic: PropTypes.func,
};

Root.propTypes = {
  store: PropTypes.shape({
    subscribe: PropTypes.func.isRequired,
    dispatch: PropTypes.func.isRequired,
    getState: PropTypes.func.isRequired,
    replaceReducer: PropTypes.func.isRequired,
  }),
  token: PropTypes.string,
  disableAuth: PropTypes.bool.isRequired,
  logger: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
  currentPerms: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  currentUser: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  epics: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  locale: PropTypes.string,
  translations: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  plugins: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  bindings: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  config: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  okapi: PropTypes.shape({
    url: PropTypes.string,
    tenant: PropTypes.string,
    withoutOkapi: PropTypes.bool,
  }),
  actionNames: PropTypes.arrayOf(
    PropTypes.string,
  ).isRequired,
  discovery: PropTypes.shape({
    modules: PropTypes.object, // eslint-disable-line react/forbid-prop-types
    interfaces: PropTypes.object, // eslint-disable-line react/forbid-prop-types
    isFinished: PropTypes.bool,
  }),
  history: PropTypes.shape({
    length: PropTypes.number.isRequired,
    action: PropTypes.string.isRequired,
    push: PropTypes.func.isRequired,
    replace: PropTypes.func.isRequired,
  }),
  okapiReady: PropTypes.bool,
};

Root.defaultProps = {
  history: createBrowserHistory(),
  // TODO: remove after locale is accessible from a global config / public url
  locale: 'en-US',
  okapiReady: false,
};

function mapStateToProps(state) {
  return {
    token: state.okapi.token,
    currentUser: state.okapi.currentUser,
    currentPerms: state.okapi.currentPerms,
    locale: state.okapi.locale,
    translations: state.okapi.translations,
    plugins: state.okapi.plugins,
    bindings: state.okapi.bindings,
    discovery: state.discovery,
    okapiReady: state.okapi.okapiReady,
    okapi: state.okapi,
  };
}

export default connect(mapStateToProps)(Root);
<commit_msg>Cleanup<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { combineReducers } from 'redux';
import { connect } from 'react-redux';
import createBrowserHistory from 'history/createBrowserHistory';
import { IntlProvider } from 'react-intl';
import queryString from 'query-string';
import { ApolloProvider } from 'react-apollo';

import initialReducers from '../../initialReducers';
import enhanceReducer from '../../enhanceReducer';
import createApolloClient from '../../createApolloClient';
import { setSinglePlugin, setBindings, setOkapiToken } from '../../okapiActions';
import { loadTranslations, checkOkapiSession } from '../../loginServices';
import { getQueryResourceKey } from '../../locationService';
import Stripes from '../../Stripes';
import RootWithIntl from '../../RootWithIntl';

import './Root.css';

import { modules } from 'stripes-config'; // eslint-disable-line

class Root extends Component {
  constructor(...args) {
    super(...args);
    this.reducers = { ...initialReducers };
    this.epics = {};
    this.withOkapi = this.props.okapi.withoutOkapi !== true;

    const appModule = modules.app.find(m => window.location.pathname.startsWith(m.route) && m.queryResource);
    this.queryResourceStateKey = (appModule) ? getQueryResourceKey(appModule) : null;
  }

  getChildContext() {
    return { addReducer: this.addReducer, addEpic: this.addEpic };
  }

  componentWillMount() {
    const { okapi, store, locale } = this.props;
    if (this.withOkapi) checkOkapiSession(okapi.url, store, okapi.tenant);
    // TODO: remove this after we load locale and translations at start from a public endpoint
    loadTranslations(store, locale);
  }

  shouldComponentUpdate(nextProps) {
    return !this.withOkapi || nextProps.okapiReady;
  }

  addReducer = (key, reducer) => {
    if (this.queryResourceStateKey === key) {
      const originalReducer = reducer;
      const initialQueryObject = queryString.parse(window.location.search);
      // eslint-disable-next-line no-param-reassign
      reducer = (state = Object.values(initialQueryObject).length ? initialQueryObject : undefined, action) => originalReducer(state, action);
    }

    if (this.reducers[key] === undefined) {
      this.reducers[key] = reducer;
      this.props.store.replaceReducer(enhanceReducer(combineReducers({ ...this.reducers })));
      return true;
    }
    return false;
  }

  addEpic = (key, epic) => {
    if (this.epics[key] === undefined) {
      this.epics[key] = epic;
      this.props.epics.add(epic);
      return true;
    }
    return false;
  }

  render() {
    const { logger, store, epics, config, okapi, actionNames, token, disableAuth, currentUser, currentPerms, locale, plugins, bindings, discovery, translations, history } = this.props;

    if (!translations) return (<div />);

    const stripes = new Stripes({
      logger,
      store,
      epics,
      config,
      okapi,
      withOkapi: this.withOkapi,
      setToken: (val) => { store.dispatch(setOkapiToken(val)); },
      actionNames,
      locale,
      setLocale: (val) => { loadTranslations(store, val); },
      plugins: plugins || {},
      setSinglePlugin: (key, value) => { store.dispatch(setSinglePlugin(key, value)); },
      bindings,
      setBindings: (val) => { store.dispatch(setBindings(val)); },
      discovery,
      user: {
        user: currentUser,
        perms: currentPerms,
      },
      connect(X) { return X; },
    });

    return (
      <ApolloProvider client={createApolloClient(okapi)}>
        <IntlProvider locale={locale} key={locale} messages={translations}>
          <RootWithIntl stripes={stripes} token={token} disableAuth={disableAuth} history={history} />
        </IntlProvider>
      </ApolloProvider>
    );
  }
}

Root.childContextTypes = {
  addReducer: PropTypes.func,
  addEpic: PropTypes.func,
};

Root.propTypes = {
  store: PropTypes.shape({
    subscribe: PropTypes.func.isRequired,
    dispatch: PropTypes.func.isRequired,
    getState: PropTypes.func.isRequired,
    replaceReducer: PropTypes.func.isRequired,
  }),
  token: PropTypes.string,
  disableAuth: PropTypes.bool.isRequired,
  logger: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
  currentPerms: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  currentUser: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  epics: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  locale: PropTypes.string,
  translations: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  plugins: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  bindings: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  config: PropTypes.object, // eslint-disable-line react/forbid-prop-types
  okapi: PropTypes.shape({
    url: PropTypes.string,
    tenant: PropTypes.string,
    withoutOkapi: PropTypes.bool,
  }),
  actionNames: PropTypes.arrayOf(
    PropTypes.string,
  ).isRequired,
  discovery: PropTypes.shape({
    modules: PropTypes.object, // eslint-disable-line react/forbid-prop-types
    interfaces: PropTypes.object, // eslint-disable-line react/forbid-prop-types
    isFinished: PropTypes.bool,
  }),
  history: PropTypes.shape({
    length: PropTypes.number.isRequired,
    action: PropTypes.string.isRequired,
    push: PropTypes.func.isRequired,
    replace: PropTypes.func.isRequired,
  }),
  okapiReady: PropTypes.bool,
};

Root.defaultProps = {
  history: createBrowserHistory(),
  // TODO: remove after locale is accessible from a global config / public url
  locale: 'en-US',
  okapiReady: false,
};

function mapStateToProps(state) {
  return {
    token: state.okapi.token,
    currentUser: state.okapi.currentUser,
    currentPerms: state.okapi.currentPerms,
    locale: state.okapi.locale,
    translations: state.okapi.translations,
    plugins: state.okapi.plugins,
    bindings: state.okapi.bindings,
    discovery: state.discovery,
    okapiReady: state.okapi.okapiReady,
    okapi: state.okapi,
  };
}

export default connect(mapStateToProps)(Root);
<|endoftext|>


<commit_before>import React from 'react'
import { withState } from 'recompose'
import { Form, Row, Input, Button, AllCenter } from './styled'

const enhance = withState('passVisibility', 'setVisibility', false)

export default enhance(({ onSub, passVisibility, setVisibility }) => {
  let name
  let pass

  const visibility = passVisibility ? 'visible' : 'hidden'
  const opacity = passVisibility ? 1 : 0
  const inputHandler = (e) => {
    if (e.target.value === process.env.SUPA_NAME !== passVisibility) {
      setVisibility(prev => !prev)
    }
  }

  const clickHandler = (e) => {
    e.preventDefault()
    onSub(name.value, pass.value)
  }

  return (
    <AllCenter>
      <Form>
        <Row visible>Представьтесь:</Row>
        <Row visible>
          <Input
            type='name'
            placeholder='Имя'
            onInput={inputHandler}
            innerRef={nm => { name = nm }}
          />
        </Row>
        <Row visible>
          <Input
            type='password'
            innerRef={ps => { pass = ps }}
            style={{visibility, opacity}}
          />
          <Button onClick={clickHandler}>
            Далее
          </Button>
        </Row>
      </Form>
    </AllCenter>
  )
})
<commit_msg>fix sending empty name<commit_after>import React from 'react'
import { withState } from 'recompose'
import { Form, Row, Input, Button, AllCenter } from './styled'

const enhance = withState('passVisibility', 'setVisibility', false)

export default enhance(({ onSub, passVisibility, setVisibility }) => {
  let name
  let pass

  const visibility = passVisibility ? 'visible' : 'hidden'
  const opacity = passVisibility ? 1 : 0
  const inputHandler = (e) => {
    if (e.target.value === process.env.SUPA_NAME !== passVisibility) {
      setVisibility(prev => !prev)
    }
  }

  const clickHandler = (e) => {
    e.preventDefault()
    const nm = name.value.trim()
    const ps = pass.value.trim()

    if (!nm || passVisibility && !ps) return

    onSub(name.value, pass.value)
  }

  return (
    <AllCenter>
      <Form>
        <Row visible>Представьтесь:</Row>
        <Row visible>
          <Input
            type='name'
            placeholder='Имя'
            onInput={inputHandler}
            innerRef={nm => { name = nm }}
          />
        </Row>
        <Row visible>
          <Input
            type='password'
            innerRef={ps => { pass = ps }}
            style={{visibility, opacity}}
          />
          <Button onClick={clickHandler}>
            Далее
          </Button>
        </Row>
      </Form>
    </AllCenter>
  )
})
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import cx from 'classnames';
import { events } from '../utils';
import { getViewport } from '../utils/utils';
import MenuItem from './MenuItem.js';
import theme from './theme.css';

const POSITION = {
  AUTO: 'auto',
  STATIC: 'static',
  TOP_LEFT: 'top-left',
  TOP_RIGHT: 'top-right',
  BOTTOM_LEFT: 'bottom-left',
  BOTTOM_RIGHT: 'bottom-right',
};

class Menu extends PureComponent {
  state = {};

  componentDidMount() {
    const { width, height } = this.menuNode.getBoundingClientRect();
    this.setState({ width, height });

    const { position } = this.props;
    if (position === POSITION.AUTO) {
      this.setState({ position: this.calculatePosition() });
    }
  }

  static getDerivedStateFromProps(props, state) {
    const newStateSlice = {};

    if (props.active !== state.active) {
      newStateSlice.active = props.active;
    }

    if (props.position !== state.position) {
      newStateSlice.position = props.position;
    }

    if (newStateSlice.active || newStateSlice.position) {
      return newStateSlice;
    }

    return null;
  }

  componentDidUpdate(prevState) {
    if (prevState.active && !this.state.active) {
      this.hide();
    }

    if (!prevState.active && this.state.active) {
      this.show();
    }

    if (prevState.position !== this.state.position && this.state.position === POSITION.AUTO) {
      this.setState({ position: this.calculatePosition() });
    }

    const { width, height } = this.menuNode.getBoundingClientRect();
    if (prevState.width !== width || prevState.height !== height) {
      this.setState({ width, height }); // eslint-disable-line
    }
  }

  show() {
    const { onShow } = this.props;

    if (onShow) {
      onShow();
    }

    this.setState({ active: true });

    this.addEvents();
  }

  hide() {
    const { onHide } = this.props;

    if (onHide) {
      onHide();
    }

    this.setState({ active: false });

    this.removeEvents();
  }

  componentWillUnmount() {
    if (this.state.active) {
      this.removeEvents();
    }
  }

  addEvents() {
    events.addEventsToDocument({
      click: this.handleDocumentClick,
      touchstart: this.handleDocumentClick,
    });
  }

  removeEvents() {
    events.removeEventsFromDocument({
      click: this.handleDocumentClick,
      touchstart: this.handleDocumentClick,
    });
  }

  handleDocumentClick = event => {
    if (this.state.active && !events.targetIsDescendant(event, ReactDOM.findDOMNode(this))) {
      this.hide();
    }
  };

  handleSelect = (item, event) => {
    const { onSelect } = this.props;
    const { value, onClick } = item.props;

    if (onSelect) {
      onSelect(value);
    }

    if (onClick) {
      event.persist();
      onClick(event);
    }

    this.hide();
  };

  calculatePosition() {
    const parentNode = ReactDOM.findDOMNode(this).parentNode;

    if (!parentNode) {
      return;
    }

    const { top, left, height, width } = parentNode.getBoundingClientRect();
    const { height: vh, width: vw } = getViewport();

    const toTop = top < vh / 2 - height / 2;
    const toLeft = left < vw / 2 - width / 2;

    return `${toTop ? 'top' : 'bottom'}${toLeft ? 'Left' : 'Right'}`;
  }

  getRootStyle() {
    const { width, height, position } = this.state;

    if (position !== POSITION.STATIC) {
      return { width, height };
    }
  }

  getMenuStyle() {
    const { active } = this.state;

    if (active) {
      return this.getActiveMenuStyle();
    }

    return this.getMenuStyleByPosition();
  }

  getActiveMenuStyle() {
    const { width, height } = this.state;
    return { clip: `rect(0 ${width}px ${height}px 0)` };
  }

  getMenuStyleByPosition() {
    const { width, height, position } = this.state;

    switch (position) {
      case POSITION.TOP_RIGHT:
        return { clip: `rect(0 ${width}px 0 ${width}px)` };
      case POSITION.BOTTOM_RIGHT:
        return { clip: `rect(${height}px ${width}px ${height}px ${width}px)` };
      case POSITION.BOTTOM_LEFT:
        return { clip: `rect(${height}px 0 ${height}px 0)` };
      case POSITION.TOP_LEFT:
        return { clip: 'rect(0 0 0 0)' };
      default:
        return {};
    }
  }

  getItems() {
    const { children, selectable, selected } = this.props;

    // Because React Hot Loader creates proxied versions of your components,
    // comparing reference types of elements won't work
    // https://github.com/gaearon/react-hot-loader/blob/master/docs/Known%20Limitations.md#checking-element-types
    const MenuItemType = <MenuItem />.type;

    return React.Children.map(children, item => {
      if (!item) {
        return item;
      }

      if (item.type === MenuItemType) {
        return React.cloneElement(item, {
          selected: typeof item.props.value !== 'undefined' && selectable && item.props.value === selected,
          onClick: this.handleSelect.bind(this, item),
        });
      } else {
        return React.cloneElement(item);
      }
    });
  }

  render() {
    const { width, height, active, position } = this.state;
    const { className, outline, ...others } = this.props;

    const classNames = cx(
      theme['menu'],
      theme[position],
      {
        [theme['active']]: active,
      },
      className,
    );

    return (

        {outline ?
 : null}

 {
            this.menuNode = node;
          }}
          className={theme['menu-inner']}
          style={this.getMenuStyle()}
        >
          {this.getItems()}

    );
  }
}

Menu.propTypes = {
  active: PropTypes.bool,
  children: PropTypes.node,
  className: PropTypes.string,
  onHide: PropTypes.func,
  onSelect: PropTypes.func,
  onShow: PropTypes.func,
  outline: PropTypes.bool,
  position: PropTypes.oneOf(Object.keys(POSITION).map(key => POSITION[key])),
  selectable: PropTypes.bool,
  selected: PropTypes.any,
};

Menu.defaultProps = {
  active: false,
  outline: true,
  position: POSITION.STATIC,
  selectable: true,
};

export default Menu;
<commit_msg>Menu: Add createRef<commit_after>import React, { createRef, PureComponent } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import cx from 'classnames';
import { events } from '../utils';
import { getViewport } from '../utils/utils';
import MenuItem from './MenuItem.js';
import theme from './theme.css';

const POSITION = {
  AUTO: 'auto',
  STATIC: 'static',
  TOP_LEFT: 'top-left',
  TOP_RIGHT: 'top-right',
  BOTTOM_LEFT: 'bottom-left',
  BOTTOM_RIGHT: 'bottom-right',
};

class Menu extends PureComponent {
  state = {};
  menuNode = createRef();

  componentDidMount() {
    const { width, height } = this.menuNode.getBoundingClientRect();
    this.setState({ width, height });

    const { position } = this.props;
    if (position === POSITION.AUTO) {
      this.setState({ position: this.calculatePosition() });
    }
  }

  static getDerivedStateFromProps(props, state) {
    const newStateSlice = {};

    if (props.active !== state.active) {
      newStateSlice.active = props.active;
    }

    if (props.position !== state.position) {
      newStateSlice.position = props.position;
    }

    if (newStateSlice.active || newStateSlice.position) {
      return newStateSlice;
    }

    return null;
  }

  componentDidUpdate(prevState) {
    if (prevState.active && !this.state.active) {
      this.hide();
    }

    if (!prevState.active && this.state.active) {
      this.show();
    }

    if (prevState.position !== this.state.position && this.state.position === POSITION.AUTO) {
      this.setState({ position: this.calculatePosition() });
    }

    const { width, height } = this.menuNode.getBoundingClientRect();
    if (prevState.width !== width || prevState.height !== height) {
      this.setState({ width, height }); // eslint-disable-line
    }
  }

  show() {
    const { onShow } = this.props;

    if (onShow) {
      onShow();
    }

    this.setState({ active: true });

    this.addEvents();
  }

  hide() {
    const { onHide } = this.props;

    if (onHide) {
      onHide();
    }

    this.setState({ active: false });

    this.removeEvents();
  }

  componentWillUnmount() {
    if (this.state.active) {
      this.removeEvents();
    }
  }

  addEvents() {
    events.addEventsToDocument({
      click: this.handleDocumentClick,
      touchstart: this.handleDocumentClick,
    });
  }

  removeEvents() {
    events.removeEventsFromDocument({
      click: this.handleDocumentClick,
      touchstart: this.handleDocumentClick,
    });
  }

  handleDocumentClick = event => {
    if (this.state.active && !events.targetIsDescendant(event, ReactDOM.findDOMNode(this))) {
      this.hide();
    }
  };

  handleSelect = (item, event) => {
    const { onSelect } = this.props;
    const { value, onClick } = item.props;

    if (onSelect) {
      onSelect(value);
    }

    if (onClick) {
      event.persist();
      onClick(event);
    }

    this.hide();
  };

  calculatePosition() {
    const parentNode = ReactDOM.findDOMNode(this).parentNode;

    if (!parentNode) {
      return;
    }

    const { top, left, height, width } = parentNode.getBoundingClientRect();
    const { height: vh, width: vw } = getViewport();

    const toTop = top < vh / 2 - height / 2;
    const toLeft = left < vw / 2 - width / 2;

    return `${toTop ? 'top' : 'bottom'}${toLeft ? 'Left' : 'Right'}`;
  }

  getRootStyle() {
    const { width, height, position } = this.state;

    if (position !== POSITION.STATIC) {
      return { width, height };
    }
  }

  getMenuStyle() {
    const { active } = this.state;

    if (active) {
      return this.getActiveMenuStyle();
    }

    return this.getMenuStyleByPosition();
  }

  getActiveMenuStyle() {
    const { width, height } = this.state;
    return { clip: `rect(0 ${width}px ${height}px 0)` };
  }

  getMenuStyleByPosition() {
    const { width, height, position } = this.state;

    switch (position) {
      case POSITION.TOP_RIGHT:
        return { clip: `rect(0 ${width}px 0 ${width}px)` };
      case POSITION.BOTTOM_RIGHT:
        return { clip: `rect(${height}px ${width}px ${height}px ${width}px)` };
      case POSITION.BOTTOM_LEFT:
        return { clip: `rect(${height}px 0 ${height}px 0)` };
      case POSITION.TOP_LEFT:
        return { clip: 'rect(0 0 0 0)' };
      default:
        return {};
    }
  }

  getItems() {
    const { children, selectable, selected } = this.props;

    // Because React Hot Loader creates proxied versions of your components,
    // comparing reference types of elements won't work
    // https://github.com/gaearon/react-hot-loader/blob/master/docs/Known%20Limitations.md#checking-element-types
    const MenuItemType = <MenuItem />.type;

    return React.Children.map(children, item => {
      if (!item) {
        return item;
      }

      if (item.type === MenuItemType) {
        return React.cloneElement(item, {
          selected: typeof item.props.value !== 'undefined' && selectable && item.props.value === selected,
          onClick: this.handleSelect.bind(this, item),
        });
      } else {
        return React.cloneElement(item);
      }
    });
  }

  render() {
    const { width, height, active, position } = this.state;
    const { className, outline, ...others } = this.props;

    const classNames = cx(
      theme['menu'],
      theme[position],
      {
        [theme['active']]: active,
      },
      className,
    );

    return (

        {outline ?
 : null}

          {this.getItems()}

    );
  }
}

Menu.propTypes = {
  active: PropTypes.bool,
  children: PropTypes.node,
  className: PropTypes.string,
  onHide: PropTypes.func,
  onSelect: PropTypes.func,
  onShow: PropTypes.func,
  outline: PropTypes.bool,
  position: PropTypes.oneOf(Object.keys(POSITION).map(key => POSITION[key])),
  selectable: PropTypes.bool,
  selected: PropTypes.any,
};

Menu.defaultProps = {
  active: false,
  outline: true,
  position: POSITION.STATIC,
  selectable: true,
};

export default Menu;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

class PostsNew extends Component {
  render() {
    return (
      <form>
        <Field
          name="title"
          component={}
        />
      </form>
    );
  }
}

export default reduxForm({
  form: 'PostsNewForm'
})(PostsNew);
<commit_msg>Created title inut field!<commit_after>import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

class PostsNew extends Component {
  renderTitleField(field) {
    return (
      <div>
        <input
        type="text"
          {...field.input}
        />
      </div>
    );
  }

  render() {
    return (
      <form>
        <Field
          name="title"
          component={this.renderTitleField}
        />
      </form>
    );
  }
}

export default reduxForm({
  form: 'PostsNewForm'
})(PostsNew);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

class PostsNew extends Component {
    renderField(field) {
        return (

                {field.label}
                <input
                    className="form-control"
                    type="text"
                    {...field.input}
                />
                {field.meta.error}

        );
    }

    onSubmit(values) {
        console.log(values);
    }

    render() {
        const { handleSubmit } = this.props;

        return (
            <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
                <Field
                    label="Title for Post"
                    name="title"
                    component={this.renderField}
                />
                <Field
                    label="Categories"
                    name="categories"
                    component={this.renderField}
                />
                <Field
                    label="Post Content"
                    name="content"
                    component={this.renderField}
                />
                <button type="submit" className="btn btn-primary">Submit</button>
            </form>
        );
    }
}

function validate(values) {
    const errors = {};

    // validate the inputs from 'values'
    if (!values.title) {
        errors.title = "Enter a title!";
    }
    if (!values.categories) {
        errors.categories = "Enter some categories";
    }
    if (!values.content) {
        errors.content = "Enter some content please";
    }
    // If error is empty, the form is fine to submit
    // If error has any properties, redux form assumes form is invalid
    return errors;
}

export default reduxForm({
    validate,
    form: 'PostsNewForm'
})(PostsNew);

<commit_msg>validation rebuild<commit_after>import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';

class PostsNew extends Component {
    renderField(field) {
        return (

                {field.label}
                <input
                    className="form-control"
                    type="text"
                    {...field.input}
                />
                {field.meta.touched ? field.meta.error : ''}

        );
    }

    onSubmit(values) {
        console.log(values);
    }

    render() {
        const { handleSubmit } = this.props;

        return (
            <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
                <Field
                    label="Title for Post"
                    name="title"
                    component={this.renderField}
                />
                <Field
                    label="Categories"
                    name="categories"
                    component={this.renderField}
                />
                <Field
                    label="Post Content"
                    name="content"
                    component={this.renderField}
                />
                <button type="submit" className="btn btn-primary">Submit</button>
            </form>
        );
    }
}

function validate(values) {
    const errors = {};

    // validate the inputs from 'values'
    if (!values.title) {
        errors.title = "Enter a title!";
    }
    if (!values.categories) {
        errors.categories = "Enter some categories";
    }
    if (!values.content) {
        errors.content = "Enter some content please";
    }
    // If error is empty, the form is fine to submit
    // If error has any properties, redux form assumes form is invalid
    return errors;
}

export default reduxForm({
    validate,
    form: 'PostsNewForm'
})(PostsNew);

<|endoftext|>