Skip to content

Commit 128e5c1

Browse files
wltanAsthenosphereathuyaoojetkan-yk
authored
CP3108: Game Component (#1058)
* Refactor constants (#2) - Move ASSETS_HOST to within constants.js - Add a backend directory to facilitate future communication with the backend - Add ability to toggle asset hosts * Setup game state fetcher Includes implementation to manage active stories * Refactor save and load data * Create game testing page * Create telescope/night filter * Add test for Game Dev link * Add override functions * Retrieve data from backend * Add more tests for game-dev page and material page * Deleted unnecessary page * To use test bucket * Changed test page to automatically find folder * Prettified and Updated Snapshots * Change the story retrieval workflow Dev users will first attempt to pull from the test bucket. If it fails, then try the live bucket. Student users will always pull from the live bucket. * Fixed location of stories * Json Upload * Modify test for StoryTable * Read input JSON file and set override * Enable the JSON file to simulate customized mission pointer and current date as well * Fixed bug where tests on PixiJS will fail due to canvas error Tried pixijs/pixijs#4769 after encountering TypeError: Cannot set property 'fillStyle' of null It solved the problem with the game-dev component. * Fully moved completed-quests and collectibles away from localStorage. Saving and loading of quest and collectibles will come through the user data or from overriding data. * Save Manager now saves story action sequence and start location to localStorage * Added new actions and changed state for the addition of game state. - Made new actiontypes to update game state in the backend and in session. - Updated tests to accomodate for game state. * Updated game and gamedev components to accomodate the addition of game state and changes in save manager. * Deleted non-essential mission pointer override * Fixed Typo 'hasColletible'. * Merged GroundControl with gameStateUpdate * Using SessionStorage for Game State instead of JS * Minor Cosmetic Changes * GamePage to load only when all information is gotten * Fixed some errors and allow for reset json files * Updated Game Components to use GroundControl Use Ground Control's assessment overview instead of master.xml file. Less things to keep track of this way. * Updated Material Table Snapshots * Minor bugfixes and documentation - Fixed bug with regards to missing stories, testers now use default story if they have not overriden the game. - Potential bug fixed With no missions available, will return leaving a black screen, instead of crashing. - Fixed bug that stops the game from compiling when the last mission has closed, will now only show last opened mission. - Added minor documentation * Point hosts back to default * Removed console.log function * Fix bugs in backend.ts * Prettify code * Fix bugs in backend.ts Co-authored-by: Asthenosphere <e0271247@u.nus.edu> Co-authored-by: wltan <wltan@users.noreply.github.com> Co-authored-by: travisryte <thuyaoo200@gmail.com> Co-authored-by: jetkan-yk <jetkan.yk@gmail.com>
1 parent c1b1457 commit 128e5c1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+2821
-177
lines changed

.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
REACT_APP_LUMINUS_CLIENT_ID=your_luminus_client_id_here
1+
REACT_APP_LUMINUS_CLIENT_ID=nus_apps
22
REACT_APP_VERSION=$npm_package_version
33
REACT_APP_BACKEND_URL=http://localhost:4001
44
REACT_APP_USE_BACKEND=TRUE
55
REACT_APP_CHATKIT_INSTANCE_LOCATOR=instance_locator_here_otherwise_empty_string
66

7-
MODULE_BACKEND_URL=http://ec2-54-169-81-133.ap-southeast-1.compute.amazonaws.com
7+
MODULE_BACKEND_URL=http://ec2-54-169-81-133.ap-southeast-1.compute.amazonaws.com

package-lock.json

Lines changed: 512 additions & 42 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
}
3636
},
3737
"dependencies": {
38+
"@blueprintjs/datetime": "^3.15.2",
3839
"@pusher/chatkit-client": "^1.5.0",
3940
"ace-builds": "^1.4.8",
4041
"acorn": "^5.7.4",
@@ -122,6 +123,7 @@
122123
"enzyme": "^3.11.0",
123124
"enzyme-adapter-react-16": "^1.14.0",
124125
"husky": "^1.3.1",
126+
"jest-canvas-mock": "^2.2.0",
125127
"local-cors-proxy": "^1.0.2",
126128
"prettier": "^1.18.2",
127129
"react-scripts-ts": "^2.16.0",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import * as actionTypes from '../actionTypes';
2+
import {
3+
changeDateAssessment,
4+
deleteAssessment,
5+
publishAssessment,
6+
uploadAssessment
7+
} from '../groundControl';
8+
9+
test('changeDateAssessment generates correct action object', () => {
10+
const id = 10;
11+
const openAt = '2020-01-01T00:00:00.000Z';
12+
const closeAt = '2021-01-01T00:00:00.000Z';
13+
const action = changeDateAssessment(id, openAt, closeAt);
14+
expect(action).toEqual({
15+
type: actionTypes.CHANGE_DATE_ASSESSMENT,
16+
payload: {
17+
id,
18+
openAt,
19+
closeAt
20+
}
21+
});
22+
});
23+
24+
test('deleteAssessment generates correct action object', () => {
25+
const id = 12;
26+
const action = deleteAssessment(id);
27+
expect(action).toEqual({
28+
type: actionTypes.DELETE_ASSESSMENT,
29+
payload: id
30+
});
31+
});
32+
33+
test('publishAssessment generates correct action object', () => {
34+
const id = 54;
35+
const togglePublishTo = false;
36+
const action = publishAssessment(togglePublishTo, id);
37+
expect(action).toEqual({
38+
type: actionTypes.PUBLISH_ASSESSMENT,
39+
payload: {
40+
togglePublishTo,
41+
id
42+
}
43+
});
44+
});
45+
46+
test(' generates correct action object', () => {
47+
const file = new File([''], 'testFile');
48+
const forceUpdate = true;
49+
const action = uploadAssessment(file, forceUpdate);
50+
expect(action).toEqual({
51+
type: actionTypes.UPLOAD_ASSESSMENT,
52+
payload: {
53+
file,
54+
forceUpdate
55+
}
56+
});
57+
});

src/actions/__tests__/session.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Grading, GradingOverview } from '../../components/academy/grading/gradingShape';
22
import { IAssessment, IAssessmentOverview } from '../../components/assessment/assessmentShape';
33
import { Notification } from '../../components/notification/notificationShape';
4-
import { Role, Story } from '../../reducers/states';
4+
import { GameState, Role, Story } from '../../reducers/states';
55
import * as actionTypes from '../actionTypes';
66
import {
77
acknowledgeNotifications,
@@ -156,7 +156,8 @@ test('setUser generates correct action object', () => {
156156
role: 'student' as Role,
157157
group: '42D',
158158
grade: 150,
159-
story: {} as Story
159+
story: {} as Story,
160+
gameState: {} as GameState
160161
};
161162
const action = setUser(user);
162163
expect(action).toEqual({

src/actions/actionTypes.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,17 @@ export const ACKNOWLEDGE_NOTIFICATIONS = 'ACKNOWLEDGE_NOTIFICATIONS';
125125
export const UPDATE_NOTIFICATIONS = 'UPDATE_NOTIFICATIONS';
126126
export const NOTIFY_CHATKIT_USERS = 'NOTIFY_CHATKIT_USERS';
127127

128-
/** Dashboard */
128+
/** GAMEDEV */
129+
export const FETCH_TEST_STORIES = 'FETCH_TEST_STORIES';
130+
export const SAVE_USER_STATE = 'SAVE_USER_STATE';
131+
export const SET_GAME_STATE = 'SET_GAME_STATE';
132+
133+
/** GroundControl */
134+
export const CHANGE_DATE_ASSESSMENT = 'CHANGE_DATE_ASSESSMENT';
135+
export const DELETE_ASSESSMENT = 'DELETE_ASSESSMENT';
136+
export const PUBLISH_ASSESSMENT = 'PUBLISH_ASSESSMENT';
137+
export const UPLOAD_ASSESSMENT = 'UPLOAD_ASSESSMENT';
129138

139+
/** Dashboard */
130140
export const FETCH_GROUP_OVERVIEWS = 'FETCH_GROUP_OVERVIEWS';
131141
export const UPDATE_GROUP_OVERVIEWS = 'UPDATE_GROUP_OVERVIEWS';

src/actions/game.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import { GameState } from 'src/reducers/states';
12
import { action } from 'typesafe-actions';
2-
33
import * as actionTypes from './actionTypes';
44

5+
export const fetchTestStories = () => action(actionTypes.FETCH_TEST_STORIES);
56
export const saveCanvas = (canvas: HTMLCanvasElement) => action(actionTypes.SAVE_CANVAS, canvas);
7+
export const saveUserData = (gameState: GameState) =>
8+
action(actionTypes.SAVE_USER_STATE, gameState);

src/actions/groundControl.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { action } from 'typesafe-actions';
2+
3+
import * as actionTypes from './actionTypes';
4+
5+
export const changeDateAssessment = (id: number, openAt: string, closeAt: string) =>
6+
action(actionTypes.CHANGE_DATE_ASSESSMENT, { id, openAt, closeAt });
7+
8+
export const deleteAssessment = (id: number) => action(actionTypes.DELETE_ASSESSMENT, id);
9+
10+
export const publishAssessment = (togglePublishTo: boolean, id: number) =>
11+
action(actionTypes.PUBLISH_ASSESSMENT, { id, togglePublishTo });
12+
13+
export const uploadAssessment = (file: File, forceUpdate: boolean) =>
14+
action(actionTypes.UPLOAD_ASSESSMENT, { file, forceUpdate });

src/actions/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './collabEditing';
22
export * from './commons';
33
export * from './dashboard';
44
export * from './game';
5+
export * from './groundControl';
56
export * from './interpreter';
67
export * from './material';
78
export * from './playground';

src/actions/session.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
Notification,
77
NotificationFilterFunction
88
} from '../components/notification/notificationShape';
9-
import { Story } from '../reducers/states';
9+
import { GameState, Story } from '../reducers/states';
1010
import * as actionTypes from './actionTypes';
1111

1212
import { Role } from '../reducers/states';
@@ -31,6 +31,8 @@ export const fetchGradingOverviews = (filterToGroup = true) =>
3131

3232
export const login = () => action(actionTypes.LOGIN);
3333

34+
export const setGameState = (gameState: GameState) => action(actionTypes.SET_GAME_STATE, gameState);
35+
3436
export const setTokens = ({
3537
accessToken,
3638
refreshToken
@@ -48,7 +50,8 @@ export const setUser = (user: {
4850
role: Role;
4951
group: string | null;
5052
grade: number;
51-
story: Story;
53+
story?: Story;
54+
gameState?: GameState;
5255
}) => action(actionTypes.SET_USER, user);
5356

5457
export const submitAnswer = (id: number, answer: string | number) =>

src/components/Playground.tsx

100755100644
File mode changed.

src/components/academy/NavigationBar.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ const NavigationBar: React.SFC<OwnProps> = props => (
8585
<NavbarGroup align={Alignment.RIGHT}>
8686
<DefaultChapter />
8787

88+
<NavLink
89+
to={'/academy/groundcontrol'}
90+
activeClassName={Classes.ACTIVE}
91+
className={classNames('NavigationBar__link', Classes.BUTTON, Classes.MINIMAL)}
92+
>
93+
<Icon icon="satellite" />
94+
<div className="navbar-button-text hidden-xs">Ground Control</div>
95+
</NavLink>
96+
8897
<NavLink
8998
to={'/academy/dashboard'}
9099
activeClassName={Classes.ACTIVE}
@@ -124,6 +133,15 @@ const NavigationBar: React.SFC<OwnProps> = props => (
124133
disableHover={true}
125134
/>
126135
</NavLink>
136+
137+
<NavLink
138+
to={'/academy/gamedev'}
139+
activeClassName={Classes.ACTIVE}
140+
className={classNames('NavigationBar__link', Classes.BUTTON, Classes.MINIMAL)}
141+
>
142+
<Icon icon={IconNames.CROWN} />
143+
<div className="navbar-button-text hidden-xs">Game Dev</div>
144+
</NavLink>
127145
</NavbarGroup>
128146
) : null}
129147
</Navbar>

src/components/academy/__tests__/__snapshots__/NavigationBar.tsx.snap

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ exports[`Grading NavLink renders for Role.Admin 1`] = `
8181
</Blueprint3.NavbarGroup>
8282
<Blueprint3.NavbarGroup align=\\"right\\">
8383
<withRouter(Connect(DefaultChapter)) />
84+
<NavLink to=\\"/academy/groundcontrol\\" activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" aria-current=\\"page\\">
85+
<Blueprint3.Icon icon=\\"satellite\\" />
86+
<div className=\\"navbar-button-text hidden-xs\\">
87+
Ground Control
88+
</div>
89+
</NavLink>
8490
<NavLink to=\\"/academy/dashboard\\" activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" aria-current=\\"page\\">
8591
<Blueprint3.Icon icon=\\"globe\\" />
8692
<div className=\\"navbar-button-text hidden-xs\\">
@@ -106,6 +112,12 @@ exports[`Grading NavLink renders for Role.Admin 1`] = `
106112
</div>
107113
<Connect(NotificationBadge) notificationFilter={[Function]} disableHover={true} />
108114
</NavLink>
115+
<NavLink to=\\"/academy/gamedev\\" activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" aria-current=\\"page\\">
116+
<Blueprint3.Icon icon=\\"crown\\" />
117+
<div className=\\"navbar-button-text hidden-xs\\">
118+
Game Dev
119+
</div>
120+
</NavLink>
109121
</Blueprint3.NavbarGroup>
110122
</Blueprint3.Navbar>"
111123
`;
@@ -150,6 +162,12 @@ exports[`Grading NavLink renders for Role.Staff 1`] = `
150162
</Blueprint3.NavbarGroup>
151163
<Blueprint3.NavbarGroup align=\\"right\\">
152164
<withRouter(Connect(DefaultChapter)) />
165+
<NavLink to=\\"/academy/groundcontrol\\" activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" aria-current=\\"page\\">
166+
<Blueprint3.Icon icon=\\"satellite\\" />
167+
<div className=\\"navbar-button-text hidden-xs\\">
168+
Ground Control
169+
</div>
170+
</NavLink>
153171
<NavLink to=\\"/academy/dashboard\\" activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" aria-current=\\"page\\">
154172
<Blueprint3.Icon icon=\\"globe\\" />
155173
<div className=\\"navbar-button-text hidden-xs\\">
@@ -175,6 +193,12 @@ exports[`Grading NavLink renders for Role.Staff 1`] = `
175193
</div>
176194
<Connect(NotificationBadge) notificationFilter={[Function]} disableHover={true} />
177195
</NavLink>
196+
<NavLink to=\\"/academy/gamedev\\" activeClassName=\\"bp3-active\\" className=\\"NavigationBar__link bp3-button bp3-minimal\\" aria-current=\\"page\\">
197+
<Blueprint3.Icon icon=\\"crown\\" />
198+
<div className=\\"navbar-button-text hidden-xs\\">
199+
Game Dev
200+
</div>
201+
</NavLink>
178202
</Blueprint3.NavbarGroup>
179203
</Blueprint3.Navbar>"
180204
`;

0 commit comments

Comments
 (0)