Skip to content

Commit 8f1954c

Browse files
committed
save progress to localStorage
1 parent 0b1ffd7 commit 8f1954c

File tree

32 files changed

+186
-141
lines changed

32 files changed

+186
-141
lines changed

lib/actions/_types.js

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ exports.HINT_POSITION_SET = 'HINT_POSITION_SET';
88
exports.HINT_SHOW = 'HINT_SHOW';
99
exports.PACKAGE_SET = 'PACKAGE_SET';
1010
exports.PAGE_SET = 'PAGE_SET';
11+
exports.POSITION_LOAD = 'POSITION_LOAD';
1112
exports.POSITION_SET = 'POSITION_SET';
1213
exports.PROGRESS_LOAD = 'PROGRESS_LOAD';
1314
exports.ROUTE_SET = 'ROUTE_SET';

lib/actions/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var page_1 = require('./page');
1414
exports.pageSet = page_1.pageSet;
1515
exports.pageNext = page_1.pageNext;
1616
var position_1 = require('./position');
17+
exports.positionLoad = position_1.positionLoad;
1718
exports.positionSet = position_1.positionSet;
1819
var route_1 = require('./route');
1920
exports.routeSet = route_1.routeSet;

lib/actions/position.js

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
"use strict";
22
var _types_1 = require('./_types');
3+
function positionLoad() {
4+
return { type: _types_1.POSITION_LOAD };
5+
}
6+
exports.positionLoad = positionLoad;
37
function positionSet(position) {
48
return {
59
payload: { position: position },

lib/actions/progress.js

+11-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
"use strict";
22
var _types_1 = require('./_types');
3+
var position_1 = require('./position');
34
var store_1 = require('../store');
45
function progressLoad() {
6+
setTimeout(function () {
7+
store_1.default.dispatch(position_1.positionLoad());
8+
});
59
return { type: _types_1.PROGRESS_LOAD };
610
}
711
exports.progressLoad = progressLoad;
12+
function isTrue(x) {
13+
return x === true;
14+
}
815
function completePage() {
916
var position = store_1.default.getState().position;
10-
var pageLength = store_1.default.getState().progress.chapters[position.chapter].pages.length;
11-
if (position.page >= pageLength - 1) {
17+
var chapter = store_1.default.getState().progress.chapters[position.chapter];
18+
if (chapter.pages.every(function (x) { return x; })) {
1219
store_1.default.dispatch(completeChapter());
1320
}
1421
return {
@@ -19,8 +26,8 @@ function completePage() {
1926
exports.completePage = completePage;
2027
function completeChapter() {
2128
var chapter = store_1.default.getState().position.chapter;
22-
var chapterLength = store_1.default.getState().progress.chapters.length;
23-
if (chapter >= chapterLength - 1) {
29+
var progress = store_1.default.getState().progress;
30+
if (progress.chapters.every(function (x) { return x.completed; })) {
2431
store_1.default.dispatch(completeTutorial());
2532
}
2633
return {

lib/components/Page/Hints/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var help_1 = require('material-ui/svg-icons/action/help');
77
var styles = {
88
position: 'relative',
99
margin: '-5px 20px',
10+
right: '10px',
1011
width: '360px',
1112
textAlign: 'center',
1213
zIndex: '0',

lib/components/Page/PageToolbar/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ var styles = {
1111
right: '0px',
1212
height: '60px',
1313
width: '400px',
14+
margin: '0px',
1415
};
1516
exports.PageToolbar = function (_a) {
1617
var tasks = _a.tasks, taskPosition = _a.taskPosition, children = _a.children;

lib/components/Progress/ProgressChapter/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var descriptionStyles = {
1010
fontSize: '14px'
1111
};
1212
exports.ProgressChapter = function (_a) {
13-
var chapter = _a.chapter, chapterIndex = _a.chapterIndex, position = _a.position;
13+
var progress = _a.progress, chapter = _a.chapter, chapterIndex = _a.chapterIndex, position = _a.position;
1414
var isActive = chapterIndex === position.chapter;
15-
return (React.createElement(List_1.ListItem, {key: chapterIndex, className: isActive ? 'isActive' : null, style: styles, initiallyOpen: chapterIndex === 0, primaryTogglesNestedList: chapterIndex === position.chapter && !chapter.completed, nestedItems: chapter.pages.map(function (page, pageIndex) { return (React.createElement(ProgressPage_1.ProgressPage, {key: pageIndex, pageIndex: pageIndex, page: page, chapterIndex: chapterIndex, position: position})); })}, React.createElement("h3", null, chapterIndex + 1, ". ", chapter.title), React.createElement("span", {style: descriptionStyles}, React.createElement(index_1.Markdown, null, chapter.description))));
15+
return (React.createElement(List_1.ListItem, {key: chapterIndex, className: isActive ? 'isActive' : null, style: styles, initiallyOpen: chapterIndex === 0, primaryTogglesNestedList: chapterIndex === position.chapter && !progress.chapters[chapterIndex].completed, nestedItems: chapter.pages.map(function (page, pageIndex) { return (React.createElement(ProgressPage_1.ProgressPage, {key: pageIndex, pageIndex: pageIndex, page: page, chapterIndex: chapterIndex, position: position, progress: progress})); })}, React.createElement("h3", null, chapterIndex + 1, ". ", chapter.title), React.createElement("span", {style: descriptionStyles}, React.createElement(index_1.Markdown, null, chapter.description))));
1616
};

lib/components/Progress/ProgressPage/index.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,19 @@ var ProgressPage = (function (_super) {
2929
_super.apply(this, arguments);
3030
}
3131
ProgressPage.prototype.canActivate = function (isActive) {
32-
var _a = this.props, chapterIndex = _a.chapterIndex, pageIndex = _a.pageIndex, position = _a.position;
33-
var earlierChapter = chapterIndex < position.chapter;
32+
var _a = this.props, chapterIndex = _a.chapterIndex, pageIndex = _a.pageIndex, position = _a.position, progress = _a.progress;
33+
var completed = progress.chapters[chapterIndex].pages[pageIndex];
3434
var currentChapter = chapterIndex === position.chapter;
3535
var earlierOrCurrentPage = pageIndex <= position.page;
36-
return isActive || earlierChapter ||
36+
return isActive || completed ||
3737
(currentChapter && earlierOrCurrentPage);
3838
};
3939
ProgressPage.prototype.render = function () {
40-
var _a = this.props, page = _a.page, position = _a.position, chapterIndex = _a.chapterIndex, pageIndex = _a.pageIndex, selectPage = _a.selectPage;
40+
var _a = this.props, page = _a.page, position = _a.position, chapterIndex = _a.chapterIndex, pageIndex = _a.pageIndex, progress = _a.progress, selectPage = _a.selectPage;
4141
var isActive = chapterIndex === position.chapter && pageIndex === position.page;
4242
var canActivate = this.canActivate(isActive);
43-
return (React.createElement(List_1.ListItem, {key: pageIndex, style: Object.assign({}, styles, !canActivate ? { color: colors_1.grey400 } : {}), primaryText: (pageIndex + 1) + ". " + page.title, secondaryText: canActivate ? page.description : '', leftIcon: progressIcon_1.progressIcon(page.completed, isActive), onClick: canActivate
43+
var completed = progress.chapters[chapterIndex].pages[pageIndex];
44+
return (React.createElement(List_1.ListItem, {key: pageIndex, style: Object.assign({}, styles, !canActivate ? { color: colors_1.grey400 } : {}), primaryText: (pageIndex + 1) + ". " + page.title, secondaryText: canActivate ? page.description : '', leftIcon: progressIcon_1.progressIcon(completed, isActive), onClick: canActivate
4445
? selectPage.bind(this, {
4546
chapter: chapterIndex,
4647
page: pageIndex

lib/components/Progress/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ var pageStyle = {
99
margin: '0px',
1010
};
1111
exports.Progress = function (_a) {
12-
var progress = _a.progress, position = _a.position, info = _a.info;
13-
return (React.createElement(Paper_1.default, {style: pageStyle}, React.createElement(List_1.List, null, React.createElement(Subheader_1.default, null, info.title), progress.chapters.map(function (chapter, chapterIndex) { return (React.createElement(ProgressChapter_1.ProgressChapter, {key: chapterIndex, chapter: chapter, chapterIndex: chapterIndex, position: position})); }))));
12+
var progress = _a.progress, position = _a.position, info = _a.info, tutorial = _a.tutorial;
13+
return (React.createElement(Paper_1.default, {style: pageStyle}, React.createElement(List_1.List, null, React.createElement(Subheader_1.default, null, info.name), tutorial.chapters.map(function (chapter, chapterIndex) { return (React.createElement(ProgressChapter_1.ProgressChapter, {key: chapterIndex, chapter: chapter, chapterIndex: chapterIndex, position: position, progress: progress})); }))));
1414
};

lib/components/mount.js

-14
This file was deleted.

lib/reducers/position/index.js

+13
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
"use strict";
22
var _types_1 = require('../../actions/_types');
3+
var store_1 = require('../../store');
34
var _position = {
45
chapter: 0,
56
page: 0,
67
};
78
function positionReducer(position, action) {
89
if (position === void 0) { position = _position; }
910
switch (action.type) {
11+
case _types_1.POSITION_LOAD:
12+
var chapters = store_1.default.getState().progress.chapters;
13+
var chapter = chapters.indexOf(function (x) { return !x.completed; });
14+
if (chapter < 0) {
15+
chapter = chapters.length - 1;
16+
}
17+
var progressPage = chapters[chapter].pages;
18+
var page = progressPage.indexOf(function (x) { return !x; });
19+
if (page < 0) {
20+
page = progressPage.length - 1;
21+
}
22+
return { chapter: chapter, page: page };
1023
case _types_1.PAGE_SET:
1124
case _types_1.POSITION_SET:
1225
return action.payload.position;

lib/reducers/progress/index.js

+19-25
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,43 @@
11
"use strict";
22
var _types_1 = require('../../actions/_types');
3+
var local_storage_1 = require('./local-storage');
34
var store_1 = require('../../store');
45
var _progress = {
56
completed: false,
6-
chapters: [{
7-
title: '',
8-
description: '',
9-
completed: false,
10-
pages: [{
11-
title: '',
12-
description: '',
13-
completed: false,
14-
}]
15-
}]
7+
chapters: []
168
};
179
function progressReducer(progress, action) {
1810
if (progress === void 0) { progress = _progress; }
1911
switch (action.type) {
2012
case _types_1.PROGRESS_LOAD:
21-
var chapters = store_1.default.getState().tutorial.chapters;
13+
var tutorial = store_1.default.getState().tutorial;
14+
var saved = local_storage_1.loadProgressFromLocalStorage();
15+
if (saved) {
16+
return saved;
17+
}
2218
return {
2319
completed: false,
24-
chapters: !chapters ? [] : chapters.map(function (_a) {
25-
var title = _a.title, description = _a.description, completed = _a.completed, pages = _a.pages;
26-
return {
27-
title: title, description: description, completed: completed || false,
28-
pages: !pages ? [] : pages.map(function (page) {
29-
return {
30-
title: page.title,
31-
description: page.description,
32-
completed: page.completed || false,
33-
};
34-
})
35-
};
36-
})
20+
chapters: !tutorial.chapters
21+
? []
22+
: tutorial.chapters.map(function (chapter) {
23+
return {
24+
completed: false,
25+
pages: chapter.pages.map(function () { return false; })
26+
};
27+
})
3728
};
3829
case _types_1.COMPLETE_PAGE:
3930
var position = action.payload.position;
40-
progress.chapters[position.chapter].pages[position.page].completed = true;
31+
progress.chapters[position.chapter].pages[position.page] = true;
32+
local_storage_1.saveToLocalStorage(progress);
4133
return progress;
4234
case _types_1.COMPLETE_CHAPTER:
4335
progress.chapters[action.payload.chapter].completed = true;
36+
local_storage_1.saveToLocalStorage(progress);
4437
return progress;
4538
case _types_1.COMPLETE_TUTORIAL:
4639
progress.completed = true;
40+
local_storage_1.saveToLocalStorage(progress);
4741
return progress;
4842
default:
4943
return progress;
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"use strict";
2+
var store_1 = require('../../store');
3+
function getLocalStorageKey() {
4+
return 'coderoad:' + store_1.default.getState().tutorial.name;
5+
}
6+
function saveToLocalStorage(progress) {
7+
try {
8+
window.localStorage
9+
.setItem(getLocalStorageKey(), JSON.stringify(progress));
10+
}
11+
catch (e) {
12+
console.log('Error saving progress:', e);
13+
}
14+
}
15+
exports.saveToLocalStorage = saveToLocalStorage;
16+
function loadProgressFromLocalStorage() {
17+
var savedProgress = JSON.parse(window.localStorage.getItem(getLocalStorageKey()) || null);
18+
if (savedProgress) {
19+
return savedProgress;
20+
}
21+
return null;
22+
}
23+
exports.loadProgressFromLocalStorage = loadProgressFromLocalStorage;

lib/store/localStorage.js

-13
This file was deleted.

lib/store/middleware.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@
22
var env = 'dev';
33
var redux_1 = require('redux');
44
var redux_thunk_1 = require('redux-thunk');
5-
var localStorage_1 = require('./localStorage');
65
var middlewares = [redux_thunk_1.default];
76
if (env && env === 'dev') {
87
var createLogger = require('redux-logger');
98
var logger = createLogger();
109
middlewares.push(logger);
1110
}
12-
var createStoreWithMiddleware = redux_1.compose(redux_1.applyMiddleware.apply(void 0, middlewares), localStorage_1.default)(redux_1.createStore);
11+
var createStoreWithMiddleware = redux_1.compose(redux_1.applyMiddleware.apply(void 0, middlewares))(redux_1.createStore);
1312
Object.defineProperty(exports, "__esModule", { value: true });
1413
exports.default = createStoreWithMiddleware;

package.json

-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@
4747
"react-redux": "4.4.5",
4848
"react-tap-event-plugin": "1.0.0",
4949
"redux": "3.5.2",
50-
"redux-localstorage": "^1.0.0-rc4",
51-
"redux-localstorage-filter": "^0.1.1",
5250
"redux-logger": "2.6.1",
5351
"redux-thunk": "2.0.1"
5452
},

src/actions/_types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const HINT_POSITION_SET = 'HINT_POSITION_SET';
77
export const HINT_SHOW = 'HINT_SHOW';
88
export const PACKAGE_SET = 'PACKAGE_SET';
99
export const PAGE_SET = 'PAGE_SET';
10+
export const POSITION_LOAD = 'POSITION_LOAD';
1011
export const POSITION_SET = 'POSITION_SET';
1112
export const PROGRESS_LOAD = 'PROGRESS_LOAD';
1213
export const ROUTE_SET = 'ROUTE_SET';

src/actions/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export {
44
} from './progress';
55
export {hintShow, hintPositionSet} from './hint';
66
export {pageSet, pageNext} from './page';
7-
export {positionSet} from './position';
7+
export {positionLoad, positionSet} from './position';
88
export {routeSet} from './route';
99
export {setupVerify} from './setup';
1010
export {

src/actions/position.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import {POSITION_SET} from './_types';
1+
import {POSITION_SET, POSITION_LOAD} from './_types';
2+
3+
export function positionLoad() {
4+
return { type: POSITION_LOAD };
5+
}
26

37
export function positionSet(position: CR.Position): Action {
48
return {

src/actions/progress.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
import {
22
PROGRESS_LOAD, COMPLETE_PAGE, COMPLETE_CHAPTER, COMPLETE_TUTORIAL
33
} from './_types';
4+
import {positionLoad} from './position';
45
import store from '../store';
56

67
export function progressLoad(): Action {
8+
setTimeout(function() {
9+
store.dispatch(positionLoad());
10+
});
711
return { type: PROGRESS_LOAD };
812
}
913

14+
function isTrue(x) {
15+
return x === true;
16+
}
17+
1018
export function completePage(): Action {
1119
const position: CR.Position = store.getState().position;
12-
const pageLength: number = store.getState().progress.chapters[position.chapter].pages.length;
13-
if (position.page >= pageLength - 1) {
20+
const chapter = store.getState().progress.chapters[position.chapter];
21+
// all pages are true, chapter complete
22+
if (chapter.pages.every(x => x)) {
1423
store.dispatch(completeChapter());
1524
}
1625
return {
@@ -21,8 +30,9 @@ export function completePage(): Action {
2130

2231
export function completeChapter(): Action {
2332
const chapter: number = store.getState().position.chapter;
24-
const chapterLength: number = store.getState().progress.chapters.length;
25-
if (chapter >= chapterLength - 1) {
33+
const progress = store.getState().progress;
34+
// all chapters complete, tutorial complete
35+
if (progress.chapters.every(x => x.completed)) {
2636
store.dispatch(completeTutorial());
2737
}
2838
return {

src/components/Page/Hints/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Help from 'material-ui/svg-icons/action/help';
77
const styles = {
88
position: 'relative',
99
margin: '-5px 20px',
10+
right: '10px',
1011
width: '360px',
1112
textAlign: 'center',
1213
zIndex: '0',

src/components/Page/PageToolbar/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const styles = {
1111
right: '0px',
1212
height: '60px',
1313
width: '400px',
14+
margin: '0px',
1415
};
1516

1617
export const PageToolbar: React.StatelessComponent<{

0 commit comments

Comments
 (0)