<commit_before>
import p5 from 'p5';
import { Generator } from './simplexNoise';
import dat from 'dat-gui';

/*
 * Flyby Render - Illusion of motion and flying over a simplex landscape
 */

/* eslint-disable */
const sketch = function (p) {
  var generator;
  generator = new Generator(10);
  // setting screen vars
  var width = 640;
  var height = 640;
  var width_half = width / 2;
  var height_half = height / 2;
  var grid;
  var spacing = ~~(width / grid);
  var spacer = 0;
  // setting items for render
  var time = 0;
  var timeNoise = 0;
  var iteration = 0.5;
  var strength;
  var speed = 10;
  var shaderType;
  var radius = 10;
  // setting color vars
  var r = 0;
  var g = 0;
  var b = 0;
  var op = 255;
  var colorset = [0, 0, 0];
  // setting items for movement
  var timeout = false;
  var waveSpeed = 0.0005;
  var zOffset = 0;
  var offsetX = 0;
  var offsetY = 0;
  var zoom = -50;
  var camX = width_half;
  var camY = height_half;
  var tempX = width_half;
  var tempY = height_half;
  var thisX = width_half;
  var thisY = height_half;
  var lastHigh = 0;
  // building arrays
  var vertices = new Array(spacing);
  for (var i = 0; i < spacing; i++) {
    vertices[i] = new Array(spacing * 2);
  }

  // p5.js setup function
  p.setup = function() {
    p.createCanvas(640, 640, p.WEBGL);
    p.frameRate(60);
      // above prevents clicks from happening outside of the canvas.
      // .mousePressed(() => {isPressed = true;})
      // .mouseReleased(() => {isPressed = false;});

    var fov = 60 / 180 * p.PI;
    var cameraZ = height_half / p.tan(fov/2.0);
    p.perspective(60 / 180 * p.PI, width/height, cameraZ * 0.1, cameraZ * 10);
    p.lighting();
  // simplex noise function
  };

  p.setOptions = function(options) {
    speed = options.speed / 10;
    iteration = options.iteration / 100;
    waveSpeed = options.waveSpeed / 10000;

    shaderType = options.shaderType;
    strength = options.strength;
  };

  p.setResolution = function(options) {
    grid = options.resolution || grid;
    spacing = ~~(width / grid);
    vertices = new Array(spacing);
    for (var i = 0; i < spacing; i++) {
      vertices[i] = new Array(spacing);
    }
  };

  p.draw = function() {
    // advance time and tick draw loop for time segment
    var size = ~~(width / spacing);
    var length = ~~(size * 1.25);
    spacer = spacer + speed;
    if (spacer > length) {
      // the time phase of the noise wave moves
      // once the cubes moved one space
      time += 1;
      spacer = 0;
    }

    p.generateMesh();
    p.viewPort();

    // move to center to start drawing grid
    p.translate(-width_half, -height, 200);

    for (var j = 0; j < spacing * 2; j++) {
      for (var i = 0; i < spacing; i++) {
        // generate noise values and shader colors
        var noiseValue = (vertices[i][j].n) * 0.3;
        var colorset = p.shader(vertices[i][j].n, i, j);
        if (vertices[i][j].n > lastHigh && j % 20 == 0) {
          lastHigh = vertices[i][j].n;
        }
        // push and move 3D object into place
        p.push();
        p.translate(i * size, j * length - spacer, -noiseValue * 2);
        p.ambientMaterial(colorset.r, colorset.g, colorset.b, colorset.op);
        p.box(size, length, 50);
        p.pop();
      }
    }
  };

  p.generateMesh = function() {
    timeNoise += 1;
    const timeStop = time * iteration;
    for (var j = 0; j < spacing * 2; j++) {
      for (var i = 0; i < spacing; i++) {
        var nPoint = Math.abs(
          generator.simplex3(iteration * i,
            iteration * j + timeStop, timeNoise * waveSpeed)
          ) * strength;
        var zVector = nPoint * 10;
        vertices[i][j] = {
          n: zVector
        };
      }
    }
  };

  p.pauseChange = function() {
    timeout = true;
    setTimeout(() => {
      timeout = false;
    }, 6000);
  };

  p.viewPort = function() {
  // set viewport, background, and lighting
    p.background(0,0,0);
    // move into position to draw grid
    p.translate((width / 2) - (spacing * grid / 2), -100, zoom);
    p.checkForChange();
    p.moveVectors();
    p.rotateX(90 + camY);
    p.rotateZ(camX);
  };

  p.checkForChange = function() {
    if (p.random(1,255) > 252 && !timeout) {
      tempX = width_half - (width - p.random(1, width * 2)) * .8;
      p.pauseChange();
    }
    if (p.random(1,255) > 250 && !timeout) {
      tempY = height_half - (lastHigh / 8) - (55 - p.random(1, 120));
      p.pauseChange();
    }
  };

  p.moveVectors = function(){
    thisX = thisX - (thisX - tempX) * 0.006;
    thisY = thisY - (thisY - tempY) * 0.006;
    camX = (width_half - thisX) * 0.006;
    camY = (height_half - thisY) * 0.008;
  };

  p.mouseWheel = function(event) {
    //move the square according to the vertical scroll amount
    zoom += event.delta;
    //uncomment to block page scrolling
    return false;
  };

  p.lighting = function()  {
    p.directionalLight(250, 250, 250, 255, 1, 0, -1);
    p.directionalLight(160, 160, 160, 255, -1, 1, 0);
    p.directionalLight(160, 160, 160, 255, 0, -1, 1);
  };

  p.shader = function(noise, i, j){
    switch(shaderType) {
      case 'java':
        // java render color mode
        b = Math.cos(noise * Math.PI / 180 + (time * 0.2)) * 255;
        r = 255 - b;
        // Math.sin(1 + noise * Math.PI / 180 - (time * 0.01)) * 255;
        g = Math.cos(2 - noise * 2 * Math.PI / 180) * 255;
        op = 255;
        break;
      case 'larvel':
        // original render color mode
        r = Math.cos(noise * 1.5 * Math.PI / 180 - (time * 0.01)) * 255;
        b = Math.sin(r * 0.15 * Math.PI / 180 + (time * 0.05)) * 255;
        g = 255 - ~~(r * j * i) / 255;
        op = 255;
        break;
      case 'octal':
        // octal render color mode - red and cyan
        const m = Math.cos(noise * Math.PI / 180);
        const o = Math.sin(noise * 4 * Math.PI / 180);
        r = ~~(m * 230);
        b = ~~(o * 230);
        g = 0;
        op = 255;
  			break;
      case 'offset':
        // offset - three waves of render color
        b = Math.cos(noise * 3 * Math.PI / 180 + (j * 0.01)) * 255;
        g = Math.sin(i *  Math.PI / grid + (time * 0.01)) * 255;
        r = Math.cos(j * Math.PI / grid + (time * 0.009)) * 255;
        op = 255;
        break;
      case 'rainbow':
        // rainbow render color mode
        var mult = 0.004;
        r = ~~(255 - 255 * (1 - Math.sin((noise * mult) * j)) / 2);
        g = ~~(255 - 255 * (1 + Math.cos((noise * mult) * i)) / 2);
        b = Math.cos(noise * 5 * Math.PI / 180 - (time * 0.03)) * 255;
        op = Math.abs(((noise * 255) - 0) / (255 - 0)) / 2.5;
  			break;
      case 'hashing':
        // original render color mode
        r = Math.cos(noise * 2.5 * Math.PI / 180 - (time * 0.01)) * 255;
        b = r;
        g = b;
        op = 255;
        break;

      case 'default':
        // original render color mode
        r = 255 - Math.cos(noise * Math.PI / 180) * 255;
        g = r;
        b = g;
        op = r;
        break;
      }
    return {
      r,
      g,
      b,
      op
    };
  };
  // end of sketch
};

/** Processing p5.js Sketch Definition          **/

/* eslint-enable */
/** Parent Render Class */
export default class Render {
  constructor(element) {
    // Screen Set Up //
    this.element = element;
    this.myp5 = undefined;
    // run function //
    this.setup();
  }
  /* eslint new-cap: 0 */
  setup = () => {
    this.myp5 = new p5(sketch, this.element);
    this.createGUI();
  };
  setOptions = (options) => {
    this.myp5.setOptions(options);
  };
  setResolution = (options) => {
    this.myp5.setResolution(options);
  };
  createGUI = () => {
    const viewSize = window.innerWidth || document.documentElement.clientWidth;
    this.options = {
      iteration: 3.5,
      strength: 40,
      resolution: viewSize < 640 ? 65 : 35,
      speed: 160,
      waveSpeed: 20,
      shaderType: 'larvel',
    };
    this.gui = new dat.GUI();
    const folderRender = this.gui.addFolder('Render Options');
    folderRender.add(this.options, 'iteration', 0, 10).step(0.1)
      .onFinishChange((value) => {
        this.options.iteration = value;
        this.setOptions(this.options);
      });
    folderRender.add(this.options, 'strength', 1, 50).step(1)
      .onFinishChange((value) => {
        this.options.strength = value;
        this.setOptions(this.options);
      });
    folderRender.add(this.options, 'speed', 1, 1000).step(1)
      .onFinishChange((value) => {
        this.options.speed = value;
        this.setOptions(this.options);
      });
    folderRender.add(this.options, 'waveSpeed', 1, 100).step(1)
      .onFinishChange((value) => {
        this.options.waveSpeed = value;
        this.setOptions(this.options);
      });
    folderRender.add(this.options, 'resolution', 30, 150).step(5)
      .onFinishChange((value) => {
        this.options.resolution = value;
        this.setResolution(this.options);
      });
    folderRender.add(this.options, 'shaderType',
      ['java', 'larvel', 'octal', 'offset', 'rainbow', 'hashing', 'default'])
      .onFinishChange((value) => {
        this.options.shaderType = value;
        this.setOptions(this.options);
      });
    folderRender.open();

    this.setOptions(this.options);
    this.setResolution(this.options);
  };
}
<commit_msg>final pass<commit_after>
import p5 from 'p5';
import { Generator } from './simplexNoise';
import dat from 'dat-gui';

/*
 * Flyby Render - Illusion of motion and flying over a simplex landscape
 */

/* eslint-disable */
const sketch = function (p) {
  var generator;
  generator = new Generator(10);
  // setting screen vars
  var width = 640;
  var height = 640;
  var width_half = width / 2;
  var height_half = height / 2;
  var grid;
  var spacing = ~~(width / grid);
  var spacer = 0;
  // setting items for render
  var time = 0;
  var timeNoise = 0;
  var iteration = 0.5;
  var strength;
  var speed = 10;
  var shaderType;
  var radius = 10;
  // setting color vars
  var r = 0;
  var g = 0;
  var b = 0;
  var op = 255;
  var colorset = [0, 0, 0];
  // setting items for movement
  var timeout = false;
  var waveSpeed = 0.0005;
  var zOffset = 0;
  var offsetX = 0;
  var offsetY = 0;
  var zoom = -50;
  var camX = width_half;
  var camY = height_half;
  var tempX = width_half;
  var tempY = height_half;
  var thisX = width_half;
  var thisY = height_half;
  var lastHigh = 0;
  // building arrays
  var vertices = new Array(spacing);
  for (var i = 0; i < spacing; i++) {
    vertices[i] = new Array(spacing * 2);
  }

  // p5.js setup function
  p.setup = function() {
    p.createCanvas(640, 640, p.WEBGL);
    p.frameRate(60);
      // above prevents clicks from happening outside of the canvas.
      // .mousePressed(() => {isPressed = true;})
      // .mouseReleased(() => {isPressed = false;});

    var fov = 60 / 180 * p.PI;
    var cameraZ = height_half / p.tan(fov/2.0);
    p.perspective(60 / 180 * p.PI, width/height, cameraZ * 0.1, cameraZ * 10);
    p.lighting();
  // simplex noise function
  };

  p.setOptions = function(options) {
    speed = options.speed / 10;
    iteration = options.iteration / 100;
    waveSpeed = options.waveSpeed / 10000;

    shaderType = options.shaderType;
    strength = options.strength;
  };

  p.setResolution = function(options) {
    grid = options.resolution || grid;
    spacing = ~~(width / grid);
    vertices = new Array(spacing);
    for (var i = 0; i < spacing; i++) {
      vertices[i] = new Array(spacing);
    }
  };

  p.draw = function() {
    // advance time and tick draw loop for time segment
    var size = ~~(width / spacing);
    var length = ~~(size * 1.25);
    spacer = spacer + speed;
    if (spacer > length) {
      // the time phase of the noise wave moves
      // once the cubes moved one space
      time += 1;
      spacer = 0;
    }

    p.generateMesh();
    p.viewPort();

    // move to center to start drawing grid
    p.translate(-width_half, -height, 200);

    for (var j = 0; j < spacing * 2; j++) {
      for (var i = 0; i < spacing; i++) {
        // generate noise values and shader colors
        var noiseValue = (vertices[i][j].n) * 0.3;
        var colorset = p.shader(vertices[i][j].n, i, j);
        if (vertices[i][j].n > lastHigh && j % 20 == 0) {
          lastHigh = vertices[i][j].n;
        }
        // push and move 3D object into place
        p.push();
        p.translate(i * size, j * length - spacer, -noiseValue * 2);
        p.ambientMaterial(colorset.r, colorset.g, colorset.b, colorset.op);
        p.box(size, length, 50);
        p.pop();
      }
    }
  };

  p.generateMesh = function() {
    timeNoise += 1;
    const timeStop = time * iteration;
    for (var j = 0; j < spacing * 2; j++) {
      for (var i = 0; i < spacing; i++) {
        var nPoint = Math.abs(
          generator.simplex3(iteration * i,
            iteration * j + timeStop, timeNoise * waveSpeed)
          ) * strength;
        var zVector = nPoint * 10;
        vertices[i][j] = {
          n: zVector
        };
      }
    }
  };

  p.pauseChange = function() {
    timeout = true;
    setTimeout(() => {
      timeout = false;
    }, 6000);
  };

  p.viewPort = function() {
  // set viewport, background, and lighting
    p.background(30,30,30);
    // move into position to draw grid
    p.translate((width / 2) - (spacing * grid / 2), -100, zoom);
    p.checkForChange();
    p.moveVectors();
    p.rotateX(90 + camY);
    p.rotateZ(camX);
  };

  p.checkForChange = function() {
    if (p.random(1,255) > 252 && !timeout) {
      tempX = width_half - (width - p.random(1, width * 2)) * .8;
      p.pauseChange();
    }
    if (p.random(1,255) > 250 && !timeout) {
      tempY = height_half - (lastHigh / 8) - (55 - p.random(1, 120));
      p.pauseChange();
    }
  };

  p.moveVectors = function(){
    thisX = thisX - (thisX - tempX) * 0.006;
    thisY = thisY - (thisY - tempY) * 0.006;
    camX = (width_half - thisX) * 0.006;
    camY = (height_half - thisY) * 0.008;
  };

  p.mouseWheel = function(event) {
    //move the square according to the vertical scroll amount
    zoom += event.delta;
    //uncomment to block page scrolling
    return false;
  };

  p.lighting = function()  {
    p.directionalLight(250, 250, 250, 255, 1, 0, -1);
    p.directionalLight(160, 160, 160, 255, -1, 1, 0);
    p.directionalLight(160, 160, 160, 255, 0, -1, 1);
  };

  p.shader = function(noise, i, j){
    switch(shaderType) {
      case 'java':
        // java render color mode
        b = Math.cos(noise * Math.PI / 180 + (time * 0.2)) * 255;
        r = 255 - b;
        // Math.sin(1 + noise * Math.PI / 180 - (time * 0.01)) * 255;
        g = Math.cos(2 - noise * 2 * Math.PI / 180) * 255;
        op = 255;
        break;
      case 'larvel':
        // original render color mode
        r = Math.cos(noise * 1.5 * Math.PI / 180 - (time * 0.01)) * 255;
        b = Math.sin(r * 0.15 * Math.PI / 180 + (time * 0.05)) * 255;
        g = 255 - ~~(r * j * i) / 255;
        op = 255;
        break;
      case 'octal':
        // octal render color mode - red and cyan
        const m = Math.cos(noise * Math.PI / 180);
        const o = Math.sin(noise * 4 * Math.PI / 180);
        r = ~~(m * 230);
        b = ~~(o * 230);
        g = 0;
        op = 255;
  			break;
      case 'offset':
        // offset - three waves of render color
        b = Math.cos(noise * 3 * Math.PI / 180 + (j * 0.01)) * 255;
        g = Math.sin(i *  Math.PI / grid + (time * 0.01)) * 255;
        r = Math.cos(j * Math.PI / grid + (time * 0.009)) * 255;
        op = 255;
        break;
      case 'rainbow':
        // rainbow render color mode
        var mult = 0.004;
        r = ~~(255 - 255 * (1 - Math.sin((noise * mult) * j)) / 2);
        g = ~~(255 - 255 * (1 + Math.cos((noise * mult) * i)) / 2);
        b = Math.cos(noise * 5 * Math.PI / 180 - (time * 0.03)) * 255;
        op = Math.abs(((noise * 255) - 0) / (255 - 0)) / 2.5;
  			break;
      case 'hashing':
        // original render color mode
        r = Math.cos(noise * 2.5 * Math.PI / 180 - (time * 0.01)) * 255;
        b = r;
        g = b;
        op = 255;
        break;

      case 'default':
        // original render color mode
        r = 255 - Math.cos(noise * Math.PI / 180) * 255;
        g = r;
        b = g;
        op = r;
        break;
      }
    return {
      r,
      g,
      b,
      op
    };
  };
  // end of sketch
};

/** Processing p5.js Sketch Definition          **/

/* eslint-enable */
/** Parent Render Class */
export default class Render {
  constructor(element) {
    // Screen Set Up //
    this.element = element;
    this.myp5 = undefined;
    // run function //
    this.setup();
  }
  /* eslint new-cap: 0 */
  setup = () => {
    this.myp5 = new p5(sketch, this.element);
    this.createGUI();
  };
  setOptions = (options) => {
    this.myp5.setOptions(options);
  };
  setResolution = (options) => {
    this.myp5.setResolution(options);
  };
  createGUI = () => {
    const viewSize = window.innerWidth || document.documentElement.clientWidth;
    this.options = {
      iteration: 3.5,
      strength: 40,
      resolution: viewSize < 640 ? 65 : 35,
      speed: 160,
      waveSpeed: 20,
      shaderType: 'hashing',
    };
    this.gui = new dat.GUI();
    const folderRender = this.gui.addFolder('Render Options');
    folderRender.add(this.options, 'iteration', 0, 10).step(0.1)
      .onFinishChange((value) => {
        this.options.iteration = value;
        this.setOptions(this.options);
      });
    folderRender.add(this.options, 'strength', 1, 50).step(1)
      .onFinishChange((value) => {
        this.options.strength = value;
        this.setOptions(this.options);
      });
    folderRender.add(this.options, 'speed', 1, 1000).step(1)
      .onFinishChange((value) => {
        this.options.speed = value;
        this.setOptions(this.options);
      });
    folderRender.add(this.options, 'waveSpeed', 1, 100).step(1)
      .onFinishChange((value) => {
        this.options.waveSpeed = value;
        this.setOptions(this.options);
      });
    folderRender.add(this.options, 'resolution', 30, 150).step(5)
      .onFinishChange((value) => {
        this.options.resolution = value;
        this.setResolution(this.options);
      });
    folderRender.add(this.options, 'shaderType',
      ['java', 'larvel', 'octal', 'offset', 'rainbow', 'hashing', 'default'])
      .onFinishChange((value) => {
        this.options.shaderType = value;
        this.setOptions(this.options);
      });
    folderRender.open();

    this.setOptions(this.options);
    this.setResolution(this.options);
  };
}
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import CircularProgress from '../CircularProgress/CircularProgress'
import { browserHistory, Link } from 'react-router'
import SearchInput from '../SearchInput/SearchInput'
import Counter from '../Statistics/Counter/Counter'
import { theme  } from '../../tools'
import { fetchGlobalMetrics  } from '../../fetch/fetch'
import { waitForDataAndSetState, cancelAllPromises } from '../../helpers/components'

const styles = {
  masthead: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'space-around',
    padding: '8%',
  },
  stats: {
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'center',
    justifyContent: 'space-around',
  },
  button: {
    margin: '40px 20px 10px 20px',
    padding: '15px 20px',
    backgroundColor: theme.blue,
    color: '#fff',
    border: 'none',
  },
  paper: {
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    padding: '1em',
  },
  catalogLinks: {
    fontSize: '1.5em',
  },
  datagouv: {
    backgroundColor: '#FFF',
    border: `1px solid ${theme.blue}`,
    color: theme.blue,
    padding: 40,
    margin: '0 8% 4em',
  },
  datagouvIntro: {
    fontSize: '1.2em',
    fontWeight: 'lighter',
    textAlign: 'center',
    fontVariant: 'small-caps',
  },
  datagouvLink: {
    fontWeight: 'bolder',
    fontSize: '1.3em',
    fontVariant: 'normal',
  },
  datagouvCounter: {
    value: {
      fontSize: '3em',
    },
  },
}

class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {errors: []}
  }

  componentWillMount() {
    return waitForDataAndSetState(fetchGlobalMetrics(), this, 'datasets')
  }

  componentWillUnmount() {
    return cancelAllPromises(this)
  }

  userSearch(path, textInput) {
    browserHistory.push(`${path}?q=${textInput}`)
  }

  render() {
    const loader =  <CircularProgress />
    const notPublishedYet = this.state.datasets ? <Counter value={this.state.datasets.notPublishedYet}  style={styles.datagouvCounter} color={theme.yellow} size="large" icon="hourglass half"/> : loader
    const published = this.state.datasets ? <Counter value={this.state.datasets.published.public + this.state.datasets.published.private} style={styles.datagouvCounter} size="large" color={theme.green} icon="database"/> : loader

    return (

          <SearchInput ref="searchInput" handleTextChange={(textInput) => this.userSearch('datasets', textInput)} />

            <button style={styles.button} onClick={() => this.userSearch('datasets', this.refs.searchInput.state.textInput)}>Rechercher un jeu de donnée</button>
            <button style={styles.button} onClick={() => this.userSearch('records', this.refs.searchInput.state.textInput)}>Rechercher un enregistrements</button>

          OU
          <Link style={styles.catalogLinks} to="catalogs">Explorer les 106 catalogues</Link>

            Votre organisation gère des données géographiques avec des outils compatibles Inspire et souhaite les rendre disponibles sans effort sur data.gouv.fr

En attente de publication

              {notPublishedYet}

Jeux de données publiés

              {published}

    )
  }
}

export default Home
<commit_msg>Different style for the two button of the home page<commit_after>import React, { Component } from 'react'
import CircularProgress from '../CircularProgress/CircularProgress'
import { browserHistory, Link } from 'react-router'
import SearchInput from '../SearchInput/SearchInput'
import Counter from '../Statistics/Counter/Counter'
import { theme  } from '../../tools'
import { fetchGlobalMetrics  } from '../../fetch/fetch'
import { waitForDataAndSetState, cancelAllPromises } from '../../helpers/components'

const styles = {
  masthead: {
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'space-around',
    padding: '8%',
  },
  stats: {
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'center',
    justifyContent: 'space-around',
  },
  recordsButton: {
    margin: '40px 20px 10px 20px',
    padding: '15px 20px',
    backgroundColor: '#fff',
    border: '1px solid',
    borderColor: theme.blue,
  },
  datasetsButton: {
    margin: '40px 20px 10px 20px',
    padding: '15px 20px',
    backgroundColor: theme.blue,
    color: '#fff',
    border: 'none',
  },
  paper: {
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    padding: '1em',
  },
  catalogLinks: {
    fontSize: '1.5em',
  },
  datagouv: {
    backgroundColor: '#FFF',
    border: `1px solid ${theme.blue}`,
    color: theme.blue,
    padding: 40,
    margin: '0 8% 4em',
  },
  datagouvIntro: {
    fontSize: '1.2em',
    fontWeight: 'lighter',
    textAlign: 'center',
    fontVariant: 'small-caps',
  },
  datagouvLink: {
    fontWeight: 'bolder',
    fontSize: '1.3em',
    fontVariant: 'normal',
  },
  datagouvCounter: {
    value: {
      fontSize: '3em',
    },
  },
}

class Home extends Component {
  constructor(props) {
    super(props)
    this.state = {errors: []}
  }

  componentWillMount() {
    return waitForDataAndSetState(fetchGlobalMetrics(), this, 'datasets')
  }

  componentWillUnmount() {
    return cancelAllPromises(this)
  }

  userSearch(path, textInput) {
    browserHistory.push(`${path}?q=${textInput}`)
  }

  render() {
    const loader =  <CircularProgress />
    const notPublishedYet = this.state.datasets ? <Counter value={this.state.datasets.notPublishedYet}  style={styles.datagouvCounter} color={theme.yellow} size="large" icon="hourglass half"/> : loader
    const published = this.state.datasets ? <Counter value={this.state.datasets.published.public + this.state.datasets.published.private} style={styles.datagouvCounter} size="large" color={theme.green} icon="database"/> : loader

    return (

          <SearchInput ref="searchInput" handleTextChange={(textInput) => this.userSearch('datasets', textInput)} />

            <button style={styles.datasetsButton} onClick={() => this.userSearch('datasets', this.refs.searchInput.state.textInput)}>Rechercher un jeu de données</button>
            <button style={styles.recordsButton} onClick={() => this.userSearch('records', this.refs.searchInput.state.textInput)}>Rechercher un enregistrement</button>

          OU
          <Link style={styles.catalogLinks} to="catalogs">Explorer les 106 catalogues</Link>

            Votre organisation gère des données géographiques avec des outils compatibles Inspire et souhaite les rendre disponibles sans effort sur data.gouv.fr

En attente de publication

              {notPublishedYet}

Jeux de données publiés

              {published}

    )
  }
}

export default Home
<|endoftext|>


<commit_before>import {Component} from 'component-loader-js';
import gsap from 'gsap';

export default class extends Component {
    constructor() {
      super(...arguments);
      this.bind(
                '_onOpenMenu',
                '_onCloseMenu',
                '_onEnterCurrentSection',
                '_onMenuLinkClick'
      );
      this.isOpen = false;
      const morphEl = this.el.querySelector('.Shape');
      const s = Snap(morphEl.querySelector('svg') );
      this.path = s.select( 'path' );
      this.initialPath = this.path.attr('d');
      this.steps = morphEl.getAttribute( 'data-morph-open' ).split(';');
      this.stepsTotal = this.steps.length;
      this.isAnimating = false;
      this.subscribe('ACTION_OPEN_MENU', this._onOpenMenu);
      this.subscribe('ACTION_HIGHLIGHT_CURRENT_SECTION', this._onEnterCurrentSection);

      const closebtn = this.el.querySelector('.Menu-buttonClose');
      closebtn.addEventListener('click', this._onCloseMenu);

      const link = this.el.getElementsByClassName('Menu-button');
      for (var i=0; i<link.length; i++){
          link[i].addEventListener('click', this._onMenuLinkClick);
      }
    }

    _onOpenMenu(){
      const bodyEl = document.body;
      if( this.isAnimating ) return false;
      this.isAnimating = true;
      bodyEl.classList.add("is-showing");
      // animate path
      const pos = 0;
      const nextStep = (pos) => {
        if( pos > this.stepsTotal - 1 ) {
          this.isAnimating = false;
          return;
        }
        this.path.animate( { 'path' : this.steps[pos] }, pos === 0 ? 400 : 500, pos === 0 ? mina.easein : mina.elastic, () => { nextStep(pos); } );
        pos++;
      };
      nextStep(pos);
      this.isOpen = !this.isOpen;
    }

    _onCloseMenu(){
      this.isOpen = true;
      document.querySelector('.is-showing').classList.remove("is-showing");
      // animate path
      setTimeout( () => {
        // reset path
        this.path.attr( 'd', this.initialPath );
        this.isAnimating = false;
      }, 300 );
    }

    _onEnterCurrentSection(data){
      const idString = data.id;
      const activeLink = this.el.querySelector('.active');
      if(activeLink){
        activeLink.classList.remove("active");
      }
      const currentLink = document.querySelector("button[id='Button-"+idString+"']");
      currentLink.classList.add("active");
    }

    _onMenuLinkClick(event){
      console.log("_onMenuLinkClick", event.target.id);
      this.scrollToSection(event.target.id);
    }

    scrollToSection(id){
      const sectionId = id.replace("Button-", "#");
      TweenLite.to(window, 1, {scrollTo:{y: sectionId, offsetY:70}});
      if (Modernizr.mq('(max-width: 992px)')) {
        this._onCloseMenu();
      }
    }

    destroy() {
        super.destroy();
        this.unsubscribe('ACTION_OPEN_MENU', this._onOpenMenu);
    }
}

<commit_msg>Menu: simplified TweenLite scrollTo<commit_after>import {Component} from 'component-loader-js';
import gsap from 'gsap';

export default class extends Component {
    constructor() {
      super(...arguments);
      this.bind(
                '_onOpenMenu',
                '_onCloseMenu',
                '_onEnterCurrentSection',
                '_onMenuLinkClick'
      );
      this.isOpen = false;
      const morphEl = this.el.querySelector('.Shape');
      const s = Snap(morphEl.querySelector('svg') );
      this.path = s.select( 'path' );
      this.initialPath = this.path.attr('d');
      this.steps = morphEl.getAttribute( 'data-morph-open' ).split(';');
      this.stepsTotal = this.steps.length;
      this.isAnimating = false;
      this.subscribe('ACTION_OPEN_MENU', this._onOpenMenu);
      this.subscribe('ACTION_HIGHLIGHT_CURRENT_SECTION', this._onEnterCurrentSection);

      const closebtn = this.el.querySelector('.Menu-buttonClose');
      closebtn.addEventListener('click', this._onCloseMenu);

      const link = this.el.getElementsByClassName('Menu-button');
      for (var i=0; i<link.length; i++){
          link[i].addEventListener('click', this._onMenuLinkClick);
      }
    }

    _onOpenMenu(){
      const bodyEl = document.body;
      if( this.isAnimating ) return false;
      this.isAnimating = true;
      bodyEl.classList.add("is-showing");
      // animate path
      const pos = 0;
      const nextStep = (pos) => {
        if( pos > this.stepsTotal - 1 ) {
          this.isAnimating = false;
          return;
        }
        this.path.animate( { 'path' : this.steps[pos] }, pos === 0 ? 400 : 500, pos === 0 ? mina.easein : mina.elastic, () => { nextStep(pos); } );
        pos++;
      };
      nextStep(pos);
      this.isOpen = !this.isOpen;
    }

    _onCloseMenu(){
      this.isOpen = true;
      document.querySelector('.is-showing').classList.remove("is-showing");
      // animate path
      setTimeout( () => {
        // reset path
        this.path.attr( 'd', this.initialPath );
        this.isAnimating = false;
      }, 300 );
    }

    _onEnterCurrentSection(data){
      const idString = data.id;
      const activeLink = this.el.querySelector('.active');
      if(activeLink){
        activeLink.classList.remove("active");
      }
      const currentLink = document.querySelector("button[id='Button-"+idString+"']");
      currentLink.classList.add("active");
    }

    _onMenuLinkClick(event){
      event.preventDefault()
      this.scrollToSection(event.target.id);
    }

    scrollToSection(id){
      const sectionId = id.replace("Button-", "");
      const top = document.getElementById(sectionId).offsetTop;
      TweenLite.to(window, 1, {scrollTo:{y: top, offsetY:70}});
      if (Modernizr.mq('(max-width: 992px)')) {
        this._onCloseMenu();
      }
    }

    destroy() {
        super.destroy();
        this.unsubscribe('ACTION_OPEN_MENU', this._onOpenMenu);
    }
}

<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import {
  FormattedRelative,
  defineMessages,
  FormattedMessage,
} from 'react-intl';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import cn from 'classnames';
import s from './Poll.css';
import Button from '../Button';
import Box from '../Box';
import Layer from '../Layer';
import VoteArea from './VoteArea';
import Notification from '../Notification';
import history from '../../history';
import PollOptionsView from '../PollOptionsView';
import Avatar from '../Avatar';
import VotesList from '../VotesList';

const messages = defineMessages({
  closed: {
    id: 'poll.closed',
    defaultMessage: 'Ended',
    description: 'Poll closing time',
  },
  closing: {
    id: 'poll.closing',
    defaultMessage: 'Closing',
    description: 'Poll ending time',
  },
  retract: {
    id: 'poll.retractVote',
    defaultMessage: 'Retract your vote',
    description: 'Drawing back the vote',
  },
  cancel: {
    id: 'commands.cancel',
    defaultMessage: 'Cancel',
    description: 'Short command to cancel a operation',
  },

  notify: {
    id: 'poll.notify',
    defaultMessage: 'Your statement will be deleted!',
    description: 'Notice that vote change will lead to statement deletion',
  },
  error: {
    id: 'poll.voteError',
    defaultMessage: 'Voting failed!',
    description: 'Notice that voting was not successful',
  },
});

const mapOptions = (options, ownVote) => {
  let positions = [];
  if (ownVote && ownVote.positions) {
    ({ positions } = ownVote);
  }
  return options.reduce((obj, option) => {
    // eslint-disable-next-line
    obj[option.pos] = {
      ...option,
      checked: positions.some(p => p.pos === option.pos && p.value),
      disabled: false,
    };
    return obj;
  }, {});
};

class Poll extends React.Component {
  static propTypes = {
    id: PropTypes.string.isRequired,
    threshold: PropTypes.number.isRequired,
    endTime: PropTypes.string.isRequired,
    allVoters: PropTypes.number.isRequired,
    ownStatement: PropTypes.shape({}),
    closedAt: PropTypes.string,
    // statements: PropTypes.arrayOf(PropTypes.object),
    upvotes: PropTypes.number.isRequired,
    downvotes: PropTypes.number.isRequired,
    votes: PropTypes.arrayOf(PropTypes.shape({})),
    ownVote: PropTypes.shape({
      id: PropTypes.string,
      positions: PropTypes.string,
      pollId: PropTypes.string,
    }),
    mode: PropTypes.shape({
      withStatements: PropTypes.bool,
      unipolar: PropTypes.bool,
      thresholdRef: PropTypes.string,
    }).isRequired,
    onVote: PropTypes.func.isRequired,
    onFetchVoters: PropTypes.func.isRequired,
    followeeVotes: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
    filter: PropTypes.string.isRequired,
    updates: PropTypes.shape({ vote: PropTypes.shape({}) }).isRequired,
    canVote: PropTypes.bool,
  };

  static defaultProps = {
    votes: null,
    ownVote: null,
    ownStatement: null,
    closedAt: null,
    canVote: null,
  };

  constructor(props) {
    super(props);
    this.state = { pollOptions: mapOptions(props.options, props.ownVote) };
    this.voteUp = this.voteUp.bind(this);
    this.voteDown = this.voteDown.bind(this);
    this.fetchVoters = this.fetchVoters.bind(this);
    this.handleOptionSelection = this.handleOptionSelection.bind(this);
    this.toggleVotersBox = this.toggleVotersBox.bind(this);
  }

  componentWillReceiveProps({ updates, id, options, ownVote }) {
    const { id: oldId, updates: oldUpdates } = this.props;
    if (id === oldId && updates) {
      let voteError;
      if (updates.error) {
        const oldStatus = oldUpdates || {};
        voteError = !oldStatus.error;
      }
      if (updates.success) {
        voteError = false;
      }
      this.setState({
        voteError,
        pollOptions: mapOptions(options, ownVote),
      });
    }
  }

  getFolloweeVotes(pos) {
    const { followeeVotes } = this.props;
    if (!followeeVotes) {
      return null;
    }
    return followeeVotes
      .filter(vote => vote.positions[0].pos === (pos === 'pro' ? 0 : 1))
      .map(vote => (
        <Avatar
          onClick={() => {
            history.push(`/accounts/${vote.voter.id}`);
          }}
          className={s.followee}
          user={vote.voter}
        />
      ));
  }

  toggleVotersBox() {
    const { isExpanded } = this.state;
    this.setState(prevState => ({ isExpanded: !prevState.isExpanded }));
    if (!isExpanded) {
      this.fetchVoters();
    }
  }

  canVote(positions) {
    const { ownVote, ownStatement, id, onVote, extended } = this.props;
    let method; // or take methods better directly in and connect to redux
    let info = null;

    if (!ownVote) {
      method = 'create';
    } else if (ownVote.positions[0].pos !== positions[0].pos || extended) {
      if (
        // delete last selected option
        extended &&
        ownVote.positions.length === 1 &&
        ownVote.positions[0].pos === positions[0].pos &&
        positions[0].value === 0
      ) {
        method = 'del';
      } else {
        method = 'update';
      }
    } else {
      method = 'del';
    }
    const voteId = ownVote ? ownVote.id : null;
    if (ownStatement) {
      info = ownStatement.id;
      this.setState({
        confirmationFunc: () => {
          onVote({ vote: { positions, pollId: id, id: voteId } }, method, info);
          this.setState({ confirmationFunc: null });
        },
      });
      return;
    }
    onVote({ vote: { positions, pollId: id, id: voteId } }, method, info);
  }

  voteUp() {
    this.canVote([{ pos: 0, value: 1 }]);
  }

  voteDown() {
    this.canVote([{ pos: 1, value: 1 }]);
  }

  fetchVoters() {
    const { onFetchVoters, id } = this.props;
    onFetchVoters(id);
  }

  handleOptionSelection(data) {
    // const { multipleChoice } = this.props;
    const { pollOptions } = this.state;
    if (data) {
      const option = pollOptions[data.pos];
      this.canVote([{ pos: option.pos, value: option.checked ? 0 : 1 }]);
      // set all options to disabled
      /* this.setState(prevState => ({
          pollOptions: {
            ...prevState.pollOptions,
            [data.pos]: {
              ...prevState.pollOptions[data.pos],
              checked: !prevState.pollOptions[data.pos].checked,
            },
          },
        })); */
    }
  }

  renderVotingComponent() {
    const {
      updates,
      canVote,
      closedAt,
      ownVote,
      mode,
      extended,
      options,
      numVotes,
      followeeVotes,
      votes,
      threshold,
    } = this.props;
    const { pollOptions } = this.state;
    if (extended) {
      return (
        <PollOptionsView
          canVote={canVote}
          closedAt={closedAt}
          onLoadVotes={this.fetchVoters}
          pollOptions={pollOptions}
          numVotes={numVotes}
          updates={updates}
          followeeVotes={followeeVotes}
          votes={votes}
          onChange={this.handleOptionSelection}
          options={options}
        />
      );
    }
    return (
      <VoteArea
        updates={updates}
        upvotes={options[0].numVotes}
        downvotes={!mode.unipolar ? options[1].numVotes : 0}
        unipolar={mode.unipolar}
        active={canVote && !closedAt}
        onUpvoteClick={this.voteUp}
        onDownvoteClick={this.voteDown}
        ownVote={ownVote}
        threshold={threshold}
        onClick={this.toggleVotersBox}
      />
    );
  }

  render() {
    const { closedAt, mode, votes, updates, threshold } = this.props;
    const { confirmationFunc, voteError, isExpanded } = this.state;

    return (

        {confirmationFunc && (
          <Layer>
            <Box column pad className={s.confirmationBox}>
              <Notification
                type="alert"
                message={<FormattedMessage {...messages.notify} />}
              />
              <Box justify>
                <Button onClick={() => confirmationFunc()} label="Ok" />
                <Button
                  primary
                  label={<FormattedMessage {...messages.cancel} />}
                  onClick={() => {
                    this.setState({ confirmationFunc: null });
                  }}
                />
              </Box>
            </Box>
          </Layer>
        )}
        {closedAt && (

            <FormattedMessage {...messages.closed} />{' '}
            <FormattedRelative value={closedAt} />

        )}
        {this.renderVotingComponent()}

{this.getFolloweeVotes('pro')}

            {this.getFolloweeVotes('con')}

        {isExpanded && (

            <VotesList
              autoLoadVotes
              unipolar={mode.unipolar}
              votes={votes}
              isFetching={(updates && updates.isPending) || false}
              errorMessage={updates && updates.error}
              getVotes={this.fetchVoters}
            />
            {!mode.unipolar && threshold < 50 ? ' (IMPOSSIBLE)' : ''}

        )}
        {voteError && (
          <Notification
            type="error"
            message={<FormattedMessage {...messages.error} />}
          />
        )}

    );
  }
}

export default withStyles(s)(Poll);
<commit_msg>added toggle for votes box<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import {
  FormattedRelative,
  defineMessages,
  FormattedMessage,
} from 'react-intl';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import cn from 'classnames';
import s from './Poll.css';
import Button from '../Button';
import Box from '../Box';
import Layer from '../Layer';
import VoteArea from './VoteArea';
import Notification from '../Notification';
import history from '../../history';
import PollOptionsView from '../PollOptionsView';
import Avatar from '../Avatar';
import VotesList from '../VotesList';

const messages = defineMessages({
  closed: {
    id: 'poll.closed',
    defaultMessage: 'Ended',
    description: 'Poll closing time',
  },
  closing: {
    id: 'poll.closing',
    defaultMessage: 'Closing',
    description: 'Poll ending time',
  },
  retract: {
    id: 'poll.retractVote',
    defaultMessage: 'Retract your vote',
    description: 'Drawing back the vote',
  },
  cancel: {
    id: 'commands.cancel',
    defaultMessage: 'Cancel',
    description: 'Short command to cancel a operation',
  },

  notify: {
    id: 'poll.notify',
    defaultMessage: 'Your statement will be deleted!',
    description: 'Notice that vote change will lead to statement deletion',
  },
  error: {
    id: 'poll.voteError',
    defaultMessage: 'Voting failed!',
    description: 'Notice that voting was not successful',
  },
});

const mapOptions = (options, ownVote) => {
  let positions = [];
  if (ownVote && ownVote.positions) {
    ({ positions } = ownVote);
  }
  return options.reduce((obj, option) => {
    // eslint-disable-next-line
    obj[option.pos] = {
      ...option,
      checked: positions.some(p => p.pos === option.pos && p.value),
      disabled: false,
    };
    return obj;
  }, {});
};

class Poll extends React.Component {
  static propTypes = {
    id: PropTypes.string.isRequired,
    threshold: PropTypes.number.isRequired,
    endTime: PropTypes.string.isRequired,
    allVoters: PropTypes.number.isRequired,
    ownStatement: PropTypes.shape({}),
    closedAt: PropTypes.string,
    // statements: PropTypes.arrayOf(PropTypes.object),
    upvotes: PropTypes.number.isRequired,
    downvotes: PropTypes.number.isRequired,
    votes: PropTypes.arrayOf(PropTypes.shape({})),
    ownVote: PropTypes.shape({
      id: PropTypes.string,
      positions: PropTypes.string,
      pollId: PropTypes.string,
    }),
    mode: PropTypes.shape({
      withStatements: PropTypes.bool,
      unipolar: PropTypes.bool,
      thresholdRef: PropTypes.string,
    }).isRequired,
    onVote: PropTypes.func.isRequired,
    onFetchVoters: PropTypes.func.isRequired,
    followeeVotes: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
    filter: PropTypes.string.isRequired,
    updates: PropTypes.shape({ vote: PropTypes.shape({}) }).isRequired,
    canVote: PropTypes.bool,
  };

  static defaultProps = {
    votes: null,
    ownVote: null,
    ownStatement: null,
    closedAt: null,
    canVote: null,
  };

  constructor(props) {
    super(props);
    this.state = { pollOptions: mapOptions(props.options, props.ownVote) };
    this.voteUp = this.voteUp.bind(this);
    this.voteDown = this.voteDown.bind(this);
    this.fetchVoters = this.fetchVoters.bind(this);
    this.handleOptionSelection = this.handleOptionSelection.bind(this);
    this.toggleVotersBox = this.toggleVotersBox.bind(this);
  }

  componentWillReceiveProps({ updates, id, options, ownVote }) {
    const { id: oldId, updates: oldUpdates } = this.props;
    if (id === oldId && updates) {
      let voteError;
      if (updates.error) {
        const oldStatus = oldUpdates || {};
        voteError = !oldStatus.error;
      }
      if (updates.success) {
        voteError = false;
      }
      this.setState({
        voteError,
        pollOptions: mapOptions(options, ownVote),
      });
    }
  }

  getFolloweeVotes(pos) {
    const { followeeVotes } = this.props;
    if (!followeeVotes) {
      return null;
    }
    return followeeVotes
      .filter(vote => vote.positions[0].pos === (pos === 'pro' ? 0 : 1))
      .map(vote => (
        <Avatar
          onClick={() => {
            history.push(`/accounts/${vote.voter.id}`);
          }}
          className={s.followee}
          user={vote.voter}
        />
      ));
  }

  toggleVotersBox() {
    const { isExpanded } = this.state;
    this.setState(prevState => ({ isExpanded: !prevState.isExpanded }));
    if (!isExpanded) {
      this.fetchVoters();
    }
  }

  canVote(positions) {
    const { ownVote, ownStatement, id, onVote, extended } = this.props;
    let method; // or take methods better directly in and connect to redux
    let info = null;

    if (!ownVote) {
      method = 'create';
    } else if (ownVote.positions[0].pos !== positions[0].pos || extended) {
      if (
        // delete last selected option
        extended &&
        ownVote.positions.length === 1 &&
        ownVote.positions[0].pos === positions[0].pos &&
        positions[0].value === 0
      ) {
        method = 'del';
      } else {
        method = 'update';
      }
    } else {
      method = 'del';
    }
    const voteId = ownVote ? ownVote.id : null;
    if (ownStatement) {
      info = ownStatement.id;
      this.setState({
        confirmationFunc: () => {
          onVote({ vote: { positions, pollId: id, id: voteId } }, method, info);
          this.setState({ confirmationFunc: null });
        },
      });
      return;
    }
    onVote({ vote: { positions, pollId: id, id: voteId } }, method, info);
  }

  voteUp() {
    this.canVote([{ pos: 0, value: 1 }]);
  }

  voteDown() {
    this.canVote([{ pos: 1, value: 1 }]);
  }

  fetchVoters() {
    const { onFetchVoters, id } = this.props;
    onFetchVoters(id);
  }

  handleOptionSelection(data) {
    // const { multipleChoice } = this.props;
    const { pollOptions } = this.state;
    if (data) {
      const option = pollOptions[data.pos];
      this.canVote([{ pos: option.pos, value: option.checked ? 0 : 1 }]);
      // set all options to disabled
      /* this.setState(prevState => ({
          pollOptions: {
            ...prevState.pollOptions,
            [data.pos]: {
              ...prevState.pollOptions[data.pos],
              checked: !prevState.pollOptions[data.pos].checked,
            },
          },
        })); */
    }
  }

  renderVotingComponent() {
    const {
      updates,
      canVote,
      closedAt,
      ownVote,
      mode,
      extended,
      options,
      numVotes,
      followeeVotes,
      votes,
      threshold,
    } = this.props;
    const { pollOptions } = this.state;
    if (extended) {
      return (
        <PollOptionsView
          canVote={canVote}
          closedAt={closedAt}
          onLoadVotes={this.fetchVoters}
          pollOptions={pollOptions}
          numVotes={numVotes}
          updates={updates}
          followeeVotes={followeeVotes}
          votes={votes}
          onChange={this.handleOptionSelection}
          options={options}
        />
      );
    }
    return (
      <VoteArea
        updates={updates}
        upvotes={options[0].numVotes}
        downvotes={!mode.unipolar ? options[1].numVotes : 0}
        unipolar={mode.unipolar}
        active={canVote && !closedAt}
        onUpvoteClick={this.voteUp}
        onDownvoteClick={this.voteDown}
        ownVote={ownVote}
        threshold={threshold}
        onClick={this.toggleVotersBox}
      />
    );
  }

  render() {
    const { closedAt, mode, votes, updates, threshold } = this.props;
    const { confirmationFunc, voteError, isExpanded } = this.state;

    return (

        {confirmationFunc && (
          <Layer>
            <Box column pad className={s.confirmationBox}>
              <Notification
                type="alert"
                message={<FormattedMessage {...messages.notify} />}
              />
              <Box justify>
                <Button onClick={() => confirmationFunc()} label="Ok" />
                <Button
                  primary
                  label={<FormattedMessage {...messages.cancel} />}
                  onClick={() => {
                    this.setState({ confirmationFunc: null });
                  }}
                />
              </Box>
            </Box>
          </Layer>
        )}
        {closedAt && (

            <FormattedMessage {...messages.closed} />{' '}
            <FormattedRelative value={closedAt} />

        )}
        {this.renderVotingComponent()}

{this.getFolloweeVotes('pro')}

            {this.getFolloweeVotes('con')}

        <Button
          label={isExpanded ? 'Hide votes' : 'Show votes'}
          plain
          onClick={this.toggleVotersBox}
        />
        {isExpanded && (

            <VotesList
              autoLoadVotes
              unipolar={mode.unipolar}
              votes={votes}
              isFetching={(updates && updates.isPending) || false}
              errorMessage={updates && updates.error}
              getVotes={this.fetchVoters}
            />
            {!mode.unipolar && threshold < 50 ? ' (IMPOSSIBLE)' : ''}

        )}
        {voteError && (
          <Notification
            type="error"
            message={<FormattedMessage {...messages.error} />}
          />
        )}

    );
  }
}

export default withStyles(s)(Poll);
<|endoftext|>


<commit_before>#!/usr/bin/env node
var fs = require('fs')
var GitHubSlugger = require('github-slugger')
var markybars = require('./lib/markybars.js')
var path = require('path')
var pullOrClone = require('./lib/pull-or-clone.js')
var join = path.join
var sh = require('shelljs')
var resolve = require('path').resolve

var awesomePath = join('tmp/awesome-standard')
var buildPath = 'build'
var logoPath = join(buildPath, 'docs')
var demoPath = join('tmp/standard-demo')
var mdPath = join('tmp/markdown')
var stdPath = join('tmp/standard')
var stdDocsPath = join('tmp/standard/docs')
var page = join('layout/page.html')
var demoPage = join('layout/demo.html')

var partials = {
  toc: join('layout/partials/toc.html'),
  ga: join('layout/partials/ga.html')
}

var slugger = new GitHubSlugger()

if (!sh.which('git')) {
  sh.echo('Sorry, this script requires git')
  sh.exit(1)
}

pullOrClone('https://github.com/standard/standard', stdPath)
pullOrClone('https://github.com/standard/awesome-standard', awesomePath)
pullOrClone('https://github.com/flet/standard-demo', demoPath)

sh.rm('-rf', buildPath)
sh.rm('-rf', mdPath)

sh.mkdir(buildPath)
sh.mkdir('-p', logoPath)
sh.mkdir(mdPath)

sh.cp('-f', join('markdown/*.md'), mdPath)
sh.cp('-f', join(stdPath, '*.md'), mdPath)
sh.cp('-f', join(stdDocsPath, '*.md'), mdPath)
sh.cp('-f', join(awesomePath, 'README.md'), join(mdPath, 'awesome.md'))
sh.cp('-R', join(stdDocsPath, 'logos'), logoPath)
var genPage = markybars.compile(page, partials)
var genDemo = markybars.compile(demoPage, partials)

var files = sh.ls(mdPath)
files.forEach(function (file) {
  var fileData = fs.readFileSync(join(mdPath, file), 'utf8')
  var name = path.parse(file).name
  var gen = name === 'demo' ? genDemo : genPage

  var htmlData = gen({data: fileData})
  var fileName = slugger.slug(name) + '.html'

  fs.writeFileSync(join(buildPath, fileName), htmlData, 'utf8')
})

sh.find(buildPath)
.filter(function (file) { return file.match(/\.html$/) })
.forEach(function (f) {
  // replace all RULES.md instances in links with rules.html
  sh.sed('-i', /"(.*?)RULES(.*?)\.md/g, '"rules$2.html', f)

  sh.sed('-i', /"\.\.\/README.md/g, '"index.html', f)
  sh.sed('-i', /"(.*?)README(.*?)\.md/g, '"readme$2.html', f)

  sh.sed('-i', /"(docs\/|\.\.\/)?webstorm(.*?)\.md/g, '"webstorm$2.html', f)
})

// rename files to be internet friendly
sh.mv('-f', join(buildPath, 'readme.html'), join(buildPath, 'index.html'))

// once everything is built, copy it to dist
sh.rm('dist/*.html')
sh.cp('-R', buildPath + '/', resolve(__dirname, 'dist'))

// copy standard-demo bundle.js to dist
sh.cp('-f', join(demoPath, 'bundle.js'), resolve(__dirname, 'dist', 'standard-demo.js'))

// copy favicons to dist
sh.cp('-R', 'favicons', resolve(__dirname, 'dist'))

// remove tmp dir
// sh.rm('-rf', 'tmp')
<commit_msg>uncommenting rm -rf 'tmp'<commit_after>#!/usr/bin/env node
var fs = require('fs')
var GitHubSlugger = require('github-slugger')
var markybars = require('./lib/markybars.js')
var path = require('path')
var pullOrClone = require('./lib/pull-or-clone.js')
var join = path.join
var sh = require('shelljs')
var resolve = require('path').resolve

var awesomePath = join('tmp/awesome-standard')
var buildPath = 'build'
var logoPath = join(buildPath, 'docs')
var demoPath = join('tmp/standard-demo')
var mdPath = join('tmp/markdown')
var stdPath = join('tmp/standard')
var stdDocsPath = join('tmp/standard/docs')
var page = join('layout/page.html')
var demoPage = join('layout/demo.html')

var partials = {
  toc: join('layout/partials/toc.html'),
  ga: join('layout/partials/ga.html')
}

var slugger = new GitHubSlugger()

if (!sh.which('git')) {
  sh.echo('Sorry, this script requires git')
  sh.exit(1)
}

pullOrClone('https://github.com/standard/standard', stdPath)
pullOrClone('https://github.com/standard/awesome-standard', awesomePath)
pullOrClone('https://github.com/flet/standard-demo', demoPath)

sh.rm('-rf', buildPath)
sh.rm('-rf', mdPath)

sh.mkdir(buildPath)
sh.mkdir('-p', logoPath)
sh.mkdir(mdPath)

sh.cp('-f', join('markdown/*.md'), mdPath)
sh.cp('-f', join(stdPath, '*.md'), mdPath)
sh.cp('-f', join(stdDocsPath, '*.md'), mdPath)
sh.cp('-f', join(awesomePath, 'README.md'), join(mdPath, 'awesome.md'))
sh.cp('-R', join(stdDocsPath, 'logos'), logoPath)
var genPage = markybars.compile(page, partials)
var genDemo = markybars.compile(demoPage, partials)

var files = sh.ls(mdPath)
files.forEach(function (file) {
  var fileData = fs.readFileSync(join(mdPath, file), 'utf8')
  var name = path.parse(file).name
  var gen = name === 'demo' ? genDemo : genPage

  var htmlData = gen({data: fileData})
  var fileName = slugger.slug(name) + '.html'

  fs.writeFileSync(join(buildPath, fileName), htmlData, 'utf8')
})

sh.find(buildPath)
.filter(function (file) { return file.match(/\.html$/) })
.forEach(function (f) {
  // replace all RULES.md instances in links with rules.html
  sh.sed('-i', /"(.*?)RULES(.*?)\.md/g, '"rules$2.html', f)

  sh.sed('-i', /"\.\.\/README.md/g, '"index.html', f)
  sh.sed('-i', /"(.*?)README(.*?)\.md/g, '"readme$2.html', f)

  sh.sed('-i', /"(docs\/|\.\.\/)?webstorm(.*?)\.md/g, '"webstorm$2.html', f)
})

// rename files to be internet friendly
sh.mv('-f', join(buildPath, 'readme.html'), join(buildPath, 'index.html'))

// once everything is built, copy it to dist
sh.rm('dist/*.html')
sh.cp('-R', buildPath + '/', resolve(__dirname, 'dist'))

// copy standard-demo bundle.js to dist
sh.cp('-f', join(demoPath, 'bundle.js'), resolve(__dirname, 'dist', 'standard-demo.js'))

// copy favicons to dist
sh.cp('-R', 'favicons', resolve(__dirname, 'dist'))

// remove tmp dir
sh.rm('-rf', 'tmp')
<|endoftext|>


<commit_before>import React from 'react';

import { Command } from '../actions/Command';
import CommandStore from '../stores/Command';

const ENTER_KEY_CODE = 13;

export default React.createClass({

  componentWillMount: function () {
    Command.loadIndex();
  },

  getInitialState: function () {
    return {query: ''};
  },

  render: function () {
    return (
      <div>
        <span>> tldr </span>
        <input placeholder='command'
          autofocus
          autocomplete="off"
          onChange={this._handleChange}
          onKeyDown={this._handleEnter}
        />
      </div>
    );
  },

  _handleChange: function (event) {
    this.setState({query: event.target.value});
  },

  _handleEnter: function (event) {
    const query = this.state.query.trim();
    if (event.keyCode === ENTER_KEY_CODE && query) {
      event.preventDefault();
      Command.search(query.toLowerCase());
      this.setState({query: ''});
    }
  }

});
<commit_msg>Highlights the Enter key on software keyboards<commit_after>import React from 'react';

import { Command } from '../actions/Command';
import CommandStore from '../stores/Command';

const ENTER_KEY_CODE = 13;

export default React.createClass({

  componentWillMount: function () {
    Command.loadIndex();
  },

  getInitialState: function () {
    return {query: ''};
  },

  render: function () {
    return (
      <form action=".">
        <span>> tldr </span>
        <input placeholder='command'
          autofocus
          autocomplete="off"
          onChange={this._handleChange}
          onKeyDown={this._handleEnter}
        />
      </form>
    );
  },

  _handleChange: function (event) {
    this.setState({query: event.target.value});
  },

  _handleEnter: function (event) {
    const query = this.state.query.trim();
    if (event.keyCode === ENTER_KEY_CODE && query) {
      event.preventDefault();
      Command.search(query.toLowerCase());
      this.setState({query: ''});
    }
  }

});
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
// import './addbutton.scss';

import React from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';

import { getSelectedBlockNode } from '../util';

/**
 * Implementation of the medium-link side `+` button to insert various rich blocks
 * like Images/Embeds/Videos.
 */
export default class AddButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      style: {},
      visible: false,
      isOpen: false,
    };
    this.node = null;
    this.blockKey = '';
    this.blockType = '';
    this.blockLength = -1;

    this.findNode = this.findNode.bind(this);
    this.hideBlock = this.hideBlock.bind(this);
    this.openToolbar = this.openToolbar.bind(this);
  }

  // To show + button only when text length == 0
  componentWillReceiveProps(newProps) {
    const { editorState } = newProps;
    const contentState = editorState.getCurrentContent();
    const selectionState = editorState.getSelection();
    if (!selectionState.isCollapsed() || selectionState.anchorKey !== selectionState.focusKey || contentState.getBlockForKey(selectionState.getAnchorKey()).getType().indexOf('atomic') >= 0) {
      // console.log('no sel');
      this.hideBlock();
      return;
    }
    const block = contentState.getBlockForKey(selectionState.anchorKey);
    const bkey = block.getKey();
    if (block.getLength() > 0) {
      this.hideBlock();
      return;
    }
    if (block.getType() !== this.blockType) {
      this.blockType = block.getType();
      if (block.getLength() === 0) {
        setTimeout(this.findNode, 0);
      }
      this.blockKey = bkey;
      return;
    }
    if (this.blockKey === bkey) {
      // console.log('block exists');
      if (block.getLength() > 0) {
        this.hideBlock();
      } else {
        this.setState({
          visible: true,
        });
      }
      return;
    }
    this.blockKey = bkey;
    if (block.getLength() > 0) {
      // console.log('no len');
      this.hideBlock();
      return;
    }
    setTimeout(this.findNode, 0);
  }

  hideBlock() {
    if (this.state.visible) {
      this.setState({
        visible: false,
        isOpen: false,
      });
    }
  }

  openToolbar() {
    this.setState({
      isOpen: !this.state.isOpen,
    }, () => { // callback function
      // save page state
      const x = window.scrollX;
      const y = window.scrollY;
      // do focus
      this.props.focus();
      // back previous window state
      window.scrollTo(x, y);
    });
  }

  findNode() {
    // eslint-disable-next-line no-undef
    const node = getSelectedBlockNode(window);
    if (node === this.node) {
      // console.log('Node exists');
      return;
    }
    if (!node) {
      // console.log('no node');
      this.setState({
        visible: false,
        isOpen: false,
      });
      return;
    }
    // const rect = node.getBoundingClientRect();
    this.node = node;
    this.setState({
      visible: true,
      style: {
        top: node.offsetTop - 3,
      },
    });
  }

  render() {
    if (!this.state.visible) {
      return null;
    }
    return (

        <button
          onClick={this.openToolbar}
          className={`md-sb-button md-add-button${this.state.isOpen ? ' md-open-button' : ''}`}
          type="button"
        >
          <svg viewBox="0 0 8 8" height="14" width="14">
            <path d="M3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z" />
          </svg>
        </button>
        {this.state.isOpen ? (
          <TransitionGroup>
            {this.props.sideButtons.map((button) => {
              const Button = button.component;
              const extraProps = button.props ? button.props : {};
              return (
                <CSSTransition
                  key={button.title}
                  classNames="md-add-btn-anim"
                  appear
                  timeout={{
                    enter: 200,
                    exit: 100,
                    appear: 100,
                  }}
                >
                  <Button
                    {...extraProps}
                    getEditorState={this.props.getEditorState}
                    setEditorState={this.props.setEditorState}
                    close={this.openToolbar}
                  />
                </CSSTransition>
              );
            })}
          </TransitionGroup>
        ) : null}

    );
  }
}

AddButton.propTypes = {
  focus: PropTypes.func,
  getEditorState: PropTypes.func.isRequired,
  setEditorState: PropTypes.func.isRequired,
  sideButtons: PropTypes.arrayOf(PropTypes.object),
};
<commit_msg>Hide side toolbar when editor does not have focus. (#166)<commit_after>import PropTypes from 'prop-types';
// import './addbutton.scss';

import React from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';

import { getSelectedBlockNode } from '../util';

/**
 * Implementation of the medium-link side `+` button to insert various rich blocks
 * like Images/Embeds/Videos.
 */
export default class AddButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      style: {},
      visible: false,
      isOpen: false,
    };
    this.node = null;
    this.blockKey = '';
    this.blockType = '';
    this.blockLength = -1;

    this.findNode = this.findNode.bind(this);
    this.hideBlock = this.hideBlock.bind(this);
    this.openToolbar = this.openToolbar.bind(this);
  }

  // To show + button only when text length == 0
  componentWillReceiveProps(newProps) {
    const { editorState } = newProps;
    const contentState = editorState.getCurrentContent();
    const selectionState = editorState.getSelection();
    const hasFocus = editorState.getSelection().getHasFocus();
    if (!selectionState.isCollapsed() || selectionState.anchorKey !== selectionState.focusKey || contentState.getBlockForKey(selectionState.getAnchorKey()).getType().indexOf('atomic') >= 0) {
      // console.log('no sel');
      this.hideBlock();
      return;
    }
    const block = contentState.getBlockForKey(selectionState.anchorKey);
    const bkey = block.getKey();
    if (block.getLength() > 0) {
      this.hideBlock();
      return;
    }
    if (block.getType() !== this.blockType) {
      this.blockType = block.getType();
      if (block.getLength() === 0) {
        setTimeout(this.findNode, 0);
      }
      this.blockKey = bkey;
      return;
    }
    if (this.blockKey === bkey) {
      // console.log('block exists');
      if (block.getLength() > 0) {
        this.hideBlock();
      } else {
        this.setState({
          visible: hasFocus,
        });
      }
      return;
    }
    this.blockKey = bkey;
    if (block.getLength() > 0) {
      // console.log('no len');
      this.hideBlock();
      return;
    }
    setTimeout(this.findNode, 0);
  }

  hideBlock() {
    if (this.state.visible) {
      this.setState({
        visible: false,
        isOpen: false,
      });
    }
  }

  openToolbar() {
    this.setState({
      isOpen: !this.state.isOpen,
    }, () => { // callback function
      // save page state
      const x = window.scrollX;
      const y = window.scrollY;
      // do focus
      this.props.focus();
      // back previous window state
      window.scrollTo(x, y);
    });
  }

  findNode() {
    const { editorState } = this.props;
    const hasFocus = editorState.getSelection().getHasFocus();
    // eslint-disable-next-line no-undef
    const node = getSelectedBlockNode(window);
    if (node === this.node) {
      // console.log('Node exists');
      return;
    }
    if (!node) {
      // console.log('no node');
      this.setState({
        visible: false,
        isOpen: false,
      });
      return;
    }
    // const rect = node.getBoundingClientRect();
    this.node = node;
    this.setState({
      visible: hasFocus,
      style: {
        top: node.offsetTop - 3,
      },
    });
  }

  render() {
    if (!this.state.visible) {
      return null;
    }
    return (

        <button
          onClick={this.openToolbar}
          className={`md-sb-button md-add-button${this.state.isOpen ? ' md-open-button' : ''}`}
          type="button"
        >
          <svg viewBox="0 0 8 8" height="14" width="14">
            <path d="M3 0v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z" />
          </svg>
        </button>
        {this.state.isOpen ? (
          <TransitionGroup>
            {this.props.sideButtons.map((button) => {
              const Button = button.component;
              const extraProps = button.props ? button.props : {};
              return (
                <CSSTransition
                  key={button.title}
                  classNames="md-add-btn-anim"
                  appear
                  timeout={{
                    enter: 200,
                    exit: 100,
                    appear: 100,
                  }}
                >
                  <Button
                    {...extraProps}
                    getEditorState={this.props.getEditorState}
                    setEditorState={this.props.setEditorState}
                    close={this.openToolbar}
                  />
                </CSSTransition>
              );
            })}
          </TransitionGroup>
        ) : null}

    );
  }
}

AddButton.propTypes = {
  focus: PropTypes.func,
  getEditorState: PropTypes.func.isRequired,
  setEditorState: PropTypes.func.isRequired,
  sideButtons: PropTypes.arrayOf(PropTypes.object),
};
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import AppBar from 'material-ui/AppBar';
import FlatButton from 'material-ui/FlatButton';
import { connect } from 'react-redux';
import * as actions from '../actions/index';

class AppHeader extends Component {
	renderButtons(){
		// if a user is currently authenticated
		if(this.props.auth){
			// render the help and signout buttons
			return (

					<FlatButton className='help-button' label="Help" />
					<FlatButton className='signout-button' label="Signout" />

			);
		} else { // else
			// render the signup and signin buttons
			return (

					<FlatButton className='signup-button' label="Signup" />
					<FlatButton className='signin-button' label="Signin" />

			);
		}
	}
	render(){
		return (
			<AppBar
				title="Icebox"
				children={this.renderButtons()}
			/>
		);
	}
}

function mapStateToProps(state) {
	return { auth: state.auth };
}

export default connect(mapStateToProps)(AppHeader);<commit_msg>[pull] creates methods and state for appDrawer component in appHeader<commit_after>import React, { Component } from 'react';
import AppBar from 'material-ui/AppBar';
import AppDrawer from './appDrawer';
import FlatButton from 'material-ui/FlatButton';
import { connect } from 'react-redux';
import * as actions from '../actions/index';

class AppHeader extends Component {
	constructor(props){
		super(props);
		this.state = {
			drawerOpen: false
		}
	}
	// Methods for handling AppDrawer behavior
	handleToggle(){this.setState({drawerOpen: !this.state.drawerOpen})};

	renderButtons(){
		// if a user is currently authenticated
		if(this.props.auth){
			// render the help and signout buttons
			return (

					<FlatButton className='help-button' label="Help" />
					<FlatButton className='signout-button' label="Signout" />

			);
		} else { // else
			// render the signup and signin buttons
			return (

					<FlatButton className='signup-button' label="Signup" />
					<FlatButton className='signin-button' label="Signin" />

			);
		}
	}
	render(){
		return (

				<AppBar
					title="Icebox"
					iconClassNameLeft="appheader-menu-button"
					onLeftIconButtonTouchTap={() => this.handleToggle()}
					children={this.renderButtons()}
				/>
				<AppDrawer
					className="app-drawer-component"
					drawerOpen={this.state.drawerOpen}
					updateDrawer={this.handleToggle.bind(this)}
				/>

		);
	}
}

function mapStateToProps(state) {
	return { auth: state.auth };
}

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


<commit_before>var CANNON = require('cannon'),
    mesh2shape = require('three-to-cannon');

require('../../../lib/CANNON-shape2mesh');

var Body = {
  dependencies: ['velocity'],

  schema: {
    mass: {default: 5, if: {type: 'dynamic'}},
    linearDamping:  { default: 0.01, if: {type: 'dynamic'}},
    angularDamping: { default: 0.01,  if: {type: 'dynamic'}},
    shape: {default: 'auto', oneOf: ['auto', 'box', 'cylinder', 'sphere', 'hull', 'mesh', 'none']},
    cylinderAxis: {default: 'y', oneOf: ['x', 'y', 'z']},
    sphereRadius: {default: NaN},
    type: {default: 'dynamic', oneOf: ['static', 'dynamic']}
  },

  /**
   * Initializes a body component, assigning it to the physics system and binding listeners for
   * parsing the elements geometry.
   */
  init: function () {
    this.system = this.el.sceneEl.systems.physics;

    if (this.el.sceneEl.hasLoaded) {
      this.initBody();
    } else {
      this.el.sceneEl.addEventListener('loaded', this.initBody.bind(this));
    }
  },

  /**
   * Parses an element's geometry and component metadata to create a CANNON.Body instance for the
   * component.
   */
  initBody: function () {
    var el = this.el,
        data = this.data;

    var obj = this.el.object3D;
    var pos = obj.position;
    var quat = obj.quaternion;

    this.body = new CANNON.Body({
      mass: data.type === 'static' ? 0 : data.mass || 0,
      material: this.system.getMaterial('defaultMaterial'),
      position: new CANNON.Vec3(pos.x, pos.y, pos.z),
      quaternion: new CANNON.Quaternion(quat.x, quat.y, quat.z, quat.w),
      linearDamping: data.linearDamping,
      angularDamping: data.angularDamping,
      type: data.type === 'dynamic' ? CANNON.Body.DYNAMIC : CANNON.Body.STATIC,
    });

    // Matrix World must be updated at root level, if scale is to be applied – updateMatrixWorld()
    // only checks an object's parent, not the rest of the ancestors. Hence, a wrapping entity with
    // scale="0.5 0.5 0.5" will be ignored.
    // Reference: https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js#L511-L541
    // Potential fix: https://github.com/mrdoob/three.js/pull/7019
    this.el.object3D.updateMatrixWorld(true);

    if(data.shape !== 'none') {
      var options = data.shape === 'auto' ? undefined : AFRAME.utils.extend({}, this.data, {
        type: mesh2shape.Type[data.shape.toUpperCase()]
      });

      var shape = mesh2shape(this.el.object3D, options);

      if (!shape) {
        el.addEventListener('object3dset', this.initBody.bind(this));
        return;
      }
      this.body.addShape(shape, shape.offset, shape.orientation);

      // Show wireframe
      if (this.system.debug) {
        this.shouldUpdateWireframe = true;
      }

      this.isLoaded = true;
    }

    this.el.body = this.body;
    this.body.el = el;

    // If component wasn't initialized when play() was called, finish up.
    if (this.isPlaying) {
      this._play();
    }

    if (this.isLoaded) {
      this.el.emit('body-loaded', {body: this.el.body});
    }
  },

  addShape: function(shape, offset, orientation) {
    if (this.data.shape !== 'none') {
      console.warn('shape can only be added if shape property is none');
      return;
    }

    if (!shape) {
      console.warn('shape cannot be null');
      return;
    }

    if (!this.body) {
      console.warn('shape cannot be added before body is loaded');
      return;
    }
    this.body.addShape(shape, offset, orientation);

    if (this.system.debug) {
      this.shouldUpdateWireframe = true;
    }

    this.shouldUpdateBody = true;
  },

  tick: function () {
    if (this.shouldUpdateBody) {
      this.isLoaded = true;

      this._play();

      this.el.emit('body-loaded', {body: this.el.body});
      this.shouldUpdateBody = false;
    }

    if (this.shouldUpdateWireframe) {
      this.createWireframe(this.body);
      this.shouldUpdateWireframe = false;
    }
  },

  /**
   * Registers the component with the physics system, if ready.
   */
  play: function () {
    if (this.isLoaded) this._play();
  },

  /**
   * Internal helper to register component with physics system.
   */
  _play: function () {
    this.syncToPhysics();
    this.system.addComponent(this);
    this.system.addBody(this.body);
    if (this.wireframe) this.el.sceneEl.object3D.add(this.wireframe);
  },

  /**
   * Unregisters the component with the physics system.
   */
  pause: function () {
    if (this.isLoaded) this._pause();
  },

  _pause: function () {
    this.system.removeComponent(this);
    if (this.body) this.system.removeBody(this.body);
    if (this.wireframe) this.el.sceneEl.object3D.remove(this.wireframe);
  },

  /**
   * Updates the CANNON.Body instance, where possible.
   */
  update: function (prevData) {
    if (!this.body) return;

    var data = this.data;

    if (prevData.type != undefined && data.type != prevData.type) {
      this.body.type = data.type === 'dynamic' ? CANNON.Body.DYNAMIC : CANNON.Body.STATIC;
    }

    this.body.mass = data.mass || 0;
    if (data.type === 'dynamic') {
      this.body.linearDamping = data.linearDamping;
      this.body.angularDamping = data.angularDamping;
    }
    if (data.mass !== prevData.mass) {
      this.body.updateMassProperties();
    }
    if (this.body.updateProperties) this.body.updateProperties();
  },

  /**
   * Removes the component and all physics and scene side effects.
   */
  remove: function () {
    delete this.body.el;
    delete this.body;
    delete this.el.body;
    delete this.wireframe;
  },

  beforeStep: function () {
    if (this.body.mass === 0) {
      this.syncToPhysics();
    }
  },

  step: function () {
    if (this.body.mass !== 0) {
      this.syncFromPhysics();
    }
  },

  /**
   * Creates a wireframe for the body, for debugging.
   * TODO(donmccurdy) – Refactor this into a standalone utility or component.
   * @param  {CANNON.Body} body
   * @param  {CANNON.Shape} shape
   */
  createWireframe: function (body) {
    if (this.wireframe) {
      this.el.sceneEl.object3D.remove(this.wireframe);
      delete this.wireframe;
    }
    this.wireframe = new THREE.Object3D();
    this.el.sceneEl.object3D.add(this.wireframe);

    var offset, mesh;
    var orientation = new THREE.Quaternion();
    for (var i = 0; i < this.body.shapes.length; i++)
    {
      offset = this.body.shapeOffsets[i],
      orientation.copy(this.body.shapeOrientations[i]),
      mesh = CANNON.shape2mesh(this.body).children[i];

      var wireframe = new THREE.LineSegments(
        new THREE.EdgesGeometry(mesh.geometry),
        new THREE.LineBasicMaterial({color: 0xff0000})
      );

      if (offset) {
        wireframe.position.copy(offset);
      }

      if (orientation) {
        wireframe.quaternion.copy(orientation);
      }

      this.wireframe.add(wireframe);
    }

    this.syncWireframe();
  },

  /**
   * Updates the debugging wireframe's position and rotation.
   */
  syncWireframe: function () {
    var offset,
        wireframe = this.wireframe;

    if (!this.wireframe) return;

    // Apply rotation. If the shape required custom orientation, also apply
    // that on the wireframe.
    wireframe.quaternion.copy(this.body.quaternion);
    if (wireframe.orientation) {
      wireframe.quaternion.multiply(wireframe.orientation);
    }

    // Apply position. If the shape required custom offset, also apply that on
    // the wireframe.
    wireframe.position.copy(this.body.position);
    if (wireframe.offset) {
      offset = wireframe.offset.clone().applyQuaternion(wireframe.quaternion);
      wireframe.position.add(offset);
    }

    wireframe.updateMatrix();
  },

  /**
   * Updates the CANNON.Body instance's position, velocity, and rotation, based on the scene.
   */
  syncToPhysics: (function () {
    var q =  new THREE.Quaternion(),
        v = new THREE.Vector3();
    return function () {
      var el = this.el,
          parentEl = el.parentEl,
          body = this.body;

      if (!body) return;

      if (el.components.velocity) body.velocity.copy(el.getAttribute('velocity'));

      if (parentEl.isScene) {
        body.quaternion.copy(el.object3D.quaternion);
        body.position.copy(el.object3D.position);
      } else {
        el.object3D.getWorldQuaternion(q);
        body.quaternion.copy(q);
        el.object3D.getWorldPosition(v);
        body.position.copy(v);
      }

      if (this.body.updateProperties) this.body.updateProperties();
      if (this.wireframe) this.syncWireframe();
    };
  }()),

  /**
   * Updates the scene object's position and rotation, based on the physics simulation.
   */
  syncFromPhysics: (function () {
    var v = new THREE.Vector3(),
        q1 = new THREE.Quaternion(),
        q2 = new THREE.Quaternion();
    return function () {
      var el = this.el,
          parentEl = el.parentEl,
          body = this.body;

      if (!body) return;

      if (parentEl.isScene) {
        el.object3D.quaternion.copy(body.quaternion);
        el.object3D.position.copy(body.position);
      } else {
        // TODO - Nested rotation doesn't seem to be working as expected.
        q1.copy(body.quaternion);
        parentEl.object3D.getWorldQuaternion(q2);
        q1.multiply(q2.inverse());
        el.object3D.quaternion.copy(q1);

        v.copy(body.position);
        parentEl.object3D.worldToLocal(v);
        el.object3D.position.copy(v);
      }

      if (this.wireframe) this.syncWireframe();
    };
  }())
};

module.exports.definition = Body;
module.exports.Component = AFRAME.registerComponent('body', Body);
<commit_msg>check for existence of body property in remove<commit_after>var CANNON = require('cannon'),
    mesh2shape = require('three-to-cannon');

require('../../../lib/CANNON-shape2mesh');

var Body = {
  dependencies: ['velocity'],

  schema: {
    mass: {default: 5, if: {type: 'dynamic'}},
    linearDamping:  { default: 0.01, if: {type: 'dynamic'}},
    angularDamping: { default: 0.01,  if: {type: 'dynamic'}},
    shape: {default: 'auto', oneOf: ['auto', 'box', 'cylinder', 'sphere', 'hull', 'mesh', 'none']},
    cylinderAxis: {default: 'y', oneOf: ['x', 'y', 'z']},
    sphereRadius: {default: NaN},
    type: {default: 'dynamic', oneOf: ['static', 'dynamic']}
  },

  /**
   * Initializes a body component, assigning it to the physics system and binding listeners for
   * parsing the elements geometry.
   */
  init: function () {
    this.system = this.el.sceneEl.systems.physics;

    if (this.el.sceneEl.hasLoaded) {
      this.initBody();
    } else {
      this.el.sceneEl.addEventListener('loaded', this.initBody.bind(this));
    }
  },

  /**
   * Parses an element's geometry and component metadata to create a CANNON.Body instance for the
   * component.
   */
  initBody: function () {
    var el = this.el,
        data = this.data;

    var obj = this.el.object3D;
    var pos = obj.position;
    var quat = obj.quaternion;

    this.body = new CANNON.Body({
      mass: data.type === 'static' ? 0 : data.mass || 0,
      material: this.system.getMaterial('defaultMaterial'),
      position: new CANNON.Vec3(pos.x, pos.y, pos.z),
      quaternion: new CANNON.Quaternion(quat.x, quat.y, quat.z, quat.w),
      linearDamping: data.linearDamping,
      angularDamping: data.angularDamping,
      type: data.type === 'dynamic' ? CANNON.Body.DYNAMIC : CANNON.Body.STATIC,
    });

    // Matrix World must be updated at root level, if scale is to be applied – updateMatrixWorld()
    // only checks an object's parent, not the rest of the ancestors. Hence, a wrapping entity with
    // scale="0.5 0.5 0.5" will be ignored.
    // Reference: https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js#L511-L541
    // Potential fix: https://github.com/mrdoob/three.js/pull/7019
    this.el.object3D.updateMatrixWorld(true);

    if(data.shape !== 'none') {
      var options = data.shape === 'auto' ? undefined : AFRAME.utils.extend({}, this.data, {
        type: mesh2shape.Type[data.shape.toUpperCase()]
      });

      var shape = mesh2shape(this.el.object3D, options);

      if (!shape) {
        el.addEventListener('object3dset', this.initBody.bind(this));
        return;
      }
      this.body.addShape(shape, shape.offset, shape.orientation);

      // Show wireframe
      if (this.system.debug) {
        this.shouldUpdateWireframe = true;
      }

      this.isLoaded = true;
    }

    this.el.body = this.body;
    this.body.el = el;

    // If component wasn't initialized when play() was called, finish up.
    if (this.isPlaying) {
      this._play();
    }

    if (this.isLoaded) {
      this.el.emit('body-loaded', {body: this.el.body});
    }
  },

  addShape: function(shape, offset, orientation) {
    if (this.data.shape !== 'none') {
      console.warn('shape can only be added if shape property is none');
      return;
    }

    if (!shape) {
      console.warn('shape cannot be null');
      return;
    }

    if (!this.body) {
      console.warn('shape cannot be added before body is loaded');
      return;
    }
    this.body.addShape(shape, offset, orientation);

    if (this.system.debug) {
      this.shouldUpdateWireframe = true;
    }

    this.shouldUpdateBody = true;
  },

  tick: function () {
    if (this.shouldUpdateBody) {
      this.isLoaded = true;

      this._play();

      this.el.emit('body-loaded', {body: this.el.body});
      this.shouldUpdateBody = false;
    }

    if (this.shouldUpdateWireframe) {
      this.createWireframe(this.body);
      this.shouldUpdateWireframe = false;
    }
  },

  /**
   * Registers the component with the physics system, if ready.
   */
  play: function () {
    if (this.isLoaded) this._play();
  },

  /**
   * Internal helper to register component with physics system.
   */
  _play: function () {
    this.syncToPhysics();
    this.system.addComponent(this);
    this.system.addBody(this.body);
    if (this.wireframe) this.el.sceneEl.object3D.add(this.wireframe);
  },

  /**
   * Unregisters the component with the physics system.
   */
  pause: function () {
    if (this.isLoaded) this._pause();
  },

  _pause: function () {
    this.system.removeComponent(this);
    if (this.body) this.system.removeBody(this.body);
    if (this.wireframe) this.el.sceneEl.object3D.remove(this.wireframe);
  },

  /**
   * Updates the CANNON.Body instance, where possible.
   */
  update: function (prevData) {
    if (!this.body) return;

    var data = this.data;

    if (prevData.type != undefined && data.type != prevData.type) {
      this.body.type = data.type === 'dynamic' ? CANNON.Body.DYNAMIC : CANNON.Body.STATIC;
    }

    this.body.mass = data.mass || 0;
    if (data.type === 'dynamic') {
      this.body.linearDamping = data.linearDamping;
      this.body.angularDamping = data.angularDamping;
    }
    if (data.mass !== prevData.mass) {
      this.body.updateMassProperties();
    }
    if (this.body.updateProperties) this.body.updateProperties();
  },

  /**
   * Removes the component and all physics and scene side effects.
   */
  remove: function () {
    if (this.body) {
      delete this.body.el;
      delete this.body;
    }
    delete this.el.body;
    delete this.wireframe;
  },

  beforeStep: function () {
    if (this.body.mass === 0) {
      this.syncToPhysics();
    }
  },

  step: function () {
    if (this.body.mass !== 0) {
      this.syncFromPhysics();
    }
  },

  /**
   * Creates a wireframe for the body, for debugging.
   * TODO(donmccurdy) – Refactor this into a standalone utility or component.
   * @param  {CANNON.Body} body
   * @param  {CANNON.Shape} shape
   */
  createWireframe: function (body) {
    if (this.wireframe) {
      this.el.sceneEl.object3D.remove(this.wireframe);
      delete this.wireframe;
    }
    this.wireframe = new THREE.Object3D();
    this.el.sceneEl.object3D.add(this.wireframe);

    var offset, mesh;
    var orientation = new THREE.Quaternion();
    for (var i = 0; i < this.body.shapes.length; i++)
    {
      offset = this.body.shapeOffsets[i],
      orientation.copy(this.body.shapeOrientations[i]),
      mesh = CANNON.shape2mesh(this.body).children[i];

      var wireframe = new THREE.LineSegments(
        new THREE.EdgesGeometry(mesh.geometry),
        new THREE.LineBasicMaterial({color: 0xff0000})
      );

      if (offset) {
        wireframe.position.copy(offset);
      }

      if (orientation) {
        wireframe.quaternion.copy(orientation);
      }

      this.wireframe.add(wireframe);
    }

    this.syncWireframe();
  },

  /**
   * Updates the debugging wireframe's position and rotation.
   */
  syncWireframe: function () {
    var offset,
        wireframe = this.wireframe;

    if (!this.wireframe) return;

    // Apply rotation. If the shape required custom orientation, also apply
    // that on the wireframe.
    wireframe.quaternion.copy(this.body.quaternion);
    if (wireframe.orientation) {
      wireframe.quaternion.multiply(wireframe.orientation);
    }

    // Apply position. If the shape required custom offset, also apply that on
    // the wireframe.
    wireframe.position.copy(this.body.position);
    if (wireframe.offset) {
      offset = wireframe.offset.clone().applyQuaternion(wireframe.quaternion);
      wireframe.position.add(offset);
    }

    wireframe.updateMatrix();
  },

  /**
   * Updates the CANNON.Body instance's position, velocity, and rotation, based on the scene.
   */
  syncToPhysics: (function () {
    var q =  new THREE.Quaternion(),
        v = new THREE.Vector3();
    return function () {
      var el = this.el,
          parentEl = el.parentEl,
          body = this.body;

      if (!body) return;

      if (el.components.velocity) body.velocity.copy(el.getAttribute('velocity'));

      if (parentEl.isScene) {
        body.quaternion.copy(el.object3D.quaternion);
        body.position.copy(el.object3D.position);
      } else {
        el.object3D.getWorldQuaternion(q);
        body.quaternion.copy(q);
        el.object3D.getWorldPosition(v);
        body.position.copy(v);
      }

      if (this.body.updateProperties) this.body.updateProperties();
      if (this.wireframe) this.syncWireframe();
    };
  }()),

  /**
   * Updates the scene object's position and rotation, based on the physics simulation.
   */
  syncFromPhysics: (function () {
    var v = new THREE.Vector3(),
        q1 = new THREE.Quaternion(),
        q2 = new THREE.Quaternion();
    return function () {
      var el = this.el,
          parentEl = el.parentEl,
          body = this.body;

      if (!body) return;

      if (parentEl.isScene) {
        el.object3D.quaternion.copy(body.quaternion);
        el.object3D.position.copy(body.position);
      } else {
        // TODO - Nested rotation doesn't seem to be working as expected.
        q1.copy(body.quaternion);
        parentEl.object3D.getWorldQuaternion(q2);
        q1.multiply(q2.inverse());
        el.object3D.quaternion.copy(q1);

        v.copy(body.position);
        parentEl.object3D.worldToLocal(v);
        el.object3D.position.copy(v);
      }

      if (this.wireframe) this.syncWireframe();
    };
  }())
};

module.exports.definition = Body;
module.exports.Component = AFRAME.registerComponent('body', Body);
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from "react";
import DatePicker from "react-datepicker";
require('react-datepicker/dist/react-datepicker.css');
import moment from "moment";

import { dateFormat } from "../utils";

export default class DateInput extends Component {
  shouldComponentUpdate(nextProps) {
    //return this.props.field !== nextProps.field;
    return true;
  }

  render() {
    const { field, placeholder, ...rest } = this.props;
    return (
      <DatePicker
        selected={field.value ? moment(field.value) : null}
        placeholderText={placeholder}
        dateFormat={dateFormat} {...field}
        {...rest} />)
  }
}

DateInput.propTypes = {
  field: PropTypes.object.isRequired,
}
<commit_msg>Add back shouldComponentUpdate for dateInput component<commit_after>import React, { Component, PropTypes } from "react";
import DatePicker from "react-datepicker";
require('react-datepicker/dist/react-datepicker.css');
import moment from "moment";

import { dateFormat } from "../utils";

export default class DateInput extends Component {
  shouldComponentUpdate(nextProps) {
    return this.props.field !== nextProps.field;
  }

  render() {
    const { field, placeholder, ...rest } = this.props;
    return (
      <DatePicker
        selected={field.value ? moment(field.value) : null}
        placeholderText={placeholder}
        dateFormat={dateFormat} {...field}
        {...rest} />)
  }
}

DateInput.propTypes = {
  field: PropTypes.object.isRequired,
}
<|endoftext|>