Skip to content

Commit

Permalink
Merge pull request #60 from lgraziani2712/access-level-more-strict
Browse files Browse the repository at this point in the history
Make the access to exercises more strict
  • Loading branch information
lgraziani2712 authored Sep 4, 2017
2 parents 9491118 + 1bacf44 commit d41dba1
Show file tree
Hide file tree
Showing 22 changed files with 386 additions and 107 deletions.
3 changes: 3 additions & 0 deletions .storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ if (process.env.STORYBOOK_FOLDER === 'activities') {
if (process.env.STORYBOOK_FOLDER === 'core') {
req = require.context('../core', true, /\.stories\.jsx$/);
}
if (process.env.STORYBOOK_FOLDER === 'client') {
req = require.context('../client', true, /\.stories\.jsx$/);
}

function loadStories() {
req.keys().forEach(req);
Expand Down
5 changes: 3 additions & 2 deletions client/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
## HEAD

## v1.0.0-alpha.0
- ⚙️ [v1.1.0] `pages/MenuBar`: Make the menu more simple to reflect the new way to access to exercises (#59).
- ⚙️ [v1.1.0] `pages/links`: Add the exercise name to the link's title when playing (#56).

### 💅 Components
## v1.0.0-alpha.0

- 🆕 [v1.0.0] `FrontPage`.
- 🆕 [v1.0.0] `pages/MenuBar`.
Expand Down
47 changes: 18 additions & 29 deletions client/components/pages/MenuBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,44 +51,33 @@ const ExternalLinksContainer = styled.div`
type Props = {|
routes: Array<Codimo$Route>,
|};
/**
* Códimo client menu bar.
*
* @version 1.1.0
* @param {Array<Codimo$Route>} routes List of routes.
* @return {React$Element} Menu bar element.
*/
const MenuBar = ({ routes }: Props) => (
<Background>
<ContentContainer>
<CodimoLink />

<LinksContainer>
<LocalLinksContainer>
{routes.map((route, key) => {
const parentPath = `/${route.activityName}`;

if (!route.children) {
return (
<HeaderLink
key={parentPath}
to={parentPath}
title={route.title}
/>
);
}
{routes.map((route) => {
const path =
!route.children
? `/${route.activityName}`
// $FlowDoNotDisturb difficulty prop exist if the route has children
: `/${route.activityName}/${route.difficulty}/${route.children[0].path}`;

return (
// eslint-disable-next-line react/no-array-index-key
<HeaderLink key={key} title={route.title}>
{route.children.map((child) => {
if (!route.difficulty) {
throw new Error(
// eslint-disable-next-line max-len
`The activity ${route.activityName} requires to add the difficulty to the metadata definition.`,
);
}
const childrenPath =
`/${route.activityName}/${route.difficulty}/${child.path}`;

return (
<HeaderLink key={childrenPath} to={childrenPath} title={child.title} />
);
})}
</HeaderLink>
<HeaderLink
key={path}
to={path}
title={route.title}
/>
);
})}
</LocalLinksContainer>
Expand Down
44 changes: 30 additions & 14 deletions client/components/pages/links/HeaderLink.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,24 @@
// @see https://github.com/styled-components/stylelint-processor-styled-components/issues/54
// stylelint-disable
import React from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { Link as RouterLink, withRouter } from 'react-router-dom';
import styled from 'styled-components';

import { COLOR_PALETTE } from 'core/constants/colors';
import gameTextUI from 'core/constants/localize/es/gameTextUI';

const LinkContainer = styled.li`
list-style-type: none;
position: relative;
&::before {
background: ${({ isActive }) => (!isActive ? 'default' : COLOR_PALETTE.orange.clear)};
content: '';
height: 100%;
left: 50%;
left: ${({ isActive }) => (!isActive ? '50%' : '0')};
position: absolute;
transition: 0.5s;
width: 0;
width: ${({ isActive }) => (!isActive ? '0' : '100%')};
z-index: -1;
}
Expand Down Expand Up @@ -88,19 +90,33 @@ const ChildrenContainer = styled.ul`
}
`;

const isActive = (actualUrl: string, url: string) => (
actualUrl.split('/')[2] === url.split('/')[2]
);
const exerciseTitle = (actualUrl: string) => {
const level = parseInt(actualUrl.split('/').pop());

return `: ${gameTextUI.exercise} ${gameTextUI.levels(level)}`;
};

type Props = {|
location: Object,
title: string,
to: string,
children?: React.Element<HeaderLink>,
to?: string,
|};
const HeaderLink = ({ children, to, title }: Props) => (
<LinkContainer>
{!to
? <EmptyLink>{title}</EmptyLink>
: <Link to={to}>{title}</Link>
}
{!children || (<ChildrenContainer>{children}</ChildrenContainer>)}
</LinkContainer>
);
const HeaderLink = ({ children, location, to, title }: Props) => {
const active = isActive(location.pathname, to);

return (
<LinkContainer isActive={active}>
{active
? <EmptyLink>{title}{exerciseTitle(location.pathname)}</EmptyLink>
: <Link to={to}>{title}</Link>
}
{!children || (<ChildrenContainer>{children}</ChildrenContainer>)}
</LinkContainer>
);
};

export default HeaderLink;
export default withRouter(HeaderLink);
6 changes: 6 additions & 0 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## HEAD

### 💅 React UI

- ⚙️ [v1.0.2] `Activity`: Adds the `handleNextLevelRedirection` helper (#59).
- ⚙️ [v1.1.0] `CodimoRouter`: Adds a 404 page to announce the end game of an activity (#59).
- 🆕 [v1.0.0] `CodimoRouter/FourOhFour`: 404 page (#59).

## v1.0.0-alpha.1

### 🤖 PixiJS Engine
Expand Down
39 changes: 21 additions & 18 deletions core/constants/localize/es/gameTextUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,33 @@
*/
import CompleteURL from '../../images/complete.gif';

const difficulty = {
easy: 'NIVEL INICIAL',
normal: 'NIVEL INTERMEDIO',
hard: 'NIVEL AVANZADO',
};

export default {
accept: 'Aceptar',
accept: 'ACEPTAR',
loadingMessages: [
'Armando la línea numérica',
'Cazando números salvajes',
'Levantando los muros del laberinto',
'Pintando las paredes',
'Dibujando los bloques',
'ARMANDO LA LÍNEA NUMÉRICA',
'CAZANDO NÚMEROS SALVAJES',
'LEVANTANDO LOS MUROS DEL LABERINTO',
'PINTANDO LAS PAREDES',
'DIBUJANDO LOS BLOQUES',
],
successMessage: {
confirmButtonText: 'IR AL SIGUIENTE NIVEL',
imageUrl: CompleteURL,
title: '¡NIVEL COMPLETADO!',
confirmButtonText: 'IR AL SIGUIENTE NIVEL',
},
exercise: 'Ejercicio',
levels: [
'Primer',
'Segundo',
'Tercer',
'Cuarto',
],
difficulty: {
easy: 'Nivel inicial',
normal: 'Nivel intermedio',
hard: 'Nivel avanzado',
endGameMessage: {
title: '¡GENIAL!',
text: (actualDifficulty: string) => (
`¡TERMINASTE TODOS LOS EJERCICIOS DEL ${difficulty[actualDifficulty]}!`
),
},
exercise: 'EJERCICIO',
levels: (level: string | number) => `Nº ${level}`,
difficulty,
};
1 change: 1 addition & 0 deletions core/constants/numbers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
export const ZERO = 0;
export const ONE = 1;
export const TWO = 2;
export const THREE = 3;
export const FOUR = 4;
export const TEN = 10;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import componentGenerator from '../componentGenerator';
import positioningFunctionalityBuilder from './positioningFunctionalityBuilder';
import theFallenOneFunctionalityBuilder from './theFallenOneFunctionalityBuilder';

describe('engines/pixijs/components/functionalities/theFallenOneFunctionalityBuilder', async () => {
describe('engines/pixijs/components/functionalities/theFallenOneFunctionalityBuilder', () => {
it('should disappear on `beTheFallenOne`', async () => {
const initPosition = '1,1';
const size = 64;
Expand Down
41 changes: 41 additions & 0 deletions core/ui/Activity/helpers/handleNextLevelRedirection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @author Luciano Graziani @lgraziani2712
* @license {@link http://www.opensource.org/licenses/mit-license.php|MIT License}
*
* @flow
*/
import swal from 'sweetalert2';

import { ONE, THREE } from 'core/constants/numbers';
import gameTextUI from 'core/constants/localize/es/gameTextUI';

/**
* This is in charge of redirect to the next
* exercise in case it exists one.
* If not, it announce the level completeness.
*
* @version 1.0.0
* @param {string} activityName The activity name.
* @param {string} difficulty The difficulty.
* @param {Object} location The react-router location object.
* @param {Object} history The react-router history object.
* @return {Promise<void>} The sweetalert promise.
*/
const handleNextLevelRedirection = (
activityName: string,
difficulty: string,
location: Object,
history: Object,
) => (): Promise<void> => {
const level = parseInt(location.pathname.split('/').pop());
const stringLvl = (level + ONE).toString().padStart(THREE, '0');
const path = `/${activityName}/${difficulty}/${stringLvl}`;

return swal(gameTextUI.successMessage).then(() => {
history.push(path);
}, () => {
history.push(path);
});
};

export default handleNextLevelRedirection;
22 changes: 18 additions & 4 deletions core/ui/Activity/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
*/
import React from 'react';
import swal from 'sweetalert2';
import { withRouter } from 'react-router-dom';

import {
type ClientError,
} from 'core/engines/pixijs/engineGenerator/processors/checkers/engineErrorBuilder';
import { type Instructions } from 'core/workspaces/blockly/parseInstructions';
import { type GameDifficulty } from 'core/workspaces/blockly/instanciateEveryBlock';
import { type EngineData, type Engine } from 'core/engines/pixijs/engineGenerator';
import gameTextUI from 'core/constants/localize/es/gameTextUI';
import { ZERO } from 'core/constants/numbers';
import { getRandomInt } from 'core/helpers/randomizers';

Expand All @@ -22,6 +22,7 @@ import PixiApp from '../PixiApp';

import BackgroundImage from './components/BackgroundImage';
import TwoColumns from './components/TwoColumns';
import handleNextLevelRedirection from './helpers/handleNextLevelRedirection';

export type Metadata = {|
activityName: string,
Expand All @@ -34,25 +35,36 @@ type Activity$Props = {|
engine: Engine,
metadata: Metadata,
hasNotEnd?: boolean,
// react-router props
history: Object,
location: Object,
match: Object,
|};

/**
* The Container is in charge of loading the required activity.
*
* @version 1.0.1
* @version 1.0.2
* @todo 1. Subcomponents async loading.
* @todo 2. Make it more generic.
* @todo 3. Add example.
*/
export default class Activity extends React.Component {
class Activity extends React.Component {
props: Activity$Props;

image: string;
handleNextLevelRedirection: () => Promise<void>;

constructor(props: Activity$Props) {
super(props);

this.image = props.backgroundImages[getRandomInt(ZERO, props.backgroundImages.length)];
this.handleNextLevelRedirection = handleNextLevelRedirection(
this.props.metadata.activityName,
this.props.metadata.difficulty,
this.props.location,
this.props.history,
);
}
/**
* This callback will be used by the BlocklyApp.
Expand All @@ -75,7 +87,7 @@ export default class Activity extends React.Component {
}

return executionPromise
.then(() => (swal(gameTextUI.successMessage).catch(swal.noop)))
.then(this.handleNextLevelRedirection)
.catch((error: ClientError) => {
if (error.title === undefined) {
throw error;
Expand Down Expand Up @@ -108,3 +120,5 @@ export default class Activity extends React.Component {
);
}
}

export default withRouter(Activity);
6 changes: 5 additions & 1 deletion core/ui/BlocklyApp/components/BlocklyWorkspace.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ import BlocklyToolbox, { type BlocklyToolboxElement } from './BlocklyToolbox';

const Workspace = styled.div`
height: 520px;
width: 580px;
width: 500px;
& .blocklyTrash {
opacity: 1 !important;
}
& .blocklyZoom > image {
opacity: 1;
}
& .blocklyDraggable {
cursor: url(${GrabURL}) 15 5, auto;
Expand Down
5 changes: 4 additions & 1 deletion core/ui/BlocklyApp/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ export default class BlocklyApp extends React.Component {
toolbox,
trashcan: true,
zoom: {
startScale: 1.25,
controls: true,
maxScale: 1.5,
startScale: 1,
scaleSpeed: 1.05,
},
});
this.highlightBlock = (id: string) => {
Expand Down
Loading

0 comments on commit d41dba1

Please sign in to comment.