Skip to content

Commit

Permalink
Add shortcuts to go back and forth (prev & next) (#176)
Browse files Browse the repository at this point in the history
Add shortcuts to jump to previous and next stories
  • Loading branch information
arunoda committed May 9, 2016
1 parent 651b22b commit ec590c3
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 21 deletions.
10 changes: 9 additions & 1 deletion dist/client/libs/key_events.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ var features = exports.features = {
DOWN_PANEL: 2,
LEFT_PANEL: 3,
SHORTCUTS_HELP: 4,
ESCAPE: 5
ESCAPE: 5,
NEXT_STORY: 6,
PREV_STORY: 7
};

function isModifierPressed(e) {
Expand All @@ -44,6 +46,12 @@ function handle(e) {
case (0, _keycode2.default)('L'):
e.preventDefault();
return features.LEFT_PANEL;
case (0, _keycode2.default)('right'):
e.preventDefault();
return features.NEXT_STORY;
case (0, _keycode2.default)('left'):
e.preventDefault();
return features.PREV_STORY;
default:
return false;
}
Expand Down
22 changes: 11 additions & 11 deletions dist/manager.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/manager.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/client/libs/key_events.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export const features = {
LEFT_PANEL: 3,
SHORTCUTS_HELP: 4,
ESCAPE: 5,
NEXT_STORY: 6,
PREV_STORY: 7,
};

export function isModifierPressed(e) {
Expand All @@ -31,6 +33,12 @@ export default function handle(e) {
case keycode('L'):
e.preventDefault();
return features.LEFT_PANEL;
case keycode('right'):
e.preventDefault();
return features.NEXT_STORY;
case keycode('left'):
e.preventDefault();
return features.PREV_STORY;
default:
return false;
}
Expand Down
48 changes: 48 additions & 0 deletions src/client/manager/modules/api/actions/__tests__/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ import { types } from '../';
const { describe, it } = global;

describe('manager.api.actions.api', () => {
describe('setStories', () => {
it('should dispatch related redux action', () => {
const reduxStore = {
dispatch: sinon.stub(),
};
const stories = [{ kind: 'aa', stories: [] }];

actions.setStories({ reduxStore }, stories);
const action = reduxStore.dispatch.args[0][0];
expect(action).to.deep.equal({
type: types.SET_STORIES,
stories,
});
});
});

describe('selectStory', () => {
it('should dispatch related redux action', () => {
const reduxStore = {
Expand All @@ -23,6 +39,22 @@ describe('manager.api.actions.api', () => {
});
});

describe('jumpToStory', () => {
it('should dispatch related redux action', () => {
const reduxStore = {
dispatch: sinon.stub(),
};
const direction = -1;

actions.jumpToStory({ reduxStore }, direction);
const action = reduxStore.dispatch.args[0][0];
expect(action).to.deep.equal({
type: types.JUMP_TO_STORY,
direction,
});
});
});

describe('clearActions', () => {
it('should dispatch related redux action', () => {
const reduxStore = {
Expand All @@ -36,4 +68,20 @@ describe('manager.api.actions.api', () => {
});
});
});

describe('addAction', () => {
it('should dispatch related redux action', () => {
const reduxStore = {
dispatch: sinon.stub(),
};
const action = {};

actions.addAction({ reduxStore }, action);
const a = reduxStore.dispatch.args[0][0];
expect(a).to.deep.equal({
type: types.ADD_ACTION,
action,
});
});
});
});
7 changes: 7 additions & 0 deletions src/client/manager/modules/api/actions/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export default {
});
},

jumpToStory({ reduxStore }, direction) {
reduxStore.dispatch({
type: types.JUMP_TO_STORY,
direction,
});
},

clearActions({ reduxStore }) {
reduxStore.dispatch({
type: types.CLEAR_ACTIONS,
Expand Down
3 changes: 2 additions & 1 deletion src/client/manager/modules/api/actions/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// define redux actions
export const types = {
SET_STORIES: 'API_SET_STORIES',
SELECT_STORY: 'API_SELECT_STORY',
JUMP_TO_STORY: 'API_JUMP_TO_STORY',
CLEAR_ACTIONS: 'API_CLEAR_ACTIONS',
SET_STORIES: 'API_SET_STORIES',
ADD_ACTION: 'API_ADD_ACTION',
};

Expand Down
65 changes: 65 additions & 0 deletions src/client/manager/modules/api/configs/reducers/__tests__/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,69 @@ describe('manager.preview.config.reducers.preview', () => {
]);
});
});

describe('JUMP_TO_STORY', () => {
it('should jump to the next story', () => {
const selectedKind = 'kk';
const selectedStory = 'ss';
const stories = [
{ kind: 'kk', stories: ['ss'] },
{ kind: 'bb', stories: ['aa', 'cc'] },
];

const action = {
type: types.JUMP_TO_STORY,
direction: 1,
};

const newState = reducer({
stories, selectedKind, selectedStory,
}, action);

expect(newState.selectedKind).to.be.equal('bb');
expect(newState.selectedStory).to.be.equal('aa');
});

it('should jump to the prev story', () => {
const selectedKind = 'bb';
const selectedStory = 'cc';
const stories = [
{ kind: 'kk', stories: ['ss'] },
{ kind: 'bb', stories: ['aa', 'cc'] },
];

const action = {
type: types.JUMP_TO_STORY,
direction: -1,
};

const newState = reducer({
stories, selectedKind, selectedStory,
}, action);

expect(newState.selectedKind).to.be.equal('bb');
expect(newState.selectedStory).to.be.equal('aa');
});

it('should jump nowhere it there is no story', () => {
const selectedKind = 'kk';
const selectedStory = 'ss';
const stories = [
{ kind: 'kk', stories: ['ss'] },
{ kind: 'bb', stories: ['aa', 'cc'] },
];

const action = {
type: types.JUMP_TO_STORY,
direction: -10,
};

const newState = reducer({
stories, selectedKind, selectedStory,
}, action);

expect(newState.selectedKind).to.be.equal('kk');
expect(newState.selectedStory).to.be.equal('ss');
});
});
});
36 changes: 34 additions & 2 deletions src/client/manager/modules/api/configs/reducers/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,37 @@ export function ensureStory(storyKinds, selectedKind, selectedStory) {
return kindInfo.stories[0];
}

export function jumpToStory(storyKinds, selectedKind, selectedStory, direction) {
const flatteredStories = [];
let currentIndex = -1;

storyKinds.forEach(({ kind, stories }) => {
stories.forEach((story) => {
flatteredStories.push({ kind, story });
if (kind === selectedKind && story === selectedStory) {
currentIndex = flatteredStories.length - 1;
}
});
});

const jumpedStory = flatteredStories[currentIndex + direction];
if (!jumpedStory) {
return { selectedKind, selectedStory };
}

return {
selectedKind: jumpedStory.kind,
selectedStory: jumpedStory.story,
};
}

const defaultState = {
actions: [],
};

export default function (state = defaultState, action) {
switch (action.type) {
case types.SELECT_STORY: {
// TODO: if action.story is null, we need to select the first story of the
// given kind.
const selectedKind = ensureKind(state.stories, action.kind);
const selectedStory = ensureStory(state.stories, selectedKind, action.story);
return {
Expand All @@ -41,6 +63,16 @@ export default function (state = defaultState, action) {
};
}

case types.JUMP_TO_STORY: {
const { selectedKind, selectedStory } =
jumpToStory(state.stories, state.selectedKind, state.selectedStory, action.direction);
return {
...state,
selectedKind,
selectedStory,
};
}

case types.CLEAR_ACTIONS: {
return {
...state,
Expand Down
22 changes: 17 additions & 5 deletions src/client/manager/modules/shortcuts/actions/shortcuts.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import { types } from './';
import { features } from '../../../../libs/key_events';
import apiActions from '../../api/actions';

export default {
handleEvent({ reduxStore }, event) {
reduxStore.dispatch({
type: types.HANDLE_EVENT,
event,
});
handleEvent(context, event) {
const { reduxStore } = context;
switch (event) {
case features.NEXT_STORY:
apiActions.api.jumpToStory(context, 1);
break;
case features.PREV_STORY:
apiActions.api.jumpToStory(context, -1);
break;
default:
reduxStore.dispatch({
type: types.HANDLE_EVENT,
event,
});
}
},
};
10 changes: 10 additions & 0 deletions src/client/manager/modules/ui/components/shortcuts_help.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ export const Content = () => (
<b style={commandStyle}>&#8963; &#8679; D</b>
Toggle Down Panel
</div>
<div>
<b style={commandStyle}>&#8984; &#8679; → </b> / &nbsp;
<b style={commandStyle}>&#8963; &#8679; → </b>
Next Story
</div>
<div>
<b style={commandStyle}>&#8984; &#8679; ← </b> / &nbsp;
<b style={commandStyle}>&#8963; &#8679; ← </b>
Previous Story
</div>
</div>
);

Expand Down

0 comments on commit ec590c3

Please sign in to comment.