<commit_before>import React, {Component} from "react";
import Color from "color";

class Grid extends Component {

    // //length, height string - canvas length and height in px;
    // updateCanvas = (length, height) => {
    //     var canvas = document.getElementById("game-grid");
    //     var context = canvas.getContext("2d");
    //
    //     for (let x = 0.5; x < length; x += 10) {
    //         context.moveTo(x, 0);
    //         context.lineTo(x, height);
    //     }
    //
    //     for (let y = 0.5; y < height; y += 10) {
    //         context.moveTo(0, y);
    //         context.lineTo(length, y);
    //     }
    //
    //     context.strokeStyle = "#ddd";
    //     context.stroke();
    // }

    handleClick = (e) => {
        let canvas = document.getElementById("game-grid");
        let ctx = canvas.getContext("2d");

        let sx = e.nativeEvent.offsetX;
        let sy = e.nativeEvent.offsetY;
        let pxlColor = Color(ctx.getImageData(sx,sy,1,1).data)

        console.log(`sx: ${sx}; sy: ${sy}\ncolor: ${pxlColor}\nimageData: ${ctx.getImageData(sx,sy,1,1).data}`)
        console.log(pxlColor.rgbNumber())
        ctx.fillStyle = "yellow";
        ctx.fillRect(sx-(sx%10), sy-(sy%10), 10, 10);

    }

    componentDidMount() {
        let width = parseInt(this.props.gridWidth, 10);
        let height = parseInt(this.props.gridHeight, 10);
        this.props.onUpdate(width, height);
    }

    render() {
        return(
            <canvas
                id="game-grid"
                width={this.props.gridWidth}
                height={this.props.gridHeight}
                onClick={this.handleClick}></canvas>
        );
    }
}

export default Grid;
<commit_msg>Add game reset feature<commit_after>import React, {Component} from "react";
import Color from "color";

class Grid extends Component {

    handleClick = (e) => {
        let canvas = document.getElementById("game-grid");
        let ctx = canvas.getContext("2d");

        let sx = e.nativeEvent.offsetX;
        let sy = e.nativeEvent.offsetY;
        let pxlColor = Color(ctx.getImageData(sx,sy,1,1).data)

        console.log(`sx: ${sx}; sy: ${sy}\ncolor: ${pxlColor}\nimageData: ${ctx.getImageData(sx,sy,1,1).data}`)
        console.log(pxlColor.rgbNumber())
        ctx.fillStyle = "yellow";
        ctx.fillRect(sx-(sx%10), sy-(sy%10), 10, 10);

    }

    componentDidMount() {
        let width = parseInt(this.props.gridWidth, 10);
        let height = parseInt(this.props.gridHeight, 10);
        this.props.onUpdate(width, height);
    }

    render() {
        return(
            <canvas
                id="game-grid"
                width={this.props.gridWidth}
                height={this.props.gridHeight}
                onClick={this.handleClick}></canvas>
        );
    }
}

export default Grid;
<|endoftext|>


<commit_before> import React from 'react';
import { Switch, Route } from 'react-router-dom';
import RecipesList from '../containers/RecipesList';
import ModifyTitle from '../containers/ModifyTitle';
import ModifyIngredients from '../containers/ModifyIngredients';
import SearchIngredient from '../containers/SearchIngredient';
import IngredientDetails from '../containers/IngredientDetails';
import ReviewRecipe from '../containers/ReviewRecipe';
import { Grid, Row, Col } from 'react-bootstrap';

const Main = (props) => {
  return (
    <Grid>
      <Row>
        <Col sm={12} lg={6} lgOffset={3}>
          <Switch>
            <Route exact path="/" component={RecipesList} />

            <Route path="/modify-title" render={() => (
              <ModifyTitle
                nextButton={true}
                nextButtonStyle={{
                  marginBottom: '10px',
                  marginTop: '10px'
                }}
              />
            )} />

            <Route path="/modify-ingredients" render={() => (
              <ModifyIngredients
                nextButton={true}
                plusButton={true}
                nextButtonStyle={{ marginBottom: '10px' }}
              />
            )} />

            <Route path="/search-ingredient" component={SearchIngredient} />

            <Route path="/ingredient-details" render={({ location }) => (
              <IngredientDetails
                location={location}
              />
            )} />

            <Route path="/review" render={() => (
              <ReviewRecipe
                buttonStyle={{
                  marginTop: '20px',
                  marginBottom: '10px'
                }} />
              )} />
            </Switch>
        </Col>
      </Row>
    </Grid>
  );
};

export default Main;
<commit_msg>Add md breakpoint for Main component so transition from sm to lg screens are more smooth.<commit_after> import React from 'react';
import { Switch, Route } from 'react-router-dom';
import RecipesList from '../containers/RecipesList';
import ModifyTitle from '../containers/ModifyTitle';
import ModifyIngredients from '../containers/ModifyIngredients';
import SearchIngredient from '../containers/SearchIngredient';
import IngredientDetails from '../containers/IngredientDetails';
import ReviewRecipe from '../containers/ReviewRecipe';
import { Grid, Row, Col } from 'react-bootstrap';

const Main = (props) => {
  return (
    <Grid>
      <Row>
        <Col sm={12} md={8} lg={6} mdOffset={2} lgOffset={3}>
          <Switch>
            <Route exact path="/" component={RecipesList} />

            <Route path="/modify-title" render={() => (
              <ModifyTitle
                nextButton={true}
                nextButtonStyle={{
                  marginBottom: '10px',
                  marginTop: '10px'
                }}
              />
            )} />

            <Route path="/modify-ingredients" render={() => (
              <ModifyIngredients
                nextButton={true}
                plusButton={true}
                nextButtonStyle={{ marginBottom: '10px' }}
              />
            )} />

            <Route path="/search-ingredient" component={SearchIngredient} />

            <Route path="/ingredient-details" render={({ location }) => (
              <IngredientDetails
                location={location}
              />
            )} />

            <Route path="/review" render={() => (
              <ReviewRecipe
                buttonStyle={{
                  marginTop: '20px',
                  marginBottom: '10px'
                }} />
              )} />
            </Switch>
        </Col>
      </Row>
    </Grid>
  );
};

export default Main;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import AppBar from 'material-ui/AppBar';

const Main = ({ children }) => (

    <AppBar
      title="Random quote machine"
      showMenuIconButton={false}
      zDepth={2}
    />
    {/* this will render the child routes */}
    {children}

);

Main.propTypes = {
  children: PropTypes.element.isRequired,
};

export default Main;
<commit_msg>Not really random<commit_after>import React, { PropTypes } from 'react';
import AppBar from 'material-ui/AppBar';

const Main = ({ children }) => (

    <AppBar
      title="Quote machine"
      showMenuIconButton={false}
      zDepth={2}
    />
    {/* this will render the child routes */}
    {children}

);

Main.propTypes = {
  children: PropTypes.element.isRequired,
};

export default Main;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Header from './Header.js';
import Button from './Button';

export default class Main extends Component {
  render() {
    return (

On Saturday, August 12th, 2017, The City of Peoria will host the area’s first civic hackathon to engage the local tech community for the purpose of innovating new civic tech solutions.

 Peoria Civic Hackathon 2017 is taking place in conjunction with Ignite Peoria, a day-long event at the Peoria Civic Center that attracts thousands of visitors to interact with and learn about the thriving arts and tech community in the region.

What is a Civic Hackathon?

Individuals or teams of 2-7 participants will come together for a coding marathon to solve a local challenge. After arriving to the Hackathon, participants will receive a Challenge Statement and access to relevant data sets. They will then be free to utilize this data, as well as other publicly available data, to create a website, app, or other tool that could improve the lives of people who live, work, and play in the Peoria area.

After the end of the 10 hour hacking session, teams will demo their projects to a panel of judges, who will decide which 2 teams created the best solution to the Challenge Statement during the hackathon. The winning and runner-up team will then be awarded cash prizes to celebrate their work.

Agenda

Friday Night Social @ TBD

6-6:30 PM: Check-in, pick up a name tag, and grab a drink (if you wish)!

6:30-7 PM: Welcome from the City of Peoria and Q & A session about the Hackathon

Use this time to gather with your team or find a team if you are a solo participant looking to join a team. Members from the City of Peoria Innovation Team will also be open to answering any questions about the hackathon during this time

7-8 PM: Mingle with fellow hackers!

Use this time to brainstorm with your team, welcome new members to your team, or just meet some new people and have fun!

Saturday Meet @ Civic Center Verizon Lobby

8-8:30 AM: Check-in and Breakfast

Stop at the registration table to check-in, grab a name tag, make sure all members of your team are registered, and find out where your team’s work space is located. Teams will have the opportunity to move around once the Hackathon period begins.

8:30-9 AM: Opening Remarks from the i-team and City of Peoria IT Department

This will be the first time that Hackathon participants will hear the challenge statement that they will be solving for during the 10-hour hack. Also, a word from our sponsors.

9 AM: HACKING BEGINS – GET HACKING!

Registration closes

1 PM: Lunch – Grab a bite to eat and don’t forget to hydrate!

5 PM: Dinner – You’ll want a little extra fuel for these last few hours!

7 PM: HACKING ENDS

At 7 PM, your project must be submitted and your team must be ready to demonstrate its functionality to the judges panel.

7-7:30 PM: Presentation of demos

Present your projects and see what other teams were able to put together!

7:30-7:45 PM: Judging Period

7:45-8:00 PM: Winners Announced and Presentation of Awards

						<Button href="/faq" styleName="goldbutton">Learn More</Button>

    );
  }
}
<commit_msg>updated content<commit_after>import React, { Component } from 'react';
import Header from './Header.js';
import Button from './Button';

export default class Main extends Component {
  render() {
    return (

On Saturday, August 12th, 2017, The City of Peoria will host the area’s first civic hackathon to engage the local tech community to innovate new civic tech solutions.

 Peoria Civic Hackathon 2017 is taking place in conjunction with Ignite Peoria, an event at the Peoria Civic Center that attracts thousands of visitors to interact with the City's thriving arts and tech community.

What is the 2017 Peoria Civic Hackathon?

Individuals or teams of 2-7 participants will come together to solve a local challenge. Participants will receive a Challenge Statement and access to relevant data sets. They will then utilize this data to create a website, app, or other tool that could improve the lives of people who live, work, and play in the Peoria area.

After the 10 hour hacking session, teams will demo their projects to a panel of judges who will decide which 2 teams created the best solution to the Challenge Statement. The first and runner-up team will receive cash prizes.

Agenda

Friday Night Social @ TBD

6-6:30 PM: Check-in, pick up a name tag, and grab a drink (if you wish)!

6:30-7 PM: Welcome from the City of Peoria and Q & A session about the Hackathon

Gather with your team or find a team if you are looking to join one. Members from the City of Peoria Innovation Team will answer questions about the hackathon during this time

7-8 PM: Mingle with fellow hackers!

Brainstorm with your team, welcome new team members, or just meet new people and have fun!

Saturday Meet @ Civic Center Verizon Lobby

8-8:30 AM: Check-in and Breakfast

Stop at the registration table to check-in, grab a name tag, make sure all members of your team are registered, and find out where your team’s work space is located. Teams will have the opportunity to move around once the Hackathon period begins.

8:30-9 AM: Opening Remarks from the City of Peoria

This will be the first time that Hackathon participants will hear the challenge statement they will be solving during the 10-hour hack. Also, a word from our sponsors.

9 AM: HACKING BEGINS

Registration closes

1 PM: Lunch

5 PM: Dinner

7 PM: HACKING ENDS

At 7 PM, your project must be submitted and your team must be ready to demonstrate its functionality to the judges panel.

7-7:30 PM: Presentation of demos

Present your projects and see what other teams created!

7:30-7:45 PM: Judging Period

7:45-8:00 PM: Winners Announced and Presentation of Awards

						<Button href="/faq" styleName="goldbutton">Learn More</Button>

    );
  }
}
<|endoftext|>


<commit_before>require('normalize.css/normalize.css');
require('styles/main.css');

var imgData = require('../data/imagedata.json');
import React from 'react';
import ReactDOM from 'react-dom';

//获取图片的数据
function getImgUrl(imgData) {
	var imageDataArr = [];
	for (var i = 0, j = imgData.length; i < j; i++) {
		var singleImageData = imgData[i];
		// singleImageData.imageUrl = require('../images/'+singleImageData.fileName);
		imageDataArr[i] = singleImageData;
	}
	return imageDataArr;
}
var imageDatas = getImgUrl(imgData);

var ImgFigure = React.createClass({
	/*
	点击处理函数
	*/
	handleClick: function(e) {
		this.props.inverse();

		e.stopPropagation();
		e.preventDefault();
	},
	render: function() {
		var styleObj = {};
		if (this.props.arrange.pos) {
			styleObj = this.props.arrange.pos;
		}
		if (this.props.arrange.rotate) {
			styleObj['-webkit-transform'] = 'rotate(' + this.props.arrange.rotate + 'deg)';
		}
		var imageURL = ('../images/' + this.props.data.fileName);

		var imgFigureClassName = "img-figure";
		imgFigureClassName = imgFigureClassName + (this.props.arrange.isInverse ? ' no_inverse' : ' is_inverse');
		return (

{this.props.data.title}

					{this.props.data.desc}

		)
	}
})

function getRandom(min, max) {
	return Math.floor(Math.random() * (max - min) + min)
}

function get30deRandom() {
	return ((Math.random() > 0.5 ? '' : '-') + Math.ceil(Math.random() * 30));
}
var galleryByReact = React.createClass({
	Constant: {
		centerPos: {
			left: 0,
			right: 0
		},
		hPosRange: { //水平范围
			leftSecX: [0, 0],
			rightSecx: [0, 0],
			y: [0, 0]
		},
		vPosRange: { //垂直范围
			x: [0, 0],
			topY: [0, 0]
		}
	},

	/*
	翻转
	*/
	inverse: function(index) {
		return function() {
			var imgsArrangeArr = this.state.imgsArrangeArr;

			imgsArrangeArr[index].isInverse = !imgsArrangeArr[index].isInverse;

			this.setState({
				imgsArrangeArr: imgsArrangeArr
			})
		}.bind(this);
	},
	/*
	 *指定居中哪个图片
	 */
	rearrange: function(centerIndex) {
		var imgsArrangeArr = this.state.imgsArrangeArr,
			Constant = this.Constant,
			centerPos = Constant.centerPos,
			hPosRange = Constant.hPosRange,
			vPosRange = Constant.vPosRange,

			hPosRangeLeftSecX = hPosRange.leftSecX,
			hPosRangeRightSecX = hPosRange.rightSecx,
			hPosRangeY = hPosRange.y,
			vPosRangeTopY = vPosRange.topY,
			vPosRangeX = vPosRange.x,

			topImgNum = Math.floor(Math.random() * 2),
			topImgSpliceIndex = 0,

			imgsArrangeCenterArr = imgsArrangeArr.splice(centerIndex, 1);

		imgsArrangeCenterArr[0].pos = centerPos;

		//中间不需要旋转
		imgsArrangeCenterArr[0].rotate = 0;

		topImgSpliceIndex = Math.floor(Math.random() * (imgsArrangeArr.length - topImgNum));
		var imgsArrangeTopArr = imgsArrangeArr.splice(topImgSpliceIndex, topImgNum);

		//布局上侧的
		imgsArrangeTopArr.forEach(function(value, index) {
			imgsArrangeTopArr[index] = {
				pos: {
					top: getRandom(vPosRangeTopY[0], vPosRangeTopY[1]),
					left: getRandom(vPosRangeX[0], vPosRangeX[1])
				},
				rotate: get30deRandom()
			}
		});

		//两侧
		for (var i = 0, j = imgsArrangeArr.length, k = j / 2; i < j; i++) {
			var hPosRangeLORX = null;

			if (i < k) {
				hPosRangeLORX = hPosRangeLeftSecX;
			} else {
				hPosRangeLORX = hPosRangeRightSecX;
			}
			imgsArrangeArr[i] = {
				pos: {
					top: getRandom(hPosRangeY[0], hPosRangeY[1]),
					left: getRandom(hPosRangeLORX[0], hPosRangeLORX[1])
				},
				rotate: get30deRandom()
			}
		}

		if (imgsArrangeTopArr && imgsArrangeTopArr[0]) {
			imgsArrangeArr.splice(topImgSpliceIndex, 0, imgsArrangeTopArr[0]);
		}

		imgsArrangeArr.splice(centerIndex, 0, imgsArrangeCenterArr[0]);

		this.setState({
			imgsArrangeArr: imgsArrangeArr
		})
	},

	getInitialState: function() {
		return {
			imgsArrangeArr: [
				/*pos: {
						left: 0,
						top: 0
					},
					rotate: 0,
					isInverse: false
				*/

			],
		}
	},

	//计算图片位置
	componentDidMount: function() {
		var stageDOM = ReactDOM.findDOMNode(this.refs.stage),
			stageWidth = stageDOM.scrollWidth,
			stageHeight = stageDOM.scrollHeight,
			halfStageWidth = Math.ceil(stageWidth / 2),
			halfStageHeight = Math.ceil(stageHeight / 2);

		var imgFigureDOM = ReactDOM.findDOMNode(this.refs.imgFigure0),
			imgWidth = imgFigureDOM.scrollWidth,
			imgHeight = imgFigureDOM.scrollHeight,
			halfImgWidth = Math.ceil(imgWidth / 2),
			halfImgHeight = Math.ceil(imgHeight / 2);

		//中心图片
		this.Constant.centerPos = {
			left: halfStageWidth - halfImgWidth,
			top: halfStageHeight - halfImgHeight
		}

		//左右范围
		this.Constant.hPosRange.leftSecX[0] = -halfImgWidth;
		this.Constant.hPosRange.leftSecX[1] = halfStageWidth - 3 * halfImgWidth;
		this.Constant.hPosRange.rightSecx[0] = halfStageWidth + halfImgWidth;
		this.Constant.hPosRange.rightSecx[1] = stageWidth - halfImgWidth;
		this.Constant.hPosRange.y[0] = -halfImgHeight;
		this.Constant.hPosRange.y[1] = stageHeight - halfImgHeight;

		//上下范围
		this.Constant.vPosRange.topY[0] = -halfImgHeight;
		this.Constant.vPosRange.topY[1] = halfStageHeight - 3 * halfImgHeight;
		this.Constant.vPosRange.x[0] = halfStageWidth - imgWidth;
		this.Constant.vPosRange.x[1] = halfImgWidth;

		this.rearrange(0);

	},
	render: function() {

		var imgFigures = [];
		var controlUnits = [];
		imageDatas.forEach(function(value, index) {
			if (!this.state.imgsArrangeArr[index]) {
				this.state.imgsArrangeArr[index] = {
					pos: {
						left: 0,
						top: 0
					},
					rotate: 0,
					isInverse: false,
				}
			}
			imgFigures.push((<ImgFigure data={value} key={'index'+index} ref={'imgFigure' + index}
				arrange={this.state.imgsArrangeArr[index]} inverse={this.inverse(index)}/>));
		}.bind(this));

		return (

					{imgFigures}

					{controlUnits}

		)
	}
})

ReactDOM.render(<galleryByReact/>, document.getElementById('app'));

module.exports = galleryByReact;<commit_msg>ss-controlcenterpic<commit_after>require('normalize.css/normalize.css');
require('styles/main.css');

var imgData = require('../data/imagedata.json');
import React from 'react';
import ReactDOM from 'react-dom';

//获取图片的数据
function getImgUrl(imgData) {
	var imageDataArr = [];
	for (var i = 0, j = imgData.length; i < j; i++) {
		var singleImageData = imgData[i];
		// singleImageData.imageUrl = require('../images/'+singleImageData.fileName);
		imageDataArr[i] = singleImageData;
	}
	return imageDataArr;
}
var imageDatas = getImgUrl(imgData);

var ImgFigure = React.createClass({
	/*
	点击处理函数
	*/
	handleClick: function(e) {

		if(this.props.arrange.isCenter){
			this.props.inverse();
		}else{
			this.props.center();
		}

		e.stopPropagation();
		e.preventDefault();
	},
	render: function() {
		var styleObj = {};
		if (this.props.arrange.pos) {
			styleObj = this.props.arrange.pos;
		}
		if (this.props.arrange.rotate) {
			styleObj['-webkit-transform'] = 'rotate(' + this.props.arrange.rotate + 'deg)';
		}

		if (this.props.arrange.isCenter){
			styleObj.zindex = 11;
		}
		var imageURL = ('../images/' + this.props.data.fileName);

		var imgFigureClassName = 'img-figure';
		imgFigureClassName = imgFigureClassName + (this.props.arrange.isInverse ? ' no_inverse' : ' is_inverse');
		return (

{this.props.data.title}

					{this.props.data.desc}

		)
	}
})

function getRandom(min, max) {
	return Math.floor(Math.random() * (max - min) + min)
}

function get30deRandom() {
	return ((Math.random() > 0.5 ? '' : '-') + Math.ceil(Math.random() * 30));
}
var galleryByReact = React.createClass({
	Constant: {
		centerPos: {
			left: 0,
			right: 0
		},
		hPosRange: { //水平范围
			leftSecX: [0, 0],
			rightSecx: [0, 0],
			y: [0, 0]
		},
		vPosRange: { //垂直范围
			x: [0, 0],
			topY: [0, 0]
		}
	},

	/*
	翻转
	*/
	inverse: function(index) {
		return function() {
			var imgsArrangeArr = this.state.imgsArrangeArr;

			imgsArrangeArr[index].isInverse = !imgsArrangeArr[index].isInverse;

			this.setState({
				imgsArrangeArr: imgsArrangeArr
			})
		}.bind(this);
	},
	/*
	 *指定居中哪个图片
	 */
	rearrange: function(centerIndex) {
		var imgsArrangeArr = this.state.imgsArrangeArr,
			Constant = this.Constant,
			centerPos = Constant.centerPos,
			hPosRange = Constant.hPosRange,
			vPosRange = Constant.vPosRange,

			hPosRangeLeftSecX = hPosRange.leftSecX,
			hPosRangeRightSecX = hPosRange.rightSecx,
			hPosRangeY = hPosRange.y,
			vPosRangeTopY = vPosRange.topY,
			vPosRangeX = vPosRange.x,

			topImgNum = Math.floor(Math.random() * 2),
			topImgSpliceIndex = 0,

			imgsArrangeCenterArr = imgsArrangeArr.splice(centerIndex, 1);

		imgsArrangeCenterArr[0] = {
				pos: centerPos,
				rotate: 0,
				isCenter: true
			}
			//中间不需要旋转

		topImgSpliceIndex = Math.floor(Math.random() * (imgsArrangeArr.length - topImgNum));
		var imgsArrangeTopArr = imgsArrangeArr.splice(topImgSpliceIndex, topImgNum);

		//布局上侧的
		imgsArrangeTopArr.forEach(function(value, index) {
			imgsArrangeTopArr[index] = {
				pos: {
					top: getRandom(vPosRangeTopY[0], vPosRangeTopY[1]),
					left: getRandom(vPosRangeX[0], vPosRangeX[1])
				},
				rotate: get30deRandom(),
				isCenter: false
			}
		});

		//两侧
		for (var i = 0, j = imgsArrangeArr.length, k = j / 2; i < j; i++) {
			var hPosRangeLORX = null;

			if (i < k) {
				hPosRangeLORX = hPosRangeLeftSecX;
			} else {
				hPosRangeLORX = hPosRangeRightSecX;
			}
			imgsArrangeArr[i] = {
				pos: {
					top: getRandom(hPosRangeY[0], hPosRangeY[1]),
					left: getRandom(hPosRangeLORX[0], hPosRangeLORX[1])
				},
				rotate: get30deRandom(),
				isCenter: false
			}
		}

		if (imgsArrangeTopArr && imgsArrangeTopArr[0]) {
			imgsArrangeArr.splice(topImgSpliceIndex, 0, imgsArrangeTopArr[0]);
		}

		imgsArrangeArr.splice(centerIndex, 0, imgsArrangeCenterArr[0]);

		this.setState({
			imgsArrangeArr: imgsArrangeArr
		})
	},

	/*
	 *居中对应index的照片
	 */
	center: function(index) {
		return function() {
			this.rearrange(index);
		}.bind(this)
	},

	getInitialState: function() {
		return {
			imgsArrangeArr: [
				/*pos: {
						left: 0,
						top: 0
					},
					rotate: 0,
					isInverse: false,
					isCenter: false
				*/
			]
		}
	},

	//计算图片位置
	componentDidMount: function() {
		var stageDOM = ReactDOM.findDOMNode(this.refs.stage),
			stageWidth = stageDOM.scrollWidth,
			stageHeight = stageDOM.scrollHeight,
			halfStageWidth = Math.ceil(stageWidth / 2),
			halfStageHeight = Math.ceil(stageHeight / 2);

		var imgFigureDOM = ReactDOM.findDOMNode(this.refs.imgFigure0),
			imgWidth = imgFigureDOM.scrollWidth,
			imgHeight = imgFigureDOM.scrollHeight,
			halfImgWidth = Math.ceil(imgWidth / 2),
			halfImgHeight = Math.ceil(imgHeight / 2);

		//中心图片
		this.Constant.centerPos = {
			left: halfStageWidth - halfImgWidth,
			top: halfStageHeight - halfImgHeight
		}

		//左右范围
		this.Constant.hPosRange.leftSecX[0] = -halfImgWidth;
		this.Constant.hPosRange.leftSecX[1] = halfStageWidth - 3 * halfImgWidth;
		this.Constant.hPosRange.rightSecx[0] = halfStageWidth + halfImgWidth;
		this.Constant.hPosRange.rightSecx[1] = stageWidth - halfImgWidth;
		this.Constant.hPosRange.y[0] = -halfImgHeight;
		this.Constant.hPosRange.y[1] = stageHeight - halfImgHeight;

		//上下范围
		this.Constant.vPosRange.topY[0] = -halfImgHeight;
		this.Constant.vPosRange.topY[1] = halfStageHeight - 3 * halfImgHeight;
		this.Constant.vPosRange.x[0] = halfStageWidth - imgWidth;
		this.Constant.vPosRange.x[1] = halfImgWidth;

		this.rearrange(0);

	},
	render: function() {

		var imgFigures = [];
		var controlUnits = [];
		imageDatas.forEach(function(value, index) {
			if (!this.state.imgsArrangeArr[index]) {
				this.state.imgsArrangeArr[index] = {
					pos: {
						left: 0,
						top: 0
					},
					rotate: 0,
					isInverse: false,
					isCenter: false
				}
			}
			imgFigures.push((<ImgFigure data={value} key={'index'+index} ref={'imgFigure' + index}
				arrange={this.state.imgsArrangeArr[index]} inverse={this.inverse(index)} center={this.center(index)}/>));
		}.bind(this));

		return (

					{imgFigures}

					{controlUnits}

		)
	}
})

ReactDOM.render(<galleryByReact/>, document.getElementById('app'));

module.exports = galleryByReact;<|endoftext|>


<commit_before>import React from "react";
import Radium from "radium";
import Button from "./Button";
import {isMoreMenuExpanded} from "../redux/selectors";
import {expandMoreMenu, collapseMoreMenu} from '../redux/actionCreators';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {styles} from './styles';
import ClickOutside from 'react-click-outside';

export class More extends React.Component {
  handleClickOutside() {
    this.props.collapse();
  }
  render() {
    return(
      <Button kind="toolbar"
              style={styles.buttons.more.moreButton}
              onClick={() =>
                this.props.expanded ? this.props.collapse() : this.props.expand()}>
        More ▾
      </Button>
    );
  }
}

More.propTypes = {
  expanded: React.PropTypes.bool,
  expand: React.PropTypes.func,
  collapse: React.PropTypes.func,
};

export default connect(
  state => ({
    expanded: isMoreMenuExpanded(state),
  }),
  dispatch => bindActionCreators( {
    expand: expandMoreMenu,
    collapse: collapseMoreMenu,
  }, dispatch)
)(ClickOutside(Radium(More)));
<commit_msg>fix unecessary collapse moreMenu action dispatches<commit_after>import React from "react";
import Radium from "radium";
import Button from "./Button";
import {isMoreMenuExpanded} from "../redux/selectors";
import {expandMoreMenu, collapseMoreMenu} from '../redux/actionCreators';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {styles} from './styles';
import ClickOutside from 'react-click-outside';

export class More extends React.Component {
  handleClickOutside() {
    if (this.props.expanded) {
      this.props.collapse();
    }
  }
  render() {
    return(
      <Button kind="toolbar"
              style={styles.buttons.more.moreButton}
              onClick={() =>
                this.props.expanded ? this.props.collapse() : this.props.expand()}>
        More ▾
      </Button>
    );
  }
}

More.propTypes = {
  expanded: React.PropTypes.bool,
  expand: React.PropTypes.func,
  collapse: React.PropTypes.func,
};

export default connect(
  state => ({
    expanded: isMoreMenuExpanded(state),
  }),
  dispatch => bindActionCreators( {
    expand: expandMoreMenu,
    collapse: collapseMoreMenu,
  }, dispatch)
)(ClickOutside(Radium(More)));
<|endoftext|>


<commit_before>const React = require('react');
const PropTypes = require('prop-types');
const Radium = require('radium');

const ButtonGroup = require('./ButtonGroup');
const StyleConstants = require('../constants/Style');

class StandardTabs extends React.Component {
  static propTypes = {
    activeTabStyles: PropTypes.object,
    brandColor: PropTypes.string,
    onTabSelect: PropTypes.func.isRequired,
    selectedTab: PropTypes.number,
    tabs: PropTypes.array.isRequired
  };

  static defaultProps = {
    brandColor: StyleConstants.Colors.PRIMARY
  };

  constructor (props) {
    super(props);

    this.state = {
      selectedTab: this.props.selectedTab || 0
    };
  }

  componentWillMount () {
    if (this.props.hasOwnProperty('useTabsInMobile')) {
      console.warn('The useTabsInMobile prop is deprecated and will be removed in a future release.');
    }
  }

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

  handleTabSelect (selectedTab) {
    this.props.onTabSelect(selectedTab);

    this.setState({
      selectedTab
    });
  }

  render () {
    return (

        {this.props.tabs.map((tab, index) =>
          <Tab
            isActive={this.state.selectedTab === index}
            key={tab}
            onClick={this.handleTabSelect.bind(this, index)}
            styles={{ activeTab: this.props.activeTabStyles }}
          >
            {tab}
          </Tab>
        )}

    );
  }
}

class TabWithoutRadium extends React.Component {
  static propTypes = {
    activeTabStyles: PropTypes.object,
    brandColor: PropTypes.string,
    isActive: PropTypes.bool,
    onClick: PropTypes.func,
    styles: PropTypes.object
  }

  static defaultProps = {
    brandColor: StyleConstants.Colors.PRIMARY,
    isActive: false,
    onClick: () => {},
    styles: {}
  }

  render () {
    const styles = this.styles();
    let style = Object.assign({}, styles.tab, this.props.styles.tab);

    if (this.props.isActive)
      style = Object.assign({}, style, styles.activeTab, this.props.styles.activeTab);

    return (

        {this.props.children}

    );
  }

  styles = () => {
    return {
      tab: {
        boxSizing: 'border-box',
        color: StyleConstants.Colors.ASH,
        cursor: 'pointer',
        display: 'inline-block',
        fontSize: StyleConstants.FontSizes.MEDIUM,
        fontStyle: StyleConstants.Fonts.SEMIBOLD,
        padding: StyleConstants.Spacing.MEDIUM,
        whiteSpace: 'nowrap',

        ':hover': {
          color: StyleConstants.Colors.CHARCOAL
        }
      },
      activeTab: Object.assign({
        cursor: 'default',
        color: this.props.brandColor,
        borderBottom: '2px solid ' + this.props.brandColor,

        ':hover': {
          color: this.props.brandColor
        }
      }, this.props.activeTabStyles)
    };
  }
}

const Tab = Radium(TabWithoutRadium);

class PillTabs extends StandardTabs {
  render () {
    const styles = this.styles();

    return (

        <ButtonGroup
          buttons={this.props.tabs.map((tab, index) => ({
            'aria-label': tab,
            onClick: (this.state.selectedTab === index ? null : this.handleTabSelect.bind(this, index)),
            style: Object.assign({}, styles.tab, this.state.selectedTab === index && styles.selected),
            text: tab
          }))}
          style={styles.buttonGroup}
          type='neutral'
        />

    );
  }

  styles = () => {
    return {
      component: {
        margin: StyleConstants.Spacing.SMALL
      },
      tab: {
        backgroundColor: StyleConstants.Colors.PORCELAIN,
        borderColor: StyleConstants.Colors.FOG,
        outline: 'none',

        ':hover': {
          backgroundColor: this.props.brandColor,
          color: StyleConstants.Colors.WHITE,
          fill: StyleConstants.Colors.WHITE
        },
        ':focus': {
          backgroundColor: this.props.brandColor,
          color: StyleConstants.Colors.WHITE,
          fill: StyleConstants.Colors.WHITE
        },
        ':active': {
          backgroundColor: StyleConstants.adjustColor(this.props.brandColor, -15)
        }
      },
      selected: {
        backgroundColor: StyleConstants.Colors.WHITE,
        color: this.props.brandColor,
        cursor: 'default',

        ':hover': {
          backgroundColor: 'transparent'
        },
        ':focus': {
          backgroundColor: StyleConstants.Colors.WHITE,
          color: this.props.brandColor
        },
        ':active': {
          backgroundColor: 'transparent'
        }
      }
    };
  }
}

const TabsTypes = {
  standard: StandardTabs,
  pill: PillTabs
};

const Tabs = ({
  alignment = 'left',
  showBottomBorder = true,
  style,
  type = 'standard',
  useTabsInMobile,
  ...props
}) => {
  if (typeof useTabsInMobile !== 'undefined') {
    console.warn('The useTabsInMobile prop is deprecated and will be removed in a future release.');
  }

  const componentStyle = Object.assign({
    borderBottom: showBottomBorder ? '1px solid ' + StyleConstants.Colors.FOG : 'none',
    boxSizing: 'border-box',
    display: 'flex',
    justifyContent: alignment === 'left' ? 'flex-start' : 'center',
    overflowX: 'scroll',
    width: '100%'
  }, style);
  const TabsComponent = TabsTypes[type];

  if (!TabsComponent) throw new Error(`Unknown Tabs type: ${type}`);

  return (

      <TabsComponent {...props} />

  );
};

Tabs.propTypes = {
  alignment: PropTypes.oneOf(['left', 'center']),
  showBottomBorder: PropTypes.bool,
  type: PropTypes.oneOf(Object.keys(TabsTypes)),
  useTabsInMobile: PropTypes.bool
};

module.exports = Tabs;
<commit_msg>Remove prop check because it was moved to Tabs<commit_after>const React = require('react');
const PropTypes = require('prop-types');
const Radium = require('radium');

const ButtonGroup = require('./ButtonGroup');
const StyleConstants = require('../constants/Style');

class StandardTabs extends React.Component {
  static propTypes = {
    activeTabStyles: PropTypes.object,
    brandColor: PropTypes.string,
    onTabSelect: PropTypes.func.isRequired,
    selectedTab: PropTypes.number,
    tabs: PropTypes.array.isRequired
  };

  static defaultProps = {
    brandColor: StyleConstants.Colors.PRIMARY
  };

  constructor (props) {
    super(props);

    this.state = {
      selectedTab: this.props.selectedTab || 0
    };
  }

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

  handleTabSelect (selectedTab) {
    this.props.onTabSelect(selectedTab);

    this.setState({
      selectedTab
    });
  }

  render () {
    return (

        {this.props.tabs.map((tab, index) =>
          <Tab
            isActive={this.state.selectedTab === index}
            key={tab}
            onClick={this.handleTabSelect.bind(this, index)}
            styles={{ activeTab: this.props.activeTabStyles }}
          >
            {tab}
          </Tab>
        )}

    );
  }
}

class TabWithoutRadium extends React.Component {
  static propTypes = {
    activeTabStyles: PropTypes.object,
    brandColor: PropTypes.string,
    isActive: PropTypes.bool,
    onClick: PropTypes.func,
    styles: PropTypes.object
  }

  static defaultProps = {
    brandColor: StyleConstants.Colors.PRIMARY,
    isActive: false,
    onClick: () => {},
    styles: {}
  }

  render () {
    const styles = this.styles();
    let style = Object.assign({}, styles.tab, this.props.styles.tab);

    if (this.props.isActive)
      style = Object.assign({}, style, styles.activeTab, this.props.styles.activeTab);

    return (

        {this.props.children}

    );
  }

  styles = () => {
    return {
      tab: {
        boxSizing: 'border-box',
        color: StyleConstants.Colors.ASH,
        cursor: 'pointer',
        display: 'inline-block',
        fontSize: StyleConstants.FontSizes.MEDIUM,
        fontStyle: StyleConstants.Fonts.SEMIBOLD,
        padding: StyleConstants.Spacing.MEDIUM,
        whiteSpace: 'nowrap',

        ':hover': {
          color: StyleConstants.Colors.CHARCOAL
        }
      },
      activeTab: Object.assign({
        cursor: 'default',
        color: this.props.brandColor,
        borderBottom: '2px solid ' + this.props.brandColor,

        ':hover': {
          color: this.props.brandColor
        }
      }, this.props.activeTabStyles)
    };
  }
}

const Tab = Radium(TabWithoutRadium);

class PillTabs extends StandardTabs {
  render () {
    const styles = this.styles();

    return (

        <ButtonGroup
          buttons={this.props.tabs.map((tab, index) => ({
            'aria-label': tab,
            onClick: (this.state.selectedTab === index ? null : this.handleTabSelect.bind(this, index)),
            style: Object.assign({}, styles.tab, this.state.selectedTab === index && styles.selected),
            text: tab
          }))}
          style={styles.buttonGroup}
          type='neutral'
        />

    );
  }

  styles = () => {
    return {
      component: {
        margin: StyleConstants.Spacing.SMALL
      },
      tab: {
        backgroundColor: StyleConstants.Colors.PORCELAIN,
        borderColor: StyleConstants.Colors.FOG,
        outline: 'none',

        ':hover': {
          backgroundColor: this.props.brandColor,
          color: StyleConstants.Colors.WHITE,
          fill: StyleConstants.Colors.WHITE
        },
        ':focus': {
          backgroundColor: this.props.brandColor,
          color: StyleConstants.Colors.WHITE,
          fill: StyleConstants.Colors.WHITE
        },
        ':active': {
          backgroundColor: StyleConstants.adjustColor(this.props.brandColor, -15)
        }
      },
      selected: {
        backgroundColor: StyleConstants.Colors.WHITE,
        color: this.props.brandColor,
        cursor: 'default',

        ':hover': {
          backgroundColor: 'transparent'
        },
        ':focus': {
          backgroundColor: StyleConstants.Colors.WHITE,
          color: this.props.brandColor
        },
        ':active': {
          backgroundColor: 'transparent'
        }
      }
    };
  }
}

const TabsTypes = {
  standard: StandardTabs,
  pill: PillTabs
};

const Tabs = ({
  alignment = 'left',
  showBottomBorder = true,
  style,
  type = 'standard',
  useTabsInMobile,
  ...props
}) => {
  if (typeof useTabsInMobile !== 'undefined') {
    console.warn('The useTabsInMobile prop is deprecated and will be removed in a future release.');
  }

  const componentStyle = Object.assign({
    borderBottom: showBottomBorder ? '1px solid ' + StyleConstants.Colors.FOG : 'none',
    boxSizing: 'border-box',
    display: 'flex',
    justifyContent: alignment === 'left' ? 'flex-start' : 'center',
    overflowX: 'scroll',
    width: '100%'
  }, style);
  const TabsComponent = TabsTypes[type];

  if (!TabsComponent) throw new Error(`Unknown Tabs type: ${type}`);

  return (

      <TabsComponent {...props} />

  );
};

Tabs.propTypes = {
  alignment: PropTypes.oneOf(['left', 'center']),
  showBottomBorder: PropTypes.bool,
  type: PropTypes.oneOf(Object.keys(TabsTypes)),
  useTabsInMobile: PropTypes.bool
};

module.exports = Tabs;
<|endoftext|>


<commit_before>import React from 'react';
import styled from 'styled-components';
import { darken, transparentize } from 'polished';
import withStyle from './Base';
import PropTypes from 'prop-types';
import LabeledContainer from './LabeledContainer';

const StyledTabs = styled.div`
  display: flex;
  white-space: nowrap;
  background-color: ${props => props.theme.colors.primary};
  width: 100%;
`;

const StyledTabButton = withStyle(styled.button.attrs({
  type: 'button'
})`
    box-sizing: border-box;
    border: 10px;
    height: 48px;
    outline: none;
    background: none;
    cursor: pointer;
    color: ${props =>
      props.active
        ? props.theme.colors.primaryText
        : transparentize(0.5, props.theme.colors.primaryText)};
    font-size: ${props => props.theme.fontSizes[1]}px;
    font-weight: ${props => props.theme.fontWeights[1]};
    display: inline-block;
    width: ${props => props.width * 100}%;
    shadow-box: none;
    border-radius: 0;
    border-bottom: ${props =>
      props.active ? `4px solid ${props.theme.colors.secondary}` : ''};

    &:hover {
        background-color: ${props => darken(0.08, props.theme.colors.primary)};
    }
`);

class Tabs extends React.Component {
  static propTypes = {
    /** Array of LabeledContainers */
    children: PropTypes.arrayOf(PropTypes.instanceOf(LabeledContainer)),
    /** activate a specific tab, otherwise the first one will be opened */
    active: PropTypes.number
  };
  static propTypes = {
    active: 0
  };
  constructor(props) {
    super(props);
    this.state = {
      active: 0
    };
  }
  onChangeActive = i => {
    this.setState({
      active: i
    });
  };
  render() {
    const { children } = this.props;
    const tabWidth = 1 / children.length;
    const tabButtons = children.map((child, i) =>

    );
    return (

        {children[this.state.active]}

    );
  }
}

export default Tabs;
<commit_msg>fix defaultProps<commit_after>import React from 'react';
import styled from 'styled-components';
import { darken, transparentize } from 'polished';
import withStyle from './Base';
import PropTypes from 'prop-types';
import LabeledContainer from './LabeledContainer';

const StyledTabs = styled.div`
  display: flex;
  white-space: nowrap;
  background-color: ${props => props.theme.colors.primary};
  width: 100%;
`;

const StyledTabButton = withStyle(styled.button.attrs({
  type: 'button'
})`
    box-sizing: border-box;
    border: 10px;
    height: 48px;
    outline: none;
    background: none;
    cursor: pointer;
    color: ${props =>
      props.active
        ? props.theme.colors.primaryText
        : transparentize(0.5, props.theme.colors.primaryText)};
    font-size: ${props => props.theme.fontSizes[1]}px;
    font-weight: ${props => props.theme.fontWeights[1]};
    display: inline-block;
    width: ${props => props.width * 100}%;
    shadow-box: none;
    border-radius: 0;
    border-bottom: ${props =>
      props.active ? `4px solid ${props.theme.colors.secondary}` : ''};

    &:hover {
        background-color: ${props => darken(0.08, props.theme.colors.primary)};
    }
`);

class Tabs extends React.Component {
  static propTypes = {
    /** Array of LabeledContainers */
    children: PropTypes.arrayOf(PropTypes.instanceOf(LabeledContainer)),
    /** activate a specific tab, otherwise the first one will be opened */
    active: PropTypes.number
  };
  static defaultProps = {
    active: 0
  };
  constructor(props) {
    super(props);
    this.state = {
      active: 0
    };
  }
  onChangeActive = i => {
    this.setState({
      active: i
    });
  };
  render() {
    const { children } = this.props;
    const tabWidth = 1 / children.length;
    const tabButtons = children.map((child, i) =>

    );
    return (

        {children[this.state.active]}

    );
  }
}

export default Tabs;
<|endoftext|>


<commit_before>define(['app', 'underscore', '/app/views/forms/edit/edit.js','/app/views/forms/edit/edit-resource-schema-base-directive.html.js'], function (app, _) {

  app.controller("editResource", ["$scope", "$http", "$filter", "Thesaurus", "$q", "Enumerable", "$controller", "IStorage", "$location",
                function ($scope, $http, $filter, Thesaurus, $q, Enumerable, $controller, storage, $location) {

    $scope.path=$location.path();

    //$scope.organizationsRef = [];
    $controller('editController', {$scope: $scope});

    _.extend($scope.options, {
      resourceTypes : function() {
        return $q.all([
          $http.get("/api/v2013/thesaurus/domains/83BA4728-A843-442B-9664-705F55A8EC52/terms", { cache: true }),
          $http.get("/api/v2013/thesaurus/terms/5B6177DD-5E5E-434E-8CB7-D63D67D5EBED",   { cache: true })
        ]).then(function(o) {
          var data = o[0].data;
          data.push(o[1].data)
          return  Thesaurus.buildTree(data);
        })
      }
    });

  }]);
});
<commit_msg>getdocument for VLR was missing, fix organizations<commit_after>define(['app', 'underscore', '/app/views/forms/edit/edit.js','/app/views/forms/edit/edit-resource-schema-base-directive.html.js'], function (app, _) {

  app.controller("editResource", ["$scope", "$http", "$filter", "Thesaurus", "$q", "Enumerable", "$controller", "IStorage", "$location",
                function ($scope, $http, $filter, Thesaurus, $q, Enumerable, $controller, storage, $location) {

    $scope.path=$location.path();

    //$scope.organizationsRef = [];
    $controller('editController', {$scope: $scope});

    _.extend($scope.options, {
      resourceTypes : function() {
        return $q.all([
          $http.get("/api/v2013/thesaurus/domains/83BA4728-A843-442B-9664-705F55A8EC52/terms", { cache: true }),
          $http.get("/api/v2013/thesaurus/terms/5B6177DD-5E5E-434E-8CB7-D63D67D5EBED",   { cache: true })
        ]).then(function(o) {
          var data = o[0].data;
          data.push(o[1].data)
          return  Thesaurus.buildTree(data);
        })
      }
    });
    //==================================
    //
    //==================================
    $scope.getCleanDocument = function() {

      var document = $scope.document;

      if (!document)
        return undefined;

      document = angular.fromJson(angular.toJson(document));

      if (/^\s*$/g.test(document.notes))
        document.notes = undefined;

      if(!$scope.isOtherSelected(document.languages))
          document.languageName = undefined;

      if(!$scope.isOtherSelected(document.resourceTypes))
          document.resourceTypeName = undefined;

      if(document.organizations && document.organizations.length <=0)
          document.organizations = undefined;

        var documentCopy = _.clone(document)

        delete documentCopy.organizationsRef;
      return documentCopy;
    };

  }]);
});
<|endoftext|>


<commit_before>var _map = require('lodash/map');
module.exports = function(app) {
  app.config([
    'formioComponentsProvider',
    function(
      formioComponentsProvider
    ) {
      formioComponentsProvider.register('file', {
        onEdit: [
          '$scope',
          'Formio',
          function($scope, Formio) {
            // Pull out title and name from the list of storage plugins.
            $scope.storage = _map(Formio.providers.storage, function(storage, key) {
              return {
                title: storage.title,
                name: key
              };
            });
          }
        ],
        icon: 'fa fa-file',
        views: [
          {
            name: 'Display',
            template: 'formio/components/file/display.html'
          },
          {
            name: 'Validation',
            template: 'formio/components/file/validate.html'
          },
          {
            name: 'API',
            template: 'formio/components/common/api.html'
          },
          {
            name: 'Layout',
            template: 'formio/components/common/layout.html'
          },
          {
            name: 'Conditional',
            template: 'formio/components/common/conditional.html'
          }
        ],
        documentation: 'http://help.form.io/userguide/#file'
      });
    }
  ]);
  app.run([
    '$templateCache',
    function($templateCache) {
      // Create the settings markup.
      $templateCache.put('formio/components/file/display.html',
        '<ng-form>' +
          '<form-builder-option property="label"></form-builder-option>' +
          '
' +
            'Storage' +
            '<select class="form-control" id="storage" name="storage" ng-options="store.name as store.title for store in storage" ng-model="component.storage"></select>' +
          '
' +
          '<form-builder-option property="url" ng-show="component.storage === \'url\'"></form-builder-option>' +
          '<form-builder-option property="dir"></form-builder-option>' +
          '<form-builder-option property="image"></form-builder-option>' +
          '<form-builder-option property="imageSize" ng-if="component.image"></form-builder-option>' +
          '<form-builder-option property="customClass"></form-builder-option>' +
          '<form-builder-option property="tabindex"></form-builder-option>' +
          '<form-builder-option property="multiple"></form-builder-option>' +
          '<form-builder-option property="clearOnHide"></form-builder-option>' +
          '<form-builder-option property="protected"></form-builder-option>' +
          '<form-builder-option property="persistent"></form-builder-option>' +
          '<form-builder-option property="hidden"></form-builder-option>' +
          '<form-builder-option property="disabled"></form-builder-option>' +
          '<form-builder-option property="tableView"></form-builder-option>' +
        '</ng-form>'
      );

      $templateCache.put('formio/components/file/validate.html',
        '<ng-form>' +
          '<form-builder-option property="validate.required"></form-builder-option>' +
          '<form-builder-option property="filePattern"></form-builder-option>' +
        '</ng-form>'
      );
    }
  ]);
};
<commit_msg>Removing random validation field on the file component, which was not used.<commit_after>var _map = require('lodash/map');
module.exports = function(app) {
  app.config([
    'formioComponentsProvider',
    function(
      formioComponentsProvider
    ) {
      formioComponentsProvider.register('file', {
        onEdit: [
          '$scope',
          'Formio',
          function($scope, Formio) {
            // Pull out title and name from the list of storage plugins.
            $scope.storage = _map(Formio.providers.storage, function(storage, key) {
              return {
                title: storage.title,
                name: key
              };
            });
          }
        ],
        icon: 'fa fa-file',
        views: [
          {
            name: 'Display',
            template: 'formio/components/file/display.html'
          },
          {
            name: 'Validation',
            template: 'formio/components/file/validate.html'
          },
          {
            name: 'API',
            template: 'formio/components/common/api.html'
          },
          {
            name: 'Layout',
            template: 'formio/components/common/layout.html'
          },
          {
            name: 'Conditional',
            template: 'formio/components/common/conditional.html'
          }
        ],
        documentation: 'http://help.form.io/userguide/#file'
      });
    }
  ]);
  app.run([
    '$templateCache',
    function($templateCache) {
      // Create the settings markup.
      $templateCache.put('formio/components/file/display.html',
        '<ng-form>' +
          '<form-builder-option property="label"></form-builder-option>' +
          '
' +
            'Storage' +
            '<select class="form-control" id="storage" name="storage" ng-options="store.name as store.title for store in storage" ng-model="component.storage"></select>' +
          '
' +
          '<form-builder-option property="url" ng-show="component.storage === \'url\'"></form-builder-option>' +
          '<form-builder-option property="dir"></form-builder-option>' +
          '<form-builder-option property="image"></form-builder-option>' +
          '<form-builder-option property="imageSize" ng-if="component.image"></form-builder-option>' +
          '<form-builder-option property="customClass"></form-builder-option>' +
          '<form-builder-option property="tabindex"></form-builder-option>' +
          '<form-builder-option property="multiple"></form-builder-option>' +
          '<form-builder-option property="clearOnHide"></form-builder-option>' +
          '<form-builder-option property="protected"></form-builder-option>' +
          '<form-builder-option property="persistent"></form-builder-option>' +
          '<form-builder-option property="hidden"></form-builder-option>' +
          '<form-builder-option property="disabled"></form-builder-option>' +
          '<form-builder-option property="tableView"></form-builder-option>' +
        '</ng-form>'
      );

      $templateCache.put('formio/components/file/validate.html',
        '<ng-form>' +
          '<form-builder-option property="validate.required"></form-builder-option>' +
        '</ng-form>'
      );
    }
  ]);
};
<|endoftext|>


<commit_before>var HierarchicalEntityCollection;
(function (_, Backbone, $, App, UriUtil, EntityCollection) {
    /**
     * This collection is used for hierarchical entites
     *
     * @class HierarchicalEntityCollection
     * @type {Backbone.CollectionSubset.extend|*|dst|target|Object|a}
     */
    HierarchicalEntityCollection = Backbone.HierarchicalEntityCollection = EntityCollection.extend({
        /**
         * Description
         * @method initialize
         * @return
         */
        initialize: function () {
            EntityCollection.prototype.initialize.apply(this);
        },
        /**
         * Description
         * @method getChildren
         * @param {} parentId
         * @param {} limit
         * @return CallExpression
         */
        getChildren: function (parentId, limit, includeEntity) {
            var outerScope = this,
                data = {parentId: parentId, limit: limit},
                url = this.getUrl(),
                key = url + UriUtil.getUriHash(data);

            var cachedDeferred = App.getCache(key);
            if (!_.isUndefined(cachedDeferred)) {
                return cachedDeferred;
            }

            /**
             * Description
             * @method getCollection
             * @return result
             */
            var getCollection = $.Deferred(function (defer) {
                var result = $.ajax({
                    type: 'GET',
                    url: url + '/GetChildren',
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    data: data,
                    /**
                     * Description
                     * @method success
                     * @param {} response
                     * @return
                     */
                    success: function (response) {
                        outerScope.addRange(response);
                        defer.resolve(outerScope.getChildrenCollection(parentId, includeEntity));
                    },
                    /**
                     * Description
                     * @method error
                     * @param {} errorResponse
                     * @return
                     */
                    error: function (errorResponse) {
                        console.log("Inside Failure");
                        console.log(errorResponse.responseText);
                        defer.reject();
                    }
                });

                return result;
            });

            App.setCache(key, getCollection);
            return getCollection;
        },
        /**
         * Description
         * @method getParents
         * @param {} id
         * @param {} limit
         * @param {} includeEntity
         * @return CallExpression
         */
        getParents: function (id, limit, includeEntity) {
            var outerScope = this,
                url = this.getUrl() + '/GetParents',
                data = {id: id, limit: limit},
                key = url + UriUtil.getUriHash(data);

            var cachedDeferred = App.getCache(key);
            if (!_.isUndefined(cachedDeferred)) {
                return cachedDeferred;
            }

            var getCollection = $.Deferred(function (defer) {
                var result = $.ajax({
                    type: 'GET',
                    url: url,
                    data: data,
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    /**
                     * Description
                     * @method success
                     * @param {} response
                     * @return
                     */
                    success: function (response) {
                        outerScope.addRange(response);
                        defer.resolve(outerScope.getParentsCollection(id, includeEntity));
                    },
                    /**
                     * Description
                     * @method error
                     * @param {} errorResponse
                     * @return
                     */
                    error: function (errorResponse) {
                        console.log("Inside Failure");
                        console.log(errorResponse.responseText);
                        defer.reject();
                    }
                });

                return result;
            });

            App.setCache(key, getCollection);
            return getCollection;
        },
        /**
         * Description
         * @method getParentIds
         * @param {} entity
         * @return uniqueParentIds
         */
        getParentIds: function (entity) {
            var currentParentIds = entity.get('parentIds'),
                allParentIds = [],
                collectionContext = this;

            allParentIds = allParentIds.concat(currentParentIds);

            _.each(currentParentIds, function (parentId) {
                var parentEntity = collectionContext.get(parentId);

                if (parentEntity.get('parentIds').length > 0) {
                    allParentIds.concat(collectionContext.getParents(parentEntity));
                }
            });

            var uniqueParentIds = _.uniq(allParentIds, function (item, key, a) {
                return item;
            });

            return uniqueParentIds;
        },
        getChildrenIds: function (entity) {
            var children = this.filter(function (profile) {
                return profile.get('parentIds').indexOf(entity.get('id')) > -1;
            });

            return _.pluck(children, 'id');
        },
        /**
         * Description
         * @method getParentsCollection
         * @param {} id
         * @param {} includeEntity
         * @return MemberExpression
         */
        getParentsCollection: function (id, includeEntity) {
            var collectionContext = this,
                entity = this.get(id);

            var parentIds = this.getParentIds(entity);

            if (includeEntity) {
                parentIds.push(id);
            }

            var collection = new Backbone.CollectionSubset({
                parent: collectionContext,
                /**
                 * Description
                 * @method filter
                 * @param {} node
                 * @return BinaryExpression
                 */
                filter: function (node) {
                    var modelId = node.get('id');
                    return parentIds.indexOf(modelId) > -1;
                }
            });

            return collection.child;
        },
        /**
         * Description
         * @method getChildrenCollection
         * @param {} id
         * @param {} includeEntity
         * @return MemberExpression
         */
        getChildrenCollection: function (id, includeEntity) {
            var collectionContext = this,
                entity = this.get(id);

            var childrenIds = this.getChildrenIds(entity);

            if (includeEntity) {
                childrenIds.push(id);
            }

            var collection = new Backbone.CollectionSubset({
                parent: collectionContext,
                /**
                 * Description
                 * @method filter
                 * @param {} node
                 * @return BinaryExpression
                 */
                filter: function (node) {
                    var modelId = node.get('id');
                    return childrenIds.indexOf(modelId) > -1;
                }
            });

            return collection.child;
        },
        /**
         * Description
         * @method getTopLevel
         * @return CallExpression
         */
        getTopLevel: function (track) {
            var outerScope = this,
                url = this.getUrl() + '/GetTopLevel';

            /**
             * Description
             * @method getCollection
             * @return result
             */
            var getCollection = $.Deferred(function (defer) {
                var result = $.ajax({
                    type: 'GET',
                    url: url,
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    /**
                     * Description
                     * @method success
                     * @param {} response
                     * @return
                     */
                    success: function (response) {
                        var models = outerScope.addRange(response);

                        if (track) {
                            defer.resolve(outerScope._getSubCollection(response));
                        } else {
                            defer.resolve(new Backbone.Collection(models));
                        }
                    },
                    /**
                     * Description
                     * @method error
                     * @param {} errorResponse
                     * @return
                     */
                    error: function (errorResponse) {
                        console.log("Inside Failure");
                        console.log(errorResponse.responseText);
                    }
                });

                return result;
            });

            return App.getCache(url, getCollection);
        }
    });
})(_, Backbone, jQuery, App, UriUtil, EntityCollection);<commit_msg>removing unneccessary initialize method<commit_after>var HierarchicalEntityCollection;
(function (_, Backbone, $, App, UriUtil, EntityCollection) {
    /**
     * This collection is used for hierarchical entites
     *
     * @class HierarchicalEntityCollection
     * @type {Backbone.CollectionSubset.extend|*|dst|target|Object|a}
     */
    HierarchicalEntityCollection = Backbone.HierarchicalEntityCollection = EntityCollection.extend({
        /**
         * Description
         * @method getChildren
         * @param {} parentId
         * @param {} limit
         * @return CallExpression
         */
        getChildren: function (parentId, limit, includeEntity) {
            var outerScope = this,
                data = {parentId: parentId, limit: limit},
                url = this.getUrl(),
                key = url + UriUtil.getUriHash(data);

            var cachedDeferred = App.getCache(key);
            if (!_.isUndefined(cachedDeferred)) {
                return cachedDeferred;
            }

            /**
             * Description
             * @method getCollection
             * @return result
             */
            var getCollection = $.Deferred(function (defer) {
                var result = $.ajax({
                    type: 'GET',
                    url: url + '/GetChildren',
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    data: data,
                    /**
                     * Description
                     * @method success
                     * @param {} response
                     * @return
                     */
                    success: function (response) {
                        outerScope.addRange(response);
                        defer.resolve(outerScope.getChildrenCollection(parentId, includeEntity));
                    },
                    /**
                     * Description
                     * @method error
                     * @param {} errorResponse
                     * @return
                     */
                    error: function (errorResponse) {
                        console.log("Inside Failure");
                        console.log(errorResponse.responseText);
                        defer.reject();
                    }
                });

                return result;
            });

            App.setCache(key, getCollection);
            return getCollection;
        },
        /**
         * Description
         * @method getParents
         * @param {} id
         * @param {} limit
         * @param {} includeEntity
         * @return CallExpression
         */
        getParents: function (id, limit, includeEntity) {
            var outerScope = this,
                url = this.getUrl() + '/GetParents',
                data = {id: id, limit: limit},
                key = url + UriUtil.getUriHash(data);

            var cachedDeferred = App.getCache(key);
            if (!_.isUndefined(cachedDeferred)) {
                return cachedDeferred;
            }

            var getCollection = $.Deferred(function (defer) {
                var result = $.ajax({
                    type: 'GET',
                    url: url,
                    data: data,
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    /**
                     * Description
                     * @method success
                     * @param {} response
                     * @return
                     */
                    success: function (response) {
                        outerScope.addRange(response);
                        defer.resolve(outerScope.getParentsCollection(id, includeEntity));
                    },
                    /**
                     * Description
                     * @method error
                     * @param {} errorResponse
                     * @return
                     */
                    error: function (errorResponse) {
                        console.log("Inside Failure");
                        console.log(errorResponse.responseText);
                        defer.reject();
                    }
                });

                return result;
            });

            App.setCache(key, getCollection);
            return getCollection;
        },
        /**
         * Description
         * @method getParentIds
         * @param {} entity
         * @return uniqueParentIds
         */
        getParentIds: function (entity) {
            var currentParentIds = entity.get('parentIds'),
                allParentIds = [],
                collectionContext = this;

            allParentIds = allParentIds.concat(currentParentIds);

            _.each(currentParentIds, function (parentId) {
                var parentEntity = collectionContext.get(parentId);

                if (parentEntity.get('parentIds').length > 0) {
                    allParentIds.concat(collectionContext.getParents(parentEntity));
                }
            });

            var uniqueParentIds = _.uniq(allParentIds, function (item, key, a) {
                return item;
            });

            return uniqueParentIds;
        },
        getChildrenIds: function (entity) {
            var children = this.filter(function (profile) {
                return profile.get('parentIds').indexOf(entity.get('id')) > -1;
            });

            return _.pluck(children, 'id');
        },
        /**
         * Description
         * @method getParentsCollection
         * @param {} id
         * @param {} includeEntity
         * @return MemberExpression
         */
        getParentsCollection: function (id, includeEntity) {
            var collectionContext = this,
                entity = this.get(id);

            var parentIds = this.getParentIds(entity);

            if (includeEntity) {
                parentIds.push(id);
            }

            var collection = new Backbone.CollectionSubset({
                parent: collectionContext,
                /**
                 * Description
                 * @method filter
                 * @param {} node
                 * @return BinaryExpression
                 */
                filter: function (node) {
                    var modelId = node.get('id');
                    return parentIds.indexOf(modelId) > -1;
                }
            });

            return collection.child;
        },
        /**
         * Description
         * @method getChildrenCollection
         * @param {} id
         * @param {} includeEntity
         * @return MemberExpression
         */
        getChildrenCollection: function (id, includeEntity) {
            var collectionContext = this,
                entity = this.get(id);

            var childrenIds = this.getChildrenIds(entity);

            if (includeEntity) {
                childrenIds.push(id);
            }

            var collection = new Backbone.CollectionSubset({
                parent: collectionContext,
                /**
                 * Description
                 * @method filter
                 * @param {} node
                 * @return BinaryExpression
                 */
                filter: function (node) {
                    var modelId = node.get('id');
                    return childrenIds.indexOf(modelId) > -1;
                }
            });

            return collection.child;
        },
        /**
         * Description
         * @method getTopLevel
         * @return CallExpression
         */
        getTopLevel: function (track) {
            var outerScope = this,
                url = this.getUrl() + '/GetTopLevel';

            /**
             * Description
             * @method getCollection
             * @return result
             */
            var getCollection = $.Deferred(function (defer) {
                var result = $.ajax({
                    type: 'GET',
                    url: url,
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    /**
                     * Description
                     * @method success
                     * @param {} response
                     * @return
                     */
                    success: function (response) {
                        var models = outerScope.addRange(response);

                        if (track) {
                            defer.resolve(outerScope._getSubCollection(response));
                        } else {
                            defer.resolve(new Backbone.Collection(models));
                        }
                    },
                    /**
                     * Description
                     * @method error
                     * @param {} errorResponse
                     * @return
                     */
                    error: function (errorResponse) {
                        console.log("Inside Failure");
                        console.log(errorResponse.responseText);
                    }
                });

                return result;
            });

            return App.getCache(url, getCollection);
        }
    });
})(_, Backbone, jQuery, App, UriUtil, EntityCollection);
<|endoftext|>


<commit_before>import React from 'react';

export default class KataComponent extends React.Component {
  render() {
    const {kata, outgoingUrl, appUrl} = this.props;
    const group = kata.kataGroup;

    return (

              Open in TDDbin

#{kata.id} {group.name}: {kata.name}

Released {kata.releaseDateAgo}

{kata.description}

Solving this kata you can learn

one thing

one thing

one thing

one thing

    );
  }
}
<commit_msg>Playing with the UI.<commit_after>import React from 'react';

export default class KataComponent extends React.Component {
  render() {
    const {kata, outgoingUrl, appUrl} = this.props;
    const group = kata.kataGroup;

    return (

              Solve this kata

#{kata.id} {group.name}: {kata.name}

Released {kata.releaseDateAgo}

{kata.description}

The following katas are recommended to do before this kata

#8 Block scope: `const` declaration

#5 Arrow functions: basics

More in depth links

Moziila MDN

Solving this kata you can learn

one thing

one thing

one thing

one thing

    );
  }
}
<|endoftext|>


<commit_before>import React from 'react';
export default class Logo {

  render() {
    return (

    );
  }

}<commit_msg>deleted name-tag<commit_after>import React from 'react';
export default class Logo {

  render() {
    return (

    );
  }

}<|endoftext|>


<commit_before>import React from 'react';
import {Link} from 'react-router';
import {Bar} from 'react-chartjs';

import formatUrl from '../utils/format-url'
import {postVoteOnPoll, changeSelectedOption} from '../actions/poll-actions';

export default ({
  polls,
  params,
  dispatch
}) => {
  let pollName = formatUrl(params.poll, false)
    , poll = polls.find(x => x.name === pollName)
    , options, data;

  if (poll) {
    options = Object.keys(poll.options);
    data = {
      labels: options,
      datasets: [{
        label: 'Bar chart',
        fillColor: 'rgba(63,81,181,0.5)',
        strokeColor: 'rgba(63,81,181,0.8)',
        highlightFill: 'rgba(63,81,181,0.75)',
        highlightStroke: 'rgba(63,81,181,1)',
        data: options.map(x => poll.options[x])
      }]
    };
    return

{pollName}

Submitted by: {' '}
            <Link to={`/users/${poll.submitter}`}>{poll.submitter}</Link>

          <select className='browser-default'
            onChange={(e) => dispatch(changeSelectedOption(poll.name, e.target.value))}
            defaultValue={poll.selectedOption}
          >
            <option value='select' disabled>Select an option to vote</option>
            {options.map((x, i) => (
              <option key={i} value={x}>{x}</option>
            ))}
          </select>

          <button
            onClick={(e) => {
              e.preventDefault();
              dispatch(postVoteOnPoll(poll.name, poll.selectedOption))}}
            type='submit' className='btn'
            disabled={poll.selectedOption === 'select'}>Submit</button>

          <Bar data={data} width={400} height={250}/>

  } else {
    return

Unable to find the poll:

{pollName}

  }
}
<commit_msg>tweet button added<commit_after>import React from 'react';
import {Link} from 'react-router';
import {Bar} from 'react-chartjs';

import formatUrl from '../utils/format-url'
import {postVoteOnPoll, changeSelectedOption} from '../actions/poll-actions';

export default ({
  polls,
  params,
  dispatch
}) => {
  let pollName = formatUrl(params.poll, false)
    , poll = polls.find(x => x.name === pollName)
    , options, data;

  if (poll) {
    options = Object.keys(poll.options);
    data = {
      labels: options,
      datasets: [{
        label: 'Bar chart',
        fillColor: 'rgba(63,81,181,0.5)',
        strokeColor: 'rgba(63,81,181,0.8)',
        highlightFill: 'rgba(63,81,181,0.75)',
        highlightStroke: 'rgba(63,81,181,1)',
        data: options.map(x => poll.options[x])
      }]
    };
    return

{pollName}

Submitted by: {' '}
            <Link to={`/users/${poll.submitter}`}>{poll.submitter}</Link>

          <a
            href={`https://twitter.com/intent/tweet?text=${poll.name} - Poll @ The Polling Vote - ${window.location.origin}/polls/${formatUrl(poll.name, true)}`}
            target='_blank'
            className='btn blue'>Share on Twitter

          <select className='browser-default'
            onChange={(e) => dispatch(changeSelectedOption(poll.name, e.target.value))}
            defaultValue={poll.selectedOption}
          >
            <option value='select' disabled>Select an option to vote</option>
            {options.map((x, i) => (
              <option key={i} value={x}>{x}</option>
            ))}
          </select>

          <button
            onClick={(e) => {
              e.preventDefault();
              dispatch(postVoteOnPoll(poll.name, poll.selectedOption))}}
            type='submit' className='btn'
            disabled={poll.selectedOption === 'select'}>Submit</button>

          <Bar data={data} width={400} height={250}/>

  } else {
    return

Unable to find the poll:

{pollName}

  }
}
<|endoftext|>


<commit_before>const React = require('react');
const csp = require('js-csp');
const { go, chan, take, put, ops } = csp;
const { displayDate } = require('../lib/date');
const ghm = require('../lib/showdown-ghm.js');
const statics = require('impl/statics');
const actions = require('../actions/blog');
const { connect } = require('../lib/redux');
const classNames = require('classnames');
const withLocalState = require('../lib/local-state');

const dom = React.DOM;
const { div, ul, li, a } = dom;
const Link = React.createFactory(require("react-router").Link);
const Page = React.createFactory(require('./page'));
const Block = React.createFactory(require('./block'));
const NotFound = React.createFactory(require('./not-found'));

const RandomMessage = React.createClass({
  getInitialState: function() {
    // We have to keep this in state because we randomly choose one of
    // these, but we can't run that on the server so do it in
    // componentDidMount
    let messages = [
      'to tell me why I\'m wrong.',
      'to discuss this post.',
      'to tell me why you\'re disgusted.',
      'to tell me what you love about this.',
      'to hate on me.'
    ];
    return { messages: messages, messageSuffix: '' };
  },

  componentDidMount: function() {
    let messages = this.state.messages;
    let messageSuffix = messages[Math.random()*messages.length | 0];
    this.setState({ messageSuffix: messageSuffix });
  },

  render: function() {
    return dom.div(
      null,
      a({ href: 'https://twitter.com/jlongster' }, 'Tweet at me'),
      ' ' + this.state.messageSuffix
    );
  }
});

const HeaderImage = React.createClass({
  getInitialState: function() {
    return { undersized: false };
  },

  componentDidMount: function() {
    // Yeah yeah hardcoded values. 1200 is the width of full-size
    // header images. I probably should abstract that out, but I got
    // cheezits to eat.
    this.setState({ undersized: window.innerWidth < 1200 });
    window.addEventListener('resize', this.handleWindowResize);
  },

  componentWillUnmount: function() {
    window.removeEventListener('resize', this.handleWindowResize);
  },

  handleWindowResize: function() {
    if(this.props.fullWidth) {
      if(window.innerWidth < 1200) {
        this.setState({ undersized: true });
      }
      else {
        this.setState({ undersized: false });
      }
    }
  },

  render: function() {
    return div({
      className: classNames({
        'full-img': this.props.fullWidth,
        'intro-img': !this.props.fullWidth,
        'undersized': this.state.undersized,
        'oversized': !this.state.undersized
      })
    }, dom.img({ src: this.props.url }));
  }
});

const Post = React.createClass({
  displayName: 'Post',

  componentDidMount: function() {
    this.updateDOM();
  },

  componentDidUpdate: function(prevProps) {
    if(this.props.post !== prevProps.post) {
      this.updateDOM();
    }
  },

  updateDOM: function() {
    const node = React.findDOMNode(this);
    if(!node) {
      return;
    }

    // TODO: turn markdown into React nodes
    const article = node.querySelector('article');
    const articleRect = article.getBoundingClientRect();

    const anchorables = node.querySelectorAll(
      'article h2, article h3, article h4'
    );
    for(var i=0; i<anchorables.length; i++) {
      let anchorable = anchorables[i];
      let anchor = document.createElement('a');
      anchor.href = '#' + anchorable.id;
      anchor.className = 'text-anchor';
      anchor.textContent = '#';
      anchorable.appendChild(anchor);
    }

    const post = this.props.post;
    if(post && post.assets) {
      // TODO: this is a big hack right now and I'm not even going to
      // explain why... let's just say I need to fix this
      let script = document.createElement('script');
      script.src = post.assets;
      this.getDOMNode().appendChild(script);
    }
  },

  render: function () {
    let post = this.props.post;
    let next = this.props.readnext;

    if(post === false) {
      return NotFound();
    }
    else if(!post) {
      return null;
    }

    return Page(
      // TODO(jwl): Hack to replace commas because those aren't valid ids.
      // Need to disallows commas in URLs.
      { id: post.shorturl.replace(',', '-') },

      Block(
        { name: 'before-footer' },
        div(
          { className: 'additional-footer' },
          div(
            { className: 'additional-footer-inner-ugh' },
            div(
              { className: 'meta' },
              div(
                { className: 'comments' },
                React.createElement(RandomMessage)
              ),
              div({ className: 'social',
                    dangerouslySetInnerHTML: { __html: statics.socialHTML }})
            ),
            next && div(
              { className: 'readnext' },
              dom.h3(
                null,
                'Read Next: ',
                a({ href: '/' + next.shorturl }, next.title)
              ),
              dom.p({ dangerouslySetInnerHTML: { __html: next.abstract }})
            )
          )
        )
      ),

      post.headerimg &&
        React.createElement(
          HeaderImage,
          { url: post.headerimg,
            fullWidth: post.headerimgfull }
        ),

      dom.article(
        { className: 'post' },

        dom.div(
          { className: classNames('header-text',
                                  { 'has-bg-image': post.headerimgfull }) },
          dom.h1(null, post.title),
          div({ className: 'date' }, displayDate(post.date))
        ),
        div({ dangerouslySetInnerHTML: {
          __html: ghm.parse(post.content)
        }}),
        div(
          { className: 'tags' },
          post.tags && post.tags.map(tag => {
            return dom.a({ key: tag, href: '/tag/' + tag }, tag);
          })
        )
      )
    );
  }
});

module.exports = connect(Post, {
  pageClass: 'post-page',

  runQueries: function (dispatch, state, params) {
    const id = decodeURI(params.post);

    go(function*() {
      const post = yield dispatch(actions.getPost(id));

      if(post) {
        dispatch(actions.updatePage({
          title: post.title
        }));

        if(post.readnext) {
          dispatch(actions.queryPosts({
            name: 'readnext',
            select: ['title', 'abstract', 'shorturl'],
            filter: { shorturl: post.readnext }
          }));
        }
      }
      else {
        console.log('WARNING: post not found: ' + id);
      }
    });
  },

  select: function(state, params) {
    const id = decodeURI(params.post);
    const readnextQuery = state.posts.get(['postsByQueryName', 'readnext']);
    return {
      post: state.posts.getIn(['postsById', id]),
      readnext: readnextQuery ? readnextQuery[0] : null
    };
  }
});
<commit_msg>tweak header images<commit_after>const React = require('react');
const csp = require('js-csp');
const { go, chan, take, put, ops } = csp;
const { displayDate } = require('../lib/date');
const ghm = require('../lib/showdown-ghm.js');
const statics = require('impl/statics');
const actions = require('../actions/blog');
const { connect } = require('../lib/redux');
const classNames = require('classnames');
const withLocalState = require('../lib/local-state');

const dom = React.DOM;
const { div, ul, li, a } = dom;
const Link = React.createFactory(require("react-router").Link);
const Page = React.createFactory(require('./page'));
const Block = React.createFactory(require('./block'));
const NotFound = React.createFactory(require('./not-found'));

const RandomMessage = React.createClass({
  getInitialState: function() {
    // We have to keep this in state because we randomly choose one of
    // these, but we can't run that on the server so do it in
    // componentDidMount
    let messages = [
      'to tell me why I\'m wrong.',
      'to discuss this post.',
      'to tell me why you\'re disgusted.',
      'to tell me what you love about this.',
      'to hate on me.'
    ];
    return { messages: messages, messageSuffix: '' };
  },

  componentDidMount: function() {
    let messages = this.state.messages;
    let messageSuffix = messages[Math.random()*messages.length | 0];
    this.setState({ messageSuffix: messageSuffix });
  },

  render: function() {
    return dom.div(
      null,
      a({ href: 'https://twitter.com/jlongster' }, 'Tweet at me'),
      ' ' + this.state.messageSuffix
    );
  }
});

const HeaderImage = React.createClass({
  getInitialState: function() {
    return { undersized: false };
  },

  componentDidMount: function() {
    // Yeah yeah hardcoded values. 1200 is the width of full-size
    // header images. I probably should abstract that out, but I got
    // cheezits to eat.
    this.setState({ undersized: window.innerWidth < 1200 });
    window.addEventListener('resize', this.handleWindowResize);
  },

  componentWillUnmount: function() {
    window.removeEventListener('resize', this.handleWindowResize);
  },

  handleWindowResize: function() {
    if(this.props.fullWidth) {
      if(window.innerWidth < 1200) {
        this.setState({ undersized: true });
      }
      else {
        this.setState({ undersized: false });
      }
    }
  },

  render: function() {
    return div(
      { className:
        classNames({ 'full-img': this.props.fullWidth,
                     'intro-img': !this.props.fullWidth,
                     'undersized': this.state.undersized,
                     'oversized': !this.state.undersized }) },
      div({ className: 'overlay' }),
      dom.img({ src: this.props.url })
    );
  }
});

const Post = React.createClass({
  displayName: 'Post',

  componentDidMount: function() {
    this.updateDOM();
  },

  componentDidUpdate: function(prevProps) {
    if(this.props.post !== prevProps.post) {
      this.updateDOM();
    }
  },

  updateDOM: function() {
    const node = React.findDOMNode(this);
    if(!node) {
      return;
    }

    // TODO: turn markdown into React nodes
    const article = node.querySelector('article');
    const articleRect = article.getBoundingClientRect();

    const anchorables = node.querySelectorAll(
      'article h2, article h3, article h4'
    );
    for(var i=0; i<anchorables.length; i++) {
      let anchorable = anchorables[i];
      let anchor = document.createElement('a');
      anchor.href = '#' + anchorable.id;
      anchor.className = 'text-anchor';
      anchor.textContent = '#';
      anchorable.appendChild(anchor);
    }

    const post = this.props.post;
    if(post && post.assets) {
      // TODO: this is a big hack right now and I'm not even going to
      // explain why... let's just say I need to fix this
      let script = document.createElement('script');
      script.src = post.assets;
      this.getDOMNode().appendChild(script);
    }
  },

  render: function () {
    let post = this.props.post;
    let next = this.props.readnext;

    if(post === false) {
      return NotFound();
    }
    else if(!post) {
      return null;
    }

    return Page(
      // TODO(jwl): Hack to replace commas because those aren't valid ids.
      // Need to disallows commas in URLs.
      { id: post.shorturl.replace(',', '-'),
        className: classNames({
          'has-bg-image': (post.headerimg &&
                           post.headerimgfull)
        })},

      Block(
        { name: 'before-footer' },
        div(
          { className: 'additional-footer' },
          div(
            { className: 'additional-footer-inner-ugh' },
            div(
              { className: 'meta' },
              div(
                { className: 'comments' },
                React.createElement(RandomMessage)
              ),
              div({ className: 'social',
                    dangerouslySetInnerHTML: { __html: statics.socialHTML }})
            ),
            next && div(
              { className: 'readnext' },
              dom.h3(
                null,
                'Read Next: ',
                a({ href: '/' + next.shorturl }, next.title)
              ),
              dom.p({ dangerouslySetInnerHTML: { __html: next.abstract }})
            )
          )
        )
      ),

      post.headerimg &&
        React.createElement(
          HeaderImage,
          { url: post.headerimg,
            fullWidth: post.headerimgfull }
        ),

      dom.article(
        { className: 'post' },

        dom.div(
          { className: classNames('header-text',
                                  { 'has-bg-image': post.headerimgfull }) },
          dom.h1(null, post.title),
          div({ className: 'date' }, displayDate(post.date))
        ),
        div({ dangerouslySetInnerHTML: {
          __html: ghm.parse(post.content)
        }}),
        div(
          { className: 'tags' },
          post.tags && post.tags.map(tag => {
            return dom.a({ key: tag, href: '/tag/' + tag }, tag);
          })
        )
      )
    );
  }
});

module.exports = connect(Post, {
  pageClass: 'post-page',

  runQueries: function (dispatch, state, params) {
    const id = decodeURI(params.post);

    go(function*() {
      const post = yield dispatch(actions.getPost(id));

      if(post) {
        dispatch(actions.updatePage({
          title: post.title
        }));

        if(post.readnext) {
          dispatch(actions.queryPosts({
            name: 'readnext',
            select: ['title', 'abstract', 'shorturl'],
            filter: { shorturl: post.readnext }
          }));
        }
      }
      else {
        console.log('WARNING: post not found: ' + id);
      }
    });
  },

  select: function(state, params) {
    const id = decodeURI(params.post);
    const readnextQuery = state.posts.get(['postsByQueryName', 'readnext']);
    return {
      post: state.posts.getIn(['postsById', id]),
      readnext: readnextQuery ? readnextQuery[0] : null
    };
  }
});
<|endoftext|>


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

import studentActions from '../flux/student-actions'
import Student from '../models/student'

import Button from './button'
import Semester from './semester'

import isCurrentYear from '../helpers/is-current-year'
import expandYear from '../helpers/expand-year'
import semesterName from '../helpers/semester-name'
import findFirstAvailableSemester from '../helpers/find-first-available-semester'

import './year.scss'

export default class Year extends Component {
	static propTypes = {
		courses: PropTypes.instanceOf(Immutable.List),
		coursesLoaded: PropTypes.bool.isRequired,
		showSearchSidebar: PropTypes.func.isRequired,
		student: PropTypes.instanceOf(Student).isRequired,
		year: PropTypes.number.isRequired,
	}

	canAddSemester = () => {
		return findFirstAvailableSemester(this.props.student.schedules, this.props.year) <= 5
	}

	addSemester = () => {
		const nextAvailableSemester = findFirstAvailableSemester(this.props.student.schedules, this.props.year)

		studentActions.addSchedule(this.props.student.id, {
			year: this.props.year, semester: nextAvailableSemester,
			sequence: 1, active: true,
		})
	}

	removeYear = () => {
		const scheduleIds = this.props.student.schedules
			.filter(isCurrentYear(this.props.year))
			.map(sched => sched.id)

		studentActions.destroyMultipleSchedules(this.props.student.id, scheduleIds)
	}

	render() {
		// console.log('Year#render')
		const terms = this.props.student.schedules
			.filter(sched => sched.active)
			.filter(sched => sched.year === this.props.year)
			.sortBy(schedule => schedule.semester)
			.map(schedule =>
				<Semester
					key={`${schedule.year}-${schedule.semester}-${schedule.id}`}
					student={this.props.student}
					semester={schedule.semester}
					year={this.props.year}
					courses={this.props.courses.filter(c => schedule.clbids.includes(c.clbid))}
					coursesLoaded={this.props.coursesLoaded}
					showSearchSidebar={this.props.showSearchSidebar}
				/>)
			.toList()

		const niceYear = expandYear(this.props.year)

		const nextAvailableSemester = findFirstAvailableSemester(this.props.student.schedules, this.props.year)
		const isAddSemesterDisabled = !(this.canAddSemester())

		return (

{niceYear}

						<Button className='add-semester'
							type='flat'
							title='Add Semester'
							disabled={isAddSemesterDisabled}
							onClick={this.addSemester}>
							{`Add ‘${semesterName(nextAvailableSemester)}’`}
						</Button>
						<Button className='remove-year' type='flat'
							title={`Remove the year ${niceYear}`}
							onClick={this.removeYear}>
							Remove Year
						</Button>

						{terms.toArray()}

		)
	}
}
<commit_msg>… there's no `sequence` prop on schedules<commit_after>import React, {Component, PropTypes} from 'react'
import Immutable from 'immutable'

import studentActions from '../flux/student-actions'
import Student from '../models/student'

import Button from './button'
import Semester from './semester'

import isCurrentYear from '../helpers/is-current-year'
import expandYear from '../helpers/expand-year'
import semesterName from '../helpers/semester-name'
import findFirstAvailableSemester from '../helpers/find-first-available-semester'

import './year.scss'

export default class Year extends Component {
	static propTypes = {
		courses: PropTypes.instanceOf(Immutable.List),
		coursesLoaded: PropTypes.bool.isRequired,
		showSearchSidebar: PropTypes.func.isRequired,
		student: PropTypes.instanceOf(Student).isRequired,
		year: PropTypes.number.isRequired,
	}

	canAddSemester = () => {
		return findFirstAvailableSemester(this.props.student.schedules, this.props.year) <= 5
	}

	addSemester = () => {
		const nextAvailableSemester = findFirstAvailableSemester(this.props.student.schedules, this.props.year)

		studentActions.addSchedule(this.props.student.id, {
			year: this.props.year, semester: nextAvailableSemester,
			index: 1, active: true,
		})
	}

	removeYear = () => {
		const scheduleIds = this.props.student.schedules
			.filter(isCurrentYear(this.props.year))
			.map(sched => sched.id)

		studentActions.destroyMultipleSchedules(this.props.student.id, scheduleIds)
	}

	render() {
		// console.log('Year#render')
		const terms = this.props.student.schedules
			.filter(sched => sched.active)
			.filter(sched => sched.year === this.props.year)
			.sortBy(schedule => schedule.semester)
			.map(schedule =>
				<Semester
					key={`${schedule.year}-${schedule.semester}-${schedule.id}`}
					student={this.props.student}
					semester={schedule.semester}
					year={this.props.year}
					courses={this.props.courses.filter(c => schedule.clbids.includes(c.clbid))}
					coursesLoaded={this.props.coursesLoaded}
					showSearchSidebar={this.props.showSearchSidebar}
				/>)
			.toList()

		const niceYear = expandYear(this.props.year)

		const nextAvailableSemester = findFirstAvailableSemester(this.props.student.schedules, this.props.year)
		const isAddSemesterDisabled = !(this.canAddSemester())

		return (

{niceYear}

						<Button className='add-semester'
							type='flat'
							title='Add Semester'
							disabled={isAddSemesterDisabled}
							onClick={this.addSemester}>
							{`Add ‘${semesterName(nextAvailableSemester)}’`}
						</Button>
						<Button className='remove-year' type='flat'
							title={`Remove the year ${niceYear}`}
							onClick={this.removeYear}>
							Remove Year
						</Button>

						{terms.toArray()}

		)
	}
}
<|endoftext|>