Skip to content

Commit 9b8234d

Browse files
committed
Help button that shows modal to explain feature
1 parent 91379e0 commit 9b8234d

File tree

10 files changed

+200
-15
lines changed

10 files changed

+200
-15
lines changed

client/constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,6 @@ export const HIDE_ERROR_MODAL = 'HIDE_ERROR_MODAL';
114114

115115
export const PERSIST_STATE = 'PERSIST_STATE';
116116
export const CLEAR_PERSISTED_STATE = 'CLEAR_PERSISTED_STATE';
117+
118+
export const SHOW_HELP_MODAL = 'SHOW_HELP_MODAL';
119+
export const HIDE_HELP_MODAL = 'HIDE_HELP_MODAL';

client/images/help.svg

Lines changed: 7 additions & 0 deletions
Loading

client/modules/IDE/actions/ide.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,16 @@ export function hideErrorModal() {
220220
type: ActionTypes.HIDE_ERROR_MODAL
221221
};
222222
}
223+
224+
export function showHelpModal(helpType) {
225+
return {
226+
type: ActionTypes.SHOW_HELP_MODAL,
227+
helpType
228+
};
229+
}
230+
231+
export function hideHelpModal() {
232+
return {
233+
type: ActionTypes.HIDE_HELP_MODAL
234+
};
235+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React, { PropTypes } from 'react';
2+
import InlineSVG from 'react-inlinesvg';
3+
4+
const exitUrl = require('../../../images/exit.svg');
5+
6+
const helpContent = {
7+
serveSecure: {
8+
title: 'Serve over HTTPS',
9+
body: (
10+
<div>
11+
<p>Use the checkbox to choose whether this sketch should be loaded using HTTPS or HTTP.</p>
12+
<p>You should choose HTTPS if you need to:</p>
13+
<ul>
14+
<li>access a webcam or microphone</li>
15+
<li>access an API served over HTTPS</li>
16+
</ul>
17+
<p>Choose HTTP if you need to:</p>
18+
<ul>
19+
<li>access an API served over HTTP</li>
20+
</ul>
21+
</div>
22+
)
23+
}
24+
};
25+
26+
const fallbackContent = {
27+
title: 'No content for this topic',
28+
body: null,
29+
};
30+
31+
class HelpModal extends React.Component {
32+
componentDidMount() {
33+
this.shareModal.focus();
34+
}
35+
render() {
36+
const content = helpContent[this.props.type] == null ?
37+
fallbackContent :
38+
helpContent[this.props.type];
39+
40+
return (
41+
<section className="help-modal" ref={(element) => { this.shareModal = element; }} tabIndex="0">
42+
<header className="help-modal__header">
43+
<h2>{content.title}</h2>
44+
<button className="about__exit-button" onClick={this.props.closeModal}>
45+
<InlineSVG src={exitUrl} alt="Close Help Overlay" />
46+
</button>
47+
</header>
48+
<div className="help-modal__section">
49+
{content.body}
50+
</div>
51+
</section>
52+
);
53+
}
54+
}
55+
56+
HelpModal.propTypes = {
57+
type: PropTypes.string.isRequired,
58+
closeModal: PropTypes.func.isRequired,
59+
};
60+
61+
export default HelpModal;

client/modules/IDE/components/Toolbar.jsx

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const logoUrl = require('../../../images/p5js-logo.svg');
88
const stopUrl = require('../../../images/stop.svg');
99
const preferencesUrl = require('../../../images/preferences.svg');
1010
const editProjectNameUrl = require('../../../images/pencil.svg');
11+
const helpUrl = require('../../../images/help.svg');
1112

1213
class Toolbar extends React.Component {
1314
constructor(props) {
@@ -102,19 +103,30 @@ class Toolbar extends React.Component {
102103
Auto-refresh
103104
</label>
104105
</div>
105-
<div className="toolbar__serve-secure">
106-
<input
107-
id="serve-secure"
108-
type="checkbox"
109-
checked={this.props.project.serveSecure}
110-
onChange={(event) => {
111-
this.props.setServeSecure(event.target.checked);
112-
}}
113-
/>
114-
<label htmlFor="serve-secure" className="toolbar__serve-secure-label">
115-
HTTPS
116-
</label>
117-
</div>
106+
{
107+
this.props.currentUser == null ?
108+
null :
109+
<div className="toolbar__serve-secure">
110+
<input
111+
id="serve-secure"
112+
type="checkbox"
113+
value={this.props.project.serveSecure}
114+
onChange={(event) => {
115+
this.props.setServeSecure(event.target.checked);
116+
}}
117+
/>
118+
<label htmlFor="serve-secure" className="toolbar__serve-secure-label">
119+
HTTPS
120+
</label>
121+
<button
122+
className="toolbar__serve-secure-help"
123+
onClick={() => this.props.showHelpModal('serveSecure')}
124+
aria-label="help"
125+
>
126+
<InlineSVG src={helpUrl} alt="Help" />
127+
</button>
128+
</div>
129+
}
118130
<div className={nameContainerClass}>
119131
<a
120132
className="toolbar__project-name"
@@ -187,6 +199,7 @@ Toolbar.propTypes = {
187199
}).isRequired,
188200
showEditProjectName: PropTypes.func.isRequired,
189201
hideEditProjectName: PropTypes.func.isRequired,
202+
showHelpModal: PropTypes.func.isRequired,
190203
infiniteLoop: PropTypes.bool.isRequired,
191204
autorefresh: PropTypes.bool.isRequired,
192205
setAutorefresh: PropTypes.func.isRequired,

client/modules/IDE/pages/IDEView.jsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import NewFolderModal from '../components/NewFolderModal';
1414
import ShareModal from '../components/ShareModal';
1515
import KeyboardShortcutModal from '../components/KeyboardShortcutModal';
1616
import ErrorModal from '../components/ErrorModal';
17+
import HelpModal from '../components/HelpModal';
1718
import Nav from '../../../components/Nav';
1819
import Console from '../components/Console';
1920
import Toast from '../components/Toast';
@@ -231,6 +232,7 @@ class IDEView extends React.Component {
231232
saveProject={this.props.saveProject}
232233
currentUser={this.props.user.username}
233234
clearConsole={this.props.clearConsole}
235+
showHelpModal={this.props.showHelpModal}
234236
/>
235237
<Preferences
236238
isVisible={this.props.ide.preferencesIsVisible}
@@ -450,6 +452,18 @@ class IDEView extends React.Component {
450452
);
451453
}
452454
})()}
455+
{(() => { // eslint-disable-line
456+
if (this.props.ide.helpType) {
457+
return (
458+
<Overlay>
459+
<HelpModal
460+
type={this.props.ide.helpType}
461+
closeModal={this.props.hideHelpModal}
462+
/>
463+
</Overlay>
464+
);
465+
}
466+
})()}
453467
</div>
454468

455469
);
@@ -493,7 +507,8 @@ IDEView.propTypes = {
493507
projectSavedTime: PropTypes.string.isRequired,
494508
previousPath: PropTypes.string.isRequired,
495509
justOpenedProject: PropTypes.bool.isRequired,
496-
errorType: PropTypes.string
510+
errorType: PropTypes.string,
511+
helpType: PropTypes.string
497512
}).isRequired,
498513
stopSketch: PropTypes.func.isRequired,
499514
startTextOutput: PropTypes.func.isRequired,
@@ -604,7 +619,9 @@ IDEView.propTypes = {
604619
showErrorModal: PropTypes.func.isRequired,
605620
hideErrorModal: PropTypes.func.isRequired,
606621
clearPersistedState: PropTypes.func.isRequired,
607-
persistState: PropTypes.func.isRequired
622+
persistState: PropTypes.func.isRequired,
623+
showHelpModal: PropTypes.func.isRequired,
624+
hideHelpModal: PropTypes.func.isRequired
608625
};
609626

610627
function mapStateToProps(state) {

client/modules/IDE/reducers/ide.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ const ide = (state = initialState, action) => {
9191
return Object.assign({}, state, { errorType: action.modalType });
9292
case ActionTypes.HIDE_ERROR_MODAL:
9393
return Object.assign({}, state, { errorType: undefined });
94+
case ActionTypes.SHOW_HELP_MODAL:
95+
return Object.assign({}, state, { helpType: action.helpType });
96+
case ActionTypes.HIDE_HELP_MODAL:
97+
return Object.assign({}, state, { helpType: undefined });
9498
default:
9599
return state;
96100
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
.help-modal {
2+
@extend %modal;
3+
padding: #{20 / $base-font-size}rem;
4+
width: #{500 / $base-font-size}rem;
5+
}
6+
7+
.help-modal__header {
8+
display: flex;
9+
justify-content: space-between;
10+
}
11+
12+
.help-modal__section {
13+
width: 100%;
14+
display: flex;
15+
align-items: center;
16+
padding: #{10 / $base-font-size}rem 0;
17+
18+
// Basic text styles for help body text
19+
ul,
20+
ol {
21+
margin-top: #{5 / $base-font-size}rem;
22+
}
23+
24+
p {
25+
margin-top: #{10 / $base-font-size}rem;
26+
}
27+
28+
li {
29+
list-style: disc inside;
30+
}
31+
}
32+
33+
.help-modal__label {
34+
width: #{86 / $base-font-size}rem;
35+
}
36+
37+
.help-modal__input {
38+
flex: 1;
39+
}

client/styles/components/_toolbar.scss

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,33 @@
120120
font-size: #{12 / $base-font-size}rem;
121121
}
122122

123+
.toolbar__serve-secure {
124+
margin-left: #{20 / $base-font-size}rem;
125+
}
126+
127+
.toolbar__serve-secure-label {
128+
@include themify() {
129+
color: getThemifyVariable('inactive-text-color');
130+
}
131+
margin-left: #{5 / $base-font-size}rem;
132+
font-size: #{12 / $base-font-size}rem;
133+
}
134+
135+
.toolbar__serve-secure-help {
136+
display: inline-block;
137+
vertical-align: top;
138+
height: #{12 / $base-font-size}rem;
139+
& svg {
140+
width: #{12 / $base-font-size}rem;
141+
height: #{12 / $base-font-size}rem;
142+
}
143+
@include themify() {
144+
& path {
145+
fill: getThemifyVariable('inactive-text-color');
146+
}
147+
}
148+
}
149+
123150
.toolbar__edit-name-button {
124151
display: inline-block;
125152
vertical-align: top;

client/styles/main.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
@import 'components/form-container';
3434
@import 'components/error-modal';
3535
@import 'components/preview-frame';
36+
@import 'components/help-modal';
3637

3738
@import 'layout/ide';
3839
@import 'layout/fullscreen';

0 commit comments

Comments
 (0)