Benoit Sida 3 년 전
부모
커밋
278d5e1176

+ 1
- 0
.meteor/packages 파일 보기

23
 fourseven:scss
23
 fourseven:scss
24
 maxharris9:classnames
24
 maxharris9:classnames
25
 momentjs:moment
25
 momentjs:moment
26
+fortawesome:fontawesome

+ 1
- 0
.meteor/versions 파일 보기

24
 ejson@1.0.13
24
 ejson@1.0.13
25
 es5-shim@4.6.15
25
 es5-shim@4.6.15
26
 fastclick@1.0.13
26
 fastclick@1.0.13
27
+fortawesome:fontawesome@4.7.0
27
 fourseven:scss@4.5.0
28
 fourseven:scss@4.5.0
28
 geojson-utils@1.0.10
29
 geojson-utils@1.0.10
29
 hot-code-push@1.0.4
30
 hot-code-push@1.0.4

+ 22
- 6
imports/ui/App.jsx 파일 보기

1
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
2
 import './styles/App';
2
 import './styles/App';
3
 import Board from './Board';
3
 import Board from './Board';
4
+import Info from './Info';
4
 
5
 
5
 export default class App extends Component {
6
 export default class App extends Component {
7
+	constructor(props) {
8
+		super(props);
9
+		this.state = {
10
+			infoVisible: false
11
+		};
12
+	}
13
+
14
+	toggleInfo() {
15
+		this.setState({ infoVisible: !this.state.infoVisible });
16
+	}
17
+
6
 	render() {
18
 	render() {
7
 		return (
19
 		return (
8
 			<div id="app-container">
20
 			<div id="app-container">
9
-				<header>ESPTrainer</header>
21
+				<header>
22
+					<h1>ESPTrainer</h1>
23
+					<div className="flex-space" />
24
+					<div><i className="info fa fa-lg fa-info-circle" onClick={this.toggleInfo.bind(this)}/></div>
25
+				</header>
10
 				<main id="content">
26
 				<main id="content">
11
-					{/*<div className="left" />*/}
12
 					<div className="center">
27
 					<div className="center">
13
-						<Board />
14
-						{/*<Actions></Actions>*/}
28
+						{ this.state.infoVisible ? <Info /> : <Board /> }
15
 					</div>
29
 					</div>
16
-					{/*<div className="right" />*/}
17
 				</main>
30
 				</main>
18
-				<footer>Copyright © 2017 Coldiary</footer>
31
+				<footer>
32
+					<div>Copyright © 2017 Coldiary</div>
33
+					<div className="credits">Based on Russell Targ's ESPTrainer on iOS</div>
34
+				</footer>
19
 			</div>
35
 			</div>
20
 		);
36
 		);
21
 	}
37
 	}

+ 0
- 1
imports/ui/Board.jsx 파일 보기

16
 		this.actions = [
16
 		this.actions = [
17
 			{ label: 'Reset', action: this.reset.bind(this), active: () => true },
17
 			{ label: 'Reset', action: this.reset.bind(this), active: () => true },
18
 			{ label: 'Pass', action: this.pass.bind(this), active: () => !this.state.end },
18
 			{ label: 'Pass', action: this.pass.bind(this), active: () => !this.state.end },
19
-			{ label: 'AddScore', action: () => this.registerScore(Math.floor(Math.random() * 100) % 24), active: () => true }
20
 		];
19
 		];
21
 		this.choices = [0, 1, 2, 3].map(i => this.choice.bind(this, i));
20
 		this.choices = [0, 1, 2, 3].map(i => this.choice.bind(this, i));
22
 	}
21
 	}

+ 1
- 0
imports/ui/BoardLayout.jsx 파일 보기

10
 
10
 
11
 const BoardLayout = ({ active, win, actions, trials, score, scores, image, choices, highlighted }) =>
11
 const BoardLayout = ({ active, win, actions, trials, score, scores, image, choices, highlighted }) =>
12
 	<div className="board">
12
 	<div className="board">
13
+		<div className="title">Tap the correct square to see a picture</div>
13
 		<Score score={score} />
14
 		<Score score={score} />
14
 		<div className="squares">
15
 		<div className="squares">
15
 			<div className="row">
16
 			<div className="row">

+ 18
- 0
imports/ui/Info.jsx 파일 보기

1
+import React, { Component, PropTypes } from 'react';
2
+import './styles/Info';
3
+
4
+export default class Info extends Component {
5
+	render() {
6
+		return <div className="Info">
7
+			<em>This program is a clone of the Russell Targ's App on the iOS platform. All credits goes to him.</em>
8
+			<div>Extract from the app:</div>
9
+			<blockquote>
10
+				<div>The player is presented with four colored squares. For each trial, one has been selected at random by the ESP Trainer. Your task is to choose the correct square.</div>
11
+				<div>If you succeed, you will [...] see a large color picture. Otherwise, the system lights up the correct square, and you proceed with the next trial.</div>
12
+				<div>The score indicator at the top counts the number of correct choices. [...] After 24 trials you may begin a new game.</div>
13
+			</blockquote>
14
+			<div>You can find the app at the link below :</div>
15
+			<a href="https://itunes.apple.com/fr/app/esp-trainer/id336882103?mt=8" className="apple-link" />
16
+		</div>;
17
+	}
18
+}

+ 1
- 0
imports/ui/Score.jsx 파일 보기

3
 
3
 
4
 const Score = ({ score }) =>
4
 const Score = ({ score }) =>
5
 	<div className="score">
5
 	<div className="score">
6
+		<h3>Correct</h3>
6
 		<div className="scale">
7
 		<div className="scale">
7
 			{ [...Array(25).keys()].map(x => <div key={x} className="grade" />) }
8
 			{ [...Array(25).keys()].map(x => <div key={x} className="grade" />) }
8
 		</div>
9
 		</div>

+ 24
- 30
imports/ui/ScoreChart.jsx 파일 보기

1
 import React, { Component, PropTypes} from 'react';
1
 import React, { Component, PropTypes} from 'react';
2
 import Chart from 'chart.js';
2
 import Chart from 'chart.js';
3
 
3
 
4
-Chart.defaults.global.legend.labels.fontColor = '#fff';
5
-const dateFormat = 'DD/MM/YYYY H:ss';
6
-const ScoreScales = {
7
-	yAxes: [{
8
-		ticks: {
9
-			fontColor: "#fff",
10
-			stepSize: 6,
11
-			max: 24,
12
-		}
13
-	}],
14
-	xAxes: [{
15
-		type: 'time',
16
-		time: {
17
-			fontColor: "#fff",
18
-			fontSize: 10,
19
-			parser: moment.unix,
20
-			tooltipFormat: dateFormat,
21
-			//unit: 'day'
22
-		},
23
-		ticks: {
24
-			fontColor: "#fff"
25
-		}
26
-	}]
27
-};
4
+
5
+
28
 
6
 
29
 
7
 
30
 export default class ScoreChart extends Component {
8
 export default class ScoreChart extends Component {
31
 	constructor(props) {
9
 	constructor(props) {
32
 		super(props);
10
 		super(props);
11
+		Chart.defaults.global.legend.labels.fontColor = '#fff';
33
 		this.chart = null;
12
 		this.chart = null;
13
+		this.scoreScales = {
14
+			yAxes: [{
15
+				ticks: {
16
+					fontColor: "#fff",
17
+					stepSize: 6,
18
+					max: 24,
19
+				}
20
+			}],
21
+			xAxes: [{
22
+				ticks: {
23
+					fontColor: "#fff",
24
+					fontSize: 10,
25
+				}
26
+			}]
27
+		};
34
 	}
28
 	}
35
 
29
 
36
 	shouldComponentUpdate(nextProps) {
30
 	shouldComponentUpdate(nextProps) {
40
 	componentDidMount() {
34
 	componentDidMount() {
41
 		let labels = Object.keys(this.props.data);
35
 		let labels = Object.keys(this.props.data);
42
 		const data = labels.map(key => this.props.data[key]);
36
 		const data = labels.map(key => this.props.data[key]);
43
-		// labels = labels.map(d => moment.unix(d).format(dateFormat).split(' '));
37
+		labels = labels.map(ts => moment.unix(ts).format('DD/MM/YYYY H:ss'));
44
 		this.chart = new Chart(this.canvas, {
38
 		this.chart = new Chart(this.canvas, {
45
 			type: 'line',
39
 			type: 'line',
46
 			data: {
40
 			data: {
48
 				datasets: [{
42
 				datasets: [{
49
 					label: 'Progression',
43
 					label: 'Progression',
50
 					data: data,
44
 					data: data,
51
-					backgroundColor: 'rgba(255, 99, 132, 0.2)',
52
-					borderColor: 'rgba(255,99,132,1)',
45
+					backgroundColor: 'rgba(33, 150, 243, 0.2)',
46
+					borderColor: 'rgba(33, 150, 243, 1)',
53
 					borderWidth: 1
47
 					borderWidth: 1
54
 				}]
48
 				}]
55
 			},
49
 			},
56
-			options: { scales: ScoreScales }
50
+			options: { scales: this.scoreScales }
57
 		});
51
 		});
58
 	}
52
 	}
59
 
53
 
60
 	componentDidUpdate() {
54
 	componentDidUpdate() {
61
 		let labels = Object.keys(this.props.data);
55
 		let labels = Object.keys(this.props.data);
62
 		const data = labels.map(key => this.props.data[key]);
56
 		const data = labels.map(key => this.props.data[key]);
63
-		// labels = labels.map(d => moment.unix(d).format(dateFormat).split(' '));
57
+		labels = labels.map(ts => moment.unix(ts).format('DD/MM/YYYY H:ss'));
64
 		this.chart.data.labels = labels;
58
 		this.chart.data.labels = labels;
65
 		this.chart.data.datasets[0].data = data;
59
 		this.chart.data.datasets[0].data = data;
66
 		this.chart.update();
60
 		this.chart.update();
67
 	}
61
 	}
68
 
62
 
69
 	render() {
63
 	render() {
70
-		return <canvas ref={(node) => this.canvas = node} width={400}/>;
64
+		return <canvas ref={(node) => this.canvas = node} />;
71
 	}
65
 	}
72
 }
66
 }
73
 
67
 

+ 1
- 1
imports/ui/styles/Actions.scss 파일 보기

4
   display: flex;
4
   display: flex;
5
   justify-content: center;
5
   justify-content: center;
6
   flex-wrap: wrap;
6
   flex-wrap: wrap;
7
-  margin-top: 20px;
7
+  margin: 20px 0;
8
 
8
 
9
   button {
9
   button {
10
     background: white;
10
     background: white;

+ 22
- 2
imports/ui/styles/App.scss 파일 보기

12
     display: flex;
12
     display: flex;
13
     flex-direction: row;
13
     flex-direction: row;
14
     justify-content: center;
14
     justify-content: center;
15
-    align-items: stretch;
15
+    align-items: flex-start;
16
 }
16
 }
17
 
17
 
18
 header {
18
 header {
19
+    display: flex;
20
+    flex-direction: row;
19
     height: 64px;
21
     height: 64px;
20
     background: #23273c;
22
     background: #23273c;
21
     color: white;
23
     color: white;
22
     line-height: 64px;
24
     line-height: 64px;
23
-    padding-left: 10px;
25
+    padding: 0 10px;
26
+
27
+    h1 {
28
+        letter-spacing: 0.1em;
29
+        font-size: 1.5em;
30
+    }
31
+
32
+    .flex-space {
33
+        flex: 1;
34
+    }
35
+    
36
+    .info {
37
+        cursor: pointer;
38
+    }
24
 }
39
 }
25
 
40
 
26
 .left, .right {
41
 .left, .right {
59
     text-align: center;
74
     text-align: center;
60
     color: white;
75
     color: white;
61
     padding: 10px;
76
     padding: 10px;
77
+
78
+    .credits {
79
+        margin-top: 10px;
80
+        font-size: 0.8em;
81
+    }
62
 }
82
 }

+ 7
- 0
imports/ui/styles/Board.scss 파일 보기

4
     align-items: stretch;
4
     align-items: stretch;
5
     max-width: 800px;
5
     max-width: 800px;
6
 
6
 
7
+    .title {
8
+        color: #fff;
9
+        text-align: center;
10
+        margin-bottom: 30px;
11
+        letter-spacing: 0.1em;
12
+    }
13
+
7
     .squares {
14
     .squares {
8
         position: relative;
15
         position: relative;
9
         display: flex;
16
         display: flex;

+ 50
- 0
imports/ui/styles/Info.scss 파일 보기

1
+@import "compat";
2
+
3
+.Info {
4
+  max-width: 440px;
5
+  display: flex;
6
+  flex-direction: column;
7
+  align-items: center;
8
+  color: #fff;
9
+  padding: 20px 50px;
10
+  @include box-sizing(border-box);
11
+  text-align: center;
12
+
13
+  blockquote  {
14
+    border-left: 3px solid grey;
15
+    padding-left: 10px;
16
+    text-align: justify;
17
+    margin: 20px 0;
18
+
19
+    &:before {
20
+      content: '“';
21
+      float: left;
22
+      font-size: 2em;
23
+      margin-right: 20px;
24
+    }
25
+
26
+    &:after {
27
+      content: '”';
28
+      float: right;
29
+      font-size: 2em;
30
+      margin-top: -25px;
31
+    }
32
+
33
+  }
34
+
35
+  * {
36
+    margin-bottom: 10px;
37
+  }
38
+
39
+  .apple-link {
40
+    display: inline-block;
41
+    overflow: hidden;
42
+    margin-top: 20px;
43
+    background: url(//linkmaker.itunes.apple.com/assets/shared/badges/fr-fr/appstore-lrg.svg) no-repeat;
44
+    width: 135px;
45
+    height: 40px;
46
+    background-size: contain;
47
+    cursor: pointer;
48
+  }
49
+  
50
+}

+ 11
- 3
imports/ui/styles/Score.scss 파일 보기

5
   flex-direction: column;
5
   flex-direction: column;
6
   margin-bottom: 50px;
6
   margin-bottom: 50px;
7
 
7
 
8
+  h3 {
9
+    color: #fff;
10
+    margin-bottom: 10px;
11
+    text-transform: uppercase;
12
+    letter-spacing: 0.1em;
13
+  }
14
+
8
   .current-score {
15
   .current-score {
9
     background: #fff;
16
     background: #fff;
10
     height: 3px;
17
     height: 3px;
36
       @mixin grade-label($number) {
43
       @mixin grade-label($number) {
37
         content: quote(inspect($number));
44
         content: quote(inspect($number));
38
         position: absolute;
45
         position: absolute;
39
-        top: -20px;
40
-        @if($number > 10) { left: -8px; }
41
-        @else { left: -4px; }
46
+        font-size: 0.7em;
47
+        top: -15px;
48
+        @if($number > 10) { left: -5px; }
49
+        @else { left: -2px; }
42
         color: white;
50
         color: white;
43
       }
51
       }
44
 
52
 

+ 5
- 1
imports/ui/styles/Square.scss 파일 보기

1
 @import "gradient";
1
 @import "gradient";
2
 @import "shadow";
2
 @import "shadow";
3
+@import "compat";
3
 
4
 
4
 $square-blue: blue;
5
 $square-blue: blue;
5
 $square-green: green;
6
 $square-green: green;
25
         @if($inverted) { @include gradient(lighten($color, 20), $color, $direction); }
26
         @if($inverted) { @include gradient(lighten($color, 20), $color, $direction); }
26
         @else { @include gradient($color, lighten($color, 20), $direction); }
27
         @else { @include gradient($color, lighten($color, 20), $direction); }
27
 
28
 
28
-        &.highlighted { @include radial-gradient($color); }
29
+        &.highlighted {
30
+            @include radial-gradient($color);
31
+            @include scale(1.1);
32
+        }
29
 
33
 
30
         &.disabled {
34
         &.disabled {
31
             $color: desaturate($color, 50);
35
             $color: desaturate($color, 50);

+ 13
- 0
imports/ui/styles/_compat.scss 파일 보기

1
+@mixin scale($amount) {
2
+  -webkit-transform: scale($amount);
3
+  -moz-transform: scale($amount);
4
+  -ms-transform: scale($amount);
5
+  -o-transform: scale($amount);
6
+  transform: scale($amount);
7
+}
8
+
9
+@mixin box-sizing($value) {
10
+  -webkit-box-sizing: $value;
11
+  -moz-box-sizing: $value;
12
+  box-sizing: $value;
13
+}