Skip to content

Commit 6e013ab

Browse files
committed
check if tutorial is latest, add update button
1 parent 7726b7d commit 6e013ab

35 files changed

+252
-152
lines changed

lib/actions.js

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ exports.tutorialSet = actions_10.tutorialSet;
3636
var actions_11 = require('./modules/tutorials/actions');
3737
exports.tutorialsFind = actions_11.tutorialsFind;
3838
exports.tutorialUpdate = actions_11.tutorialUpdate;
39+
exports.tutorialsUpdate = actions_11.tutorialsUpdate;
3940
var actions_12 = require('./modules/window/actions');
4041
exports.windowToggle = actions_12.windowToggle;
4142
exports.quit = actions_12.quit;

lib/components/Tutorials/UpdateTutorial/index.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ var UpdateTutorial = (function (_super) {
2626
UpdateTutorial.prototype.render = function () {
2727
var _a = this.props, tutorial = _a.tutorial, tutorialUpdate = _a.tutorialUpdate;
2828
return (React.createElement("span", null,
29-
React.createElement(update_1.default, {style: styles.icon, color: colors_1.pink500, onTouchTap: tutorialUpdate.bind(this, tutorial.name)}),
30-
"``",
31-
React.createElement("span", {style: styles.latest}, tutorial.latest)));
29+
React.createElement(update_1.default, {style: styles.icon, color: colors_1.pink500, onTouchTap: tutorialUpdate.bind(this, tutorial.name)})
30+
));
3231
};
3332
return UpdateTutorial;
3433
}(React.Component));

lib/components/Tutorials/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ var Tutorials = (function (_super) {
3636
),
3737
React.createElement(Table_1.TableRowColumn, null,
3838
tutorial.version,
39-
!!tutorial.latest
39+
!tutorial.latest
4040
? React.createElement(UpdateTutorial_1.default, {tutorial: tutorial})
4141
: null)));
4242
}))),

lib/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ var StatusBar_1 = require('./components/StatusBar');
55
var setup_1 = require('./modules/setup');
66
var store_1 = require('./store');
77
var subscriptions_1 = require('./subscriptions');
8-
var utils_1 = require('./utils');
8+
var polyfills_1 = require('./utils/polyfills');
99
var injectTapEventPlugin = require('react-tap-event-plugin');
1010
process.env.NODE_ENV = 'production';
1111
var Main = (function () {
1212
function Main() {
1313
injectTapEventPlugin();
14-
utils_1.default();
14+
polyfills_1.default();
1515
store_1.default.dispatch(setup_1.setupVerify());
1616
this.side = SidePanel_1.sideElement.init();
1717
this.subscriptions = new subscriptions_1.default();
+7-33
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,17 @@
11
"use strict";
2+
var compareVersions_1 = require('../../../utils/compareVersions');
3+
var system_1 = require('../../../utils/system');
24
var atom_plugin_command_line_1 = require('atom-plugin-command-line');
35
var versions = {
46
node: '4.0.0',
57
atom: '1.8.0',
68
npm: '3.0.0'
79
};
8-
function matchVersions(v) {
9-
return v.match(/([0-9]+)\.([0-9]+)/);
10-
}
11-
function isAboveVersion(a, b) {
12-
if (a === b) {
13-
return true;
14-
}
15-
var a_components = a.split('.');
16-
var b_components = b.split('.');
17-
var len = Math.min(a_components.length, b_components.length);
18-
for (var i = 0; i < len; i++) {
19-
var first = parseInt(a_components[i], 10);
20-
var second = parseInt(b_components[i], 10);
21-
if (first > second) {
22-
return true;
23-
}
24-
if (first < second) {
25-
return false;
26-
}
27-
}
28-
if (a_components.length > b_components.length) {
29-
return true;
30-
}
31-
if (a_components.length < b_components.length) {
32-
return false;
33-
}
34-
return true;
35-
}
3610
function minVersion(command) {
3711
var minVersion = versions[command];
3812
return new Promise(function (resolve, reject) {
3913
var minOrLater = atom_plugin_command_line_1.default(command, '-v')
40-
.then(function (res) { return isAboveVersion(res, minVersion); });
14+
.then(function (res) { return compareVersions_1.isAboveVersion(res, minVersion); });
4115
if (!minOrLater) {
4216
resolve(false);
4317
}
@@ -51,7 +25,7 @@ function atomMinVersion() {
5125
return new Promise(function (resolve, reject) {
5226
var minOrLater = atom_plugin_command_line_1.default('atom', '-v').then(function (res) {
5327
var match = res.match(/Atom\s+:\s+([0-9]\.[0-9]\.[0-9])/);
54-
if (match && match[1] && isAboveVersion(match[1], versions.atom)) {
28+
if (match && match[1] && compareVersions_1.isAboveVersion(match[1], versions.atom)) {
5529
resolve(true);
5630
}
5731
else {
@@ -61,8 +35,8 @@ function atomMinVersion() {
6135
});
6236
}
6337
exports.atomMinVersion = atomMinVersion;
64-
function requiresXCode() {
65-
if (!navigator.platform.match(/Mac/)) {
38+
function hasOrDoesNotRequireXCode() {
39+
if (!system_1.isMac) {
6640
return true;
6741
}
6842
return atom_plugin_command_line_1.default('xcode-select', '-v').then(function (res) {
@@ -72,4 +46,4 @@ function requiresXCode() {
7246
return false;
7347
});
7448
}
75-
exports.requiresXCode = requiresXCode;
49+
exports.hasOrDoesNotRequireXCode = hasOrDoesNotRequireXCode;

lib/modules/setup/utils/verify.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ function setupVerify(dir, packageJson) {
1818
system: {
1919
node: !!check_system_1.minVersion('node'),
2020
npm: !!check_system_1.minVersion('npm'),
21-
xcode: !!check_system_1.requiresXCode(),
21+
xcode: !!check_system_1.hasOrDoesNotRequireXCode,
2222
atom: !!check_system_1.atomMinVersion(),
2323
},
2424
setup: {

lib/modules/tutorials/actions.js

+5
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,15 @@ function tutorialUpdate(title) {
1515
};
1616
}
1717
exports.tutorialUpdate = tutorialUpdate;
18+
function tutorialsUpdate() {
19+
return { type: types_1.TUTORIALS_UPDATE };
20+
}
21+
exports.tutorialsUpdate = tutorialsUpdate;
1822
function tutorialsFind() {
1923
return function (dispatch, getState) {
2024
var dir = getState().dir;
2125
dispatch({ type: types_1.TUTORIALS_FIND, payload: { dir: dir } });
26+
dispatch(tutorialsUpdate());
2227
};
2328
}
2429
exports.tutorialsFind = tutorialsFind;

lib/modules/tutorials/index.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
11
"use strict";
2-
var reducer_1 = require('./reducer');
3-
exports.reducer = reducer_1.default;
2+
var latestVersion_1 = require('./latestVersion');
3+
var types_1 = require('./types');
4+
var coderoad_cli_1 = require('coderoad-cli');
5+
function tutorialsReducer(t, action) {
6+
if (t === void 0) { t = []; }
7+
switch (action.type) {
8+
case types_1.TUTORIALS_FIND:
9+
var tuts = coderoad_cli_1.tutorials({ dir: action.payload.dir });
10+
return tuts ? tuts : t;
11+
case types_1.TUTORIALS_UPDATE:
12+
return t.map(function (tutorial) {
13+
var name = tutorial.name, version = tutorial.version;
14+
if (version) {
15+
latestVersion_1.default({ name: name, version: version })
16+
.then(function (x) { return tutorial.latest = x; });
17+
}
18+
return tutorial;
19+
});
20+
default:
21+
return t;
22+
}
23+
}
24+
Object.defineProperty(exports, "__esModule", { value: true });
25+
exports.default = tutorialsReducer;
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"use strict";
2+
var compareVersions_1 = require('../../utils/compareVersions');
3+
var fetch_1 = require('../../utils/fetch');
4+
var npmApiCall = function (name) { return ("https://registry.npmjs.org/" + name); };
5+
function isLatestVersion(_a) {
6+
var name = _a.name, version = _a.version;
7+
return (fetch_1.default(npmApiCall(name))
8+
.then(function (res) {
9+
if (res) {
10+
var latest = JSON.parse(res)['dist-tags'].latest;
11+
return compareVersions_1.isAboveVersion(version, latest);
12+
}
13+
return false;
14+
}));
15+
}
16+
Object.defineProperty(exports, "__esModule", { value: true });
17+
exports.default = isLatestVersion;

lib/modules/tutorials/types.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
"use strict";
2-
exports.TUTORIAL_UPDATE = 'TUTORIAL_UPDATE';
32
exports.TUTORIALS_FIND = 'TUTORIALS_FIND';
3+
exports.TUTORIALS_UPDATE = 'TUTORIALS_UPDATE';
4+
exports.TUTORIAL_UPDATE = 'TUTORIAL_UPDATE';

lib/options/tutorialConfig.js

-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ var tutorialConfigOptions = {
77
],
88
language: {
99
suffix: 'js',
10-
comments: '//',
1110
}
1211
},
1312
Python: {
@@ -16,7 +15,6 @@ var tutorialConfigOptions = {
1615
],
1716
language: {
1817
suffix: 'py',
19-
comments: '#',
2018
}
2119
},
2220
};

lib/reducers.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
1616
exports.default = redux_1.combineReducers({
1717
alert: alert_1.default, checks: setup_1.checks, editor: editor_1.reducer, dir: dir_1.default, hintPosition: hints_1.default,
1818
packageJson: setup_1.packageJson, pagePosition: page_1.pagePosition, progress: progress_1.default, route: route_1.reducer,
19-
tutorial: tutorial_1.reducer, tutorials: tutorials_1.reducer,
19+
tutorial: tutorial_1.reducer, tutorials: tutorials_1.default,
2020
taskActions: page_1.taskActions, taskPosition: tests_1.taskPosition, testRun: tests_1.testRun, window: window_1.reducer
2121
});

lib/utils/compareVersions.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"use strict";
2+
function matchVersions(v) {
3+
return v.match(/([0-9]+)\.([0-9]+)/);
4+
}
5+
function isAboveVersion(a, b) {
6+
if (a === b) {
7+
return true;
8+
}
9+
var a_components = a.split('.');
10+
var b_components = b.split('.');
11+
var len = Math.min(a_components.length, b_components.length);
12+
for (var i = 0; i < len; i++) {
13+
var first = parseInt(a_components[i], 10);
14+
var second = parseInt(b_components[i], 10);
15+
if (first > second) {
16+
return true;
17+
}
18+
if (first < second) {
19+
return false;
20+
}
21+
}
22+
if (a_components.length > b_components.length) {
23+
return true;
24+
}
25+
if (a_components.length < b_components.length) {
26+
return false;
27+
}
28+
return true;
29+
}
30+
exports.isAboveVersion = isAboveVersion;

lib/utils/polyfills/index.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"use strict";
2+
var object_values_1 = require('./object-values');
3+
function loadPolyfills() {
4+
object_values_1.default();
5+
}
6+
Object.defineProperty(exports, "__esModule", { value: true });
7+
exports.default = loadPolyfills;

lib/utils/polyfills/object-values.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use strict";
2+
function polyfillObjectValues() {
3+
if (typeof Object.values !== 'function') {
4+
Object.values = function (obj) {
5+
var vals = new Set();
6+
for (var key in obj) {
7+
vals.add(obj[key]);
8+
}
9+
return Array.from(vals);
10+
};
11+
}
12+
}
13+
Object.defineProperty(exports, "__esModule", { value: true });
14+
exports.default = polyfillObjectValues;

lib/utils/system.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
"use strict";
22
exports.isWindows = window.navigator.appVersion.indexOf('Win') > -1 || false;
3+
exports.isMac = !!navigator.platform.match(/Mac/);

src/actions.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ export {routeSet} from './modules/route/actions';
88
export {setupVerify, setupPackage} from './modules/setup/actions';
99
export {testLoad, testRun, testResult, testComplete} from './modules/tests/actions';
1010
export {tutorialSet} from './modules/tutorial/actions';
11-
export {tutorialsFind, tutorialUpdate} from './modules/tutorials/actions';
11+
export {tutorialsFind, tutorialUpdate, tutorialsUpdate} from './modules/tutorials/actions';
1212
export { windowToggle, quit} from './modules/window/actions';

src/components/Tutorials/UpdateTutorial/index.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const styles = {
1616
};
1717

1818
class UpdateTutorial extends React.Component<{
19-
tutorial: Tutorial.Item, tutorialUpdate: any
19+
tutorial: Tutorial.Info, tutorialUpdate: any
2020
}, {}> {
2121
public render() {
2222
const {tutorial, tutorialUpdate} = this.props;
@@ -26,8 +26,7 @@ class UpdateTutorial extends React.Component<{
2626
style={styles.icon}
2727
color={pink500}
2828
onTouchTap={tutorialUpdate.bind(this, tutorial.name)}
29-
/>``
30-
<span style={styles.latest}>{tutorial.latest}</span>
29+
/>
3130
</span>
3231
);
3332
}
@@ -38,4 +37,4 @@ const mapStateToProps = (state, props) => ({
3837
});
3938
const mapDispatchToProps = {tutorialUpdate};
4039

41-
export default connect(mapStateToProps, mapDispatchToProps)(UpdateTutorial);
40+
export default connect(mapStateToProps, mapDispatchToProps)(UpdateTutorial);

src/components/Tutorials/index.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const styles = {
1515
};
1616

1717
class Tutorials extends React.Component<{
18-
tutorials: Tutorial.Item[], tutorialsFind: any
18+
tutorials: Tutorial.Info[], tutorialsFind: any
1919
}, {}> {
2020
constructor(props) {
2121
super(props);
@@ -38,7 +38,7 @@ class Tutorials extends React.Component<{
3838

3939
<TableBody displayRowCheckbox={false}>
4040
{tutorials.map(function tutorialRow(
41-
tutorial: Tutorial.Item, index: number
41+
tutorial: Tutorial.Info, index: number
4242
) {
4343
return (
4444
<TableRow key={index}>
@@ -48,7 +48,7 @@ class Tutorials extends React.Component<{
4848
<TableRowColumn>
4949
{tutorial.version}
5050

51-
{!!tutorial.latest
51+
{!tutorial.latest
5252
? <UpdateTutorial tutorial={tutorial} />
5353
: null
5454
}
@@ -77,4 +77,4 @@ const mapStateToProps = state => ({
7777

7878
const mapDispatchToProps = {tutorialsFind};
7979

80-
export default connect(mapStateToProps, mapDispatchToProps)(Tutorials);
80+
export default connect(mapStateToProps, mapDispatchToProps)(Tutorials);

src/modules/setup/utils/check-system.ts

+4-33
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import {isAboveVersion} from '../../../utils/compareVersions';
2+
import {isMac} from '../../../utils/system';
13
import commandLine from 'atom-plugin-command-line';
24

35
const versions = {
@@ -6,37 +8,6 @@ const versions = {
68
npm: '3.0.0'
79
};
810

9-
/**
10-
* extracts versions intro array from a string
11-
* "0.1.0" -> ['0', '1', '0']
12-
* or returns null
13-
* @param {string} v
14-
*/
15-
function matchVersions(v: string): string[]|null {
16-
return v.match(/([0-9]+)\.([0-9]+)/);
17-
}
18-
19-
/**
20-
* checks that a version is >= b version
21-
* @param {string} a
22-
* @param {string} b
23-
* @returns boolean
24-
*/
25-
function isAboveVersion(a: string, b: string): boolean {
26-
if (a === b) { return true; }
27-
const a_components = a.split('.');
28-
const b_components = b.split('.');
29-
const len = Math.min(a_components.length, b_components.length);
30-
for (let i = 0; i < len; i++) {
31-
const first = parseInt(a_components[i], 10);
32-
const second = parseInt(b_components[i], 10);
33-
if (first > second) { return true; }
34-
if (first < second) { return false; }
35-
}
36-
if (a_components.length > b_components.length) { return true; }
37-
if (a_components.length < b_components.length) { return false; }
38-
return true;
39-
}
4011

4112
/**
4213
* calls command line to check that system version is above requirement
@@ -80,8 +51,8 @@ export function atomMinVersion(): Promise<boolean> {
8051
* sets true if mac & !xcode, else false
8152
* @returns Promise
8253
*/
83-
export function requiresXCode(): Promise<boolean> | boolean {
84-
if (!navigator.platform.match(/Mac/)) {
54+
export function hasOrDoesNotRequireXCode(): Promise<boolean> | boolean {
55+
if (!isMac) {
8556
return true;
8657
}
8758
return commandLine('xcode-select', '-v').then((res: string) => {

0 commit comments

Comments
 (0)