2016-06-27 19:57:36 +00:00
|
|
|
import React, { PropTypes } from 'react';
|
2016-08-01 17:55:49 +00:00
|
|
|
import InlineSVG from 'react-inlinesvg';
|
2017-08-09 17:34:59 +00:00
|
|
|
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
2016-08-05 01:43:13 +00:00
|
|
|
// import { bindActionCreators } from 'redux';
|
|
|
|
// import { connect } from 'react-redux';
|
|
|
|
// import * as PreferencesActions from '../actions/preferences';
|
2016-06-23 22:29:55 +00:00
|
|
|
|
|
|
|
const plusUrl = require('../../../images/plus.svg');
|
|
|
|
const minusUrl = require('../../../images/minus.svg');
|
2016-09-01 03:07:43 +00:00
|
|
|
const beepUrl = require('../../../sounds/audioAlert.mp3');
|
2017-11-14 20:27:00 +00:00
|
|
|
const infoUrl = require('../../../images/information.svg');
|
2016-06-23 22:29:55 +00:00
|
|
|
|
2016-08-04 03:45:49 +00:00
|
|
|
class Preferences extends React.Component {
|
2016-08-09 20:15:28 +00:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
this.handleUpdateAutosave = this.handleUpdateAutosave.bind(this);
|
2016-11-08 18:11:07 +00:00
|
|
|
this.handleUpdateFont = this.handleUpdateFont.bind(this);
|
|
|
|
this.handleUpdateIndentation = this.handleUpdateIndentation.bind(this);
|
|
|
|
this.handleLintWarning = this.handleLintWarning.bind(this);
|
2016-08-09 20:15:28 +00:00
|
|
|
}
|
|
|
|
|
2016-08-04 03:45:49 +00:00
|
|
|
handleUpdateFont(event) {
|
2016-11-08 18:11:07 +00:00
|
|
|
let value = parseInt(event.target.value, 10);
|
|
|
|
if (isNaN(value)) {
|
|
|
|
value = 16;
|
|
|
|
}
|
|
|
|
this.props.setFontSize(value);
|
2016-08-04 03:45:49 +00:00
|
|
|
}
|
2016-07-06 15:27:39 +00:00
|
|
|
|
2016-08-04 03:45:49 +00:00
|
|
|
handleUpdateIndentation(event) {
|
2016-11-08 18:11:07 +00:00
|
|
|
let value = parseInt(event.target.value, 10);
|
|
|
|
if (isNaN(value)) {
|
|
|
|
value = 2;
|
|
|
|
}
|
|
|
|
this.props.setIndentation(value);
|
2016-08-04 03:45:49 +00:00
|
|
|
}
|
2016-07-06 15:27:39 +00:00
|
|
|
|
2016-08-09 20:15:28 +00:00
|
|
|
handleUpdateAutosave(event) {
|
|
|
|
const value = event.target.value === 'true';
|
|
|
|
this.props.setAutosave(value);
|
|
|
|
}
|
|
|
|
|
2016-08-11 18:09:59 +00:00
|
|
|
handleLintWarning(event) {
|
|
|
|
const value = event.target.value === 'true';
|
|
|
|
this.props.setLintWarning(value);
|
|
|
|
}
|
|
|
|
|
2016-08-04 03:45:49 +00:00
|
|
|
render() {
|
2016-09-01 03:07:43 +00:00
|
|
|
const beep = new Audio(beepUrl);
|
2016-08-29 18:39:23 +00:00
|
|
|
|
2016-08-04 03:45:49 +00:00
|
|
|
return (
|
2017-11-14 00:09:08 +00:00
|
|
|
<section className="preferences" tabIndex="0" title="preference-menu">
|
2017-08-09 17:34:59 +00:00
|
|
|
<Tabs>
|
|
|
|
<TabList>
|
|
|
|
<div className="preference__subheadings">
|
2017-08-16 18:23:13 +00:00
|
|
|
<Tab><h4 className="preference__subheading">General Settings</h4></Tab>
|
|
|
|
<Tab><h4 className="preference__subheading">Sketch Settings</h4></Tab>
|
|
|
|
<Tab><h4 className="preference__subheading">Accessibility</h4></Tab>
|
2017-08-09 17:34:59 +00:00
|
|
|
</div>
|
|
|
|
</TabList>
|
|
|
|
<TabPanel>
|
|
|
|
<div className="preference">
|
|
|
|
<h4 className="preference__title">Theme</h4>
|
|
|
|
<div className="preference__options">
|
|
|
|
<input
|
|
|
|
type="radio"
|
|
|
|
onChange={() => this.props.setTheme('light')}
|
|
|
|
aria-label="light theme on"
|
|
|
|
name="light theme"
|
|
|
|
id="light-theme-on"
|
|
|
|
className="preference__radio-button"
|
|
|
|
value="light"
|
|
|
|
checked={this.props.theme === 'light'}
|
|
|
|
/>
|
|
|
|
<label htmlFor="light-theme-on" className="preference__option">Light</label>
|
|
|
|
<input
|
|
|
|
type="radio"
|
|
|
|
onChange={() => this.props.setTheme('dark')}
|
|
|
|
aria-label="dark theme on"
|
|
|
|
name="dark theme"
|
|
|
|
id="dark-theme-on"
|
|
|
|
className="preference__radio-button"
|
|
|
|
value="dark"
|
|
|
|
checked={this.props.theme === 'dark'}
|
|
|
|
/>
|
|
|
|
<label htmlFor="dark-theme-on" className="preference__option">Dark</label>
|
2017-11-14 20:27:00 +00:00
|
|
|
<input
|
|
|
|
type="radio"
|
|
|
|
onChange={() => this.props.setTheme('contrast')}
|
|
|
|
aria-label="high contrast theme on"
|
|
|
|
name="high contrast theme"
|
|
|
|
id="high-contrast-theme-on"
|
|
|
|
className="preference__radio-button"
|
|
|
|
value="contrast"
|
|
|
|
checked={this.props.theme === 'contrast'}
|
|
|
|
/>
|
|
|
|
<label htmlFor="high-contrast-theme-on" className="preference__option">High Contrast</label>
|
2017-08-09 17:34:59 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="preference">
|
|
|
|
<h4 className="preference__title">Text size</h4>
|
|
|
|
<button
|
|
|
|
className="preference__minus-button"
|
|
|
|
onClick={() => this.props.setFontSize(this.props.fontSize - 2)}
|
|
|
|
aria-label="decrease font size"
|
|
|
|
>
|
|
|
|
<InlineSVG src={minusUrl} alt="Decrease Font Size" />
|
|
|
|
<h6 className="preference__label">Decrease</h6>
|
|
|
|
</button>
|
|
|
|
<input
|
|
|
|
className="preference__value"
|
|
|
|
aria-live="polite"
|
|
|
|
aria-atomic="true"
|
|
|
|
role="status"
|
|
|
|
value={this.props.fontSize}
|
|
|
|
onChange={this.handleUpdateFont}
|
|
|
|
ref={(element) => { this.fontSizeInput = element; }}
|
|
|
|
onClick={() => {
|
|
|
|
this.fontSizeInput.select();
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
</input>
|
|
|
|
<button
|
|
|
|
className="preference__plus-button"
|
|
|
|
onClick={() => this.props.setFontSize(this.props.fontSize + 2)}
|
|
|
|
aria-label="increase font size"
|
|
|
|
>
|
|
|
|
<InlineSVG src={plusUrl} alt="Increase Font Size" />
|
|
|
|
<h6 className="preference__label">Increase</h6>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div className="preference">
|
|
|
|
<h4 className="preference__title">Indentation amount</h4>
|
|
|
|
<button
|
|
|
|
className="preference__minus-button"
|
|
|
|
onClick={() => this.props.setIndentation(this.props.indentationAmount - 2)}
|
|
|
|
aria-label="decrease indentation amount"
|
|
|
|
>
|
|
|
|
<InlineSVG src={minusUrl} alt="DecreaseIndentation Amount" />
|
|
|
|
<h6 className="preference__label">Decrease</h6>
|
|
|
|
</button>
|
|
|
|
<input
|
|
|
|
className="preference__value"
|
|
|
|
aria-live="polite"
|
|
|
|
aria-atomic="true"
|
|
|
|
role="status"
|
|
|
|
value={this.props.indentationAmount}
|
|
|
|
onChange={this.handleUpdateIndentation}
|
|
|
|
ref={(element) => { this.indentationInput = element; }}
|
|
|
|
onClick={() => {
|
|
|
|
this.indentationInput.select();
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
</input>
|
|
|
|
<button
|
|
|
|
className="preference__plus-button"
|
|
|
|
onClick={() => this.props.setIndentation(this.props.indentationAmount + 2)}
|
|
|
|
aria-label="increase indentation amount"
|
|
|
|
>
|
|
|
|
<InlineSVG src={plusUrl} alt="IncreaseIndentation Amount" />
|
|
|
|
<h6 className="preference__label">Increase</h6>
|
|
|
|
</button>
|
2017-08-17 12:51:00 +00:00
|
|
|
<input
|
|
|
|
type="radio"
|
|
|
|
onChange={this.props.indentWithSpace}
|
|
|
|
aria-label="indentation with space"
|
|
|
|
name="indentation"
|
|
|
|
id="indentation-space"
|
|
|
|
className="preference__radio-button"
|
|
|
|
value="Spaces"
|
|
|
|
checked={!this.props.isTabIndent}
|
|
|
|
/>
|
2017-11-14 22:03:16 +00:00
|
|
|
<label
|
|
|
|
htmlFor="indentation-space"
|
|
|
|
className="preference__option preference__whitespace-button"
|
|
|
|
>
|
|
|
|
Spaces
|
|
|
|
</label>
|
2017-08-17 12:51:00 +00:00
|
|
|
<input
|
|
|
|
type="radio"
|
|
|
|
onChange={this.props.indentWithTab}
|
|
|
|
aria-label="indentation with tab"
|
|
|
|
name="indentation"
|
|
|
|
id="indentation-tab"
|
|
|
|
className="preference__radio-button"
|
|
|
|
value="Tabs"
|
|
|
|
checked={this.props.isTabIndent}
|
|
|
|
/>
|
2017-11-14 21:27:42 +00:00
|
|
|
<label htmlFor="indentation-tab" className="preference__option preference__whitespace-button">Tabs</label>
|
2017-08-09 17:34:59 +00:00
|
|
|
</div>
|
|
|
|
<div className="preference">
|
|
|
|
<h4 className="preference__title">Autosave</h4>
|
|
|
|
<div className="preference__options">
|
|
|
|
<input
|
|
|
|
type="radio"
|
|
|
|
onChange={() => this.props.setAutosave(true)}
|
|
|
|
aria-label="autosave on"
|
|
|
|
name="autosave"
|
|
|
|
id="autosave-on"
|
|
|
|
className="preference__radio-button"
|
|
|
|
value="On"
|
|
|
|
checked={this.props.autosave}
|
|
|
|
/>
|
|
|
|
<label htmlFor="autosave-on" className="preference__option">On</label>
|
|
|
|
<input
|
|
|
|
type="radio"
|
|
|
|
onChange={() => this.props.setAutosave(false)}
|
|
|
|
aria-label="autosave off"
|
|
|
|
name="autosave"
|
|
|
|
id="autosave-off"
|
|
|
|
className="preference__radio-button"
|
|
|
|
value="Off"
|
|
|
|
checked={!this.props.autosave}
|
|
|
|
/>
|
|
|
|
<label htmlFor="autosave-off" className="preference__option">Off</label>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</TabPanel>
|
2017-08-16 18:23:13 +00:00
|
|
|
<TabPanel>
|
2017-11-14 20:27:00 +00:00
|
|
|
{/* <div className="preference">
|
2017-08-16 18:23:13 +00:00
|
|
|
<h4 className="preference__title">Add a p5.js or an external library</h4>
|
2017-11-14 20:27:00 +00:00
|
|
|
</div> */}
|
|
|
|
<div className="preference">
|
2017-08-16 18:23:13 +00:00
|
|
|
<h4 className="preference__title">Security Protocol</h4>
|
2017-11-14 20:27:00 +00:00
|
|
|
<div className="preference__serve-secure">
|
|
|
|
<input
|
|
|
|
id="serve-secure"
|
|
|
|
type="checkbox"
|
|
|
|
checked={this.props.serveSecure || false}
|
|
|
|
onChange={(event) => {
|
|
|
|
this.props.setServeSecure(event.target.checked);
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<label htmlFor="serve-secure">Serve over HTTPS</label>
|
|
|
|
<span
|
|
|
|
className="serve-secture__tooltip tooltipped tooltipped-n tooltipped-no-delay tooltipped-multiline"
|
|
|
|
aria-label={'Choose HTTPS if you need to \n • access a microphone or webcam \n'
|
|
|
|
+ '• access an API served over HTTPS \n\n'
|
|
|
|
+ 'Choose HTTP if you need to \n'
|
|
|
|
+ '• access an API served over HTTP'}
|
|
|
|
>
|
|
|
|
<InlineSVG src={infoUrl} className="serve-secure__icon" />
|
|
|
|
</span>
|
|
|
|
</div>
|
2017-08-16 18:23:13 +00:00
|
|
|
</div>
|
|
|
|
</TabPanel>
|
2017-08-09 17:34:59 +00:00
|
|
|
<TabPanel>
|
|
|
|
<div className="preference">
|
2017-11-14 21:27:42 +00:00
|
|
|
<h4 className="preference__title">Lint warning sound</h4>
|
2017-08-09 17:34:59 +00:00
|
|
|
<div className="preference__options">
|
|
|
|
<input
|
2017-08-17 12:51:00 +00:00
|
|
|
type="radio"
|
2017-11-14 21:27:42 +00:00
|
|
|
onChange={() => this.props.setLintWarning(true)}
|
|
|
|
aria-label="lint warning on"
|
|
|
|
name="lint warning"
|
|
|
|
id="lint-warning-on"
|
2017-08-17 12:51:00 +00:00
|
|
|
className="preference__radio-button"
|
2017-08-09 17:34:59 +00:00
|
|
|
value="On"
|
2017-11-14 21:27:42 +00:00
|
|
|
checked={this.props.lintWarning}
|
2017-08-09 17:34:59 +00:00
|
|
|
/>
|
2017-11-14 21:27:42 +00:00
|
|
|
<label htmlFor="lint-warning-on" className="preference__option">On</label>
|
2017-08-09 17:34:59 +00:00
|
|
|
<input
|
2017-08-17 12:51:00 +00:00
|
|
|
type="radio"
|
2017-11-14 21:27:42 +00:00
|
|
|
onChange={() => this.props.setLintWarning(false)}
|
|
|
|
aria-label="lint warning off"
|
|
|
|
name="lint warning"
|
|
|
|
id="lint-warning-off"
|
2017-08-17 12:51:00 +00:00
|
|
|
className="preference__radio-button"
|
2017-11-14 21:27:42 +00:00
|
|
|
value="Off"
|
|
|
|
checked={!this.props.lintWarning}
|
2017-08-09 17:34:59 +00:00
|
|
|
/>
|
2017-11-14 21:27:42 +00:00
|
|
|
<label htmlFor="lint-warning-off" className="preference__option">Off</label>
|
2017-08-17 12:51:00 +00:00
|
|
|
<button
|
|
|
|
className="preference__preview-button"
|
|
|
|
onClick={() => beep.play()}
|
|
|
|
aria-label="preview sound"
|
|
|
|
>
|
|
|
|
Preview sound
|
|
|
|
</button>
|
2017-08-09 17:34:59 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="preference">
|
2017-11-14 21:27:42 +00:00
|
|
|
<h4 className="preference__title">Accessible text-based canvas</h4>
|
|
|
|
<h6 className="preference__subtitle">Used with screen reader</h6>
|
|
|
|
|
2017-08-09 17:34:59 +00:00
|
|
|
<div className="preference__options">
|
|
|
|
<input
|
2017-11-14 21:27:42 +00:00
|
|
|
type="checkbox"
|
|
|
|
onChange={(event) => {
|
|
|
|
this.props.setTextOutput(event.target.checked);
|
|
|
|
}}
|
|
|
|
aria-label="text output on"
|
|
|
|
name="text output"
|
|
|
|
id="text-output-on"
|
2017-08-09 17:34:59 +00:00
|
|
|
value="On"
|
2017-11-14 21:27:42 +00:00
|
|
|
checked={(this.props.textOutput)}
|
2017-08-09 17:34:59 +00:00
|
|
|
/>
|
2017-11-14 21:27:42 +00:00
|
|
|
<label htmlFor="text-output-on" className="preference__option preference__canvas">Plain-text</label>
|
2017-08-09 17:34:59 +00:00
|
|
|
<input
|
2017-11-14 21:27:42 +00:00
|
|
|
type="checkbox"
|
|
|
|
onChange={(event) => {
|
|
|
|
this.props.setGridOutput(event.target.checked);
|
|
|
|
}}
|
|
|
|
aria-label="table output on"
|
|
|
|
name="table output"
|
|
|
|
id="table-output-on"
|
|
|
|
value="On"
|
|
|
|
checked={(this.props.gridOutput)}
|
2017-08-09 17:34:59 +00:00
|
|
|
/>
|
2017-11-14 21:27:42 +00:00
|
|
|
<label htmlFor="table-output-on" className="preference__option preference__canvas">Table-text</label>
|
|
|
|
<input
|
|
|
|
type="checkbox"
|
|
|
|
onChange={(event) => {
|
|
|
|
this.props.setSoundOutput(event.target.checked);
|
|
|
|
}}
|
|
|
|
aria-label="sound output on"
|
|
|
|
name="sound output"
|
|
|
|
id="sound-output-on"
|
|
|
|
value="On"
|
|
|
|
checked={(this.props.soundOutput)}
|
|
|
|
/>
|
|
|
|
<label htmlFor="sound-output-on" className="preference__option preference__canvas">Sound</label>
|
2017-08-09 17:34:59 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</TabPanel>
|
|
|
|
</Tabs>
|
2016-08-04 03:45:49 +00:00
|
|
|
</section>
|
|
|
|
);
|
|
|
|
}
|
2016-06-23 22:29:55 +00:00
|
|
|
}
|
|
|
|
|
2016-06-27 19:57:36 +00:00
|
|
|
Preferences.propTypes = {
|
|
|
|
fontSize: PropTypes.number.isRequired,
|
2016-07-06 15:27:39 +00:00
|
|
|
indentationAmount: PropTypes.number.isRequired,
|
2016-08-04 03:45:49 +00:00
|
|
|
setIndentation: PropTypes.func.isRequired,
|
2016-07-11 02:52:48 +00:00
|
|
|
indentWithSpace: PropTypes.func.isRequired,
|
|
|
|
indentWithTab: PropTypes.func.isRequired,
|
2016-08-04 03:45:49 +00:00
|
|
|
isTabIndent: PropTypes.bool.isRequired,
|
2016-08-09 20:15:28 +00:00
|
|
|
setFontSize: PropTypes.func.isRequired,
|
|
|
|
autosave: PropTypes.bool.isRequired,
|
2016-08-11 18:09:59 +00:00
|
|
|
setAutosave: PropTypes.func.isRequired,
|
2017-05-31 19:23:30 +00:00
|
|
|
textOutput: PropTypes.bool.isRequired,
|
|
|
|
gridOutput: PropTypes.bool.isRequired,
|
2017-11-14 21:27:42 +00:00
|
|
|
soundOutput: PropTypes.bool.isRequired,
|
2016-08-12 19:50:33 +00:00
|
|
|
setTextOutput: PropTypes.func.isRequired,
|
2017-05-31 19:23:30 +00:00
|
|
|
setGridOutput: PropTypes.func.isRequired,
|
2017-11-14 21:27:42 +00:00
|
|
|
setSoundOutput: PropTypes.func.isRequired,
|
2016-08-11 18:09:59 +00:00
|
|
|
lintWarning: PropTypes.bool.isRequired,
|
2016-09-13 18:15:46 +00:00
|
|
|
setLintWarning: PropTypes.func.isRequired,
|
|
|
|
theme: PropTypes.string.isRequired,
|
2017-11-14 20:27:00 +00:00
|
|
|
serveSecure: PropTypes.bool.isRequired,
|
2017-09-22 13:36:25 +00:00
|
|
|
setServeSecure: PropTypes.func.isRequired,
|
2016-09-13 18:15:46 +00:00
|
|
|
setTheme: PropTypes.func.isRequired
|
2016-06-27 19:57:36 +00:00
|
|
|
};
|
|
|
|
|
2017-09-22 13:36:25 +00:00
|
|
|
Preferences.defaultProps = {
|
|
|
|
currentUser: undefined
|
|
|
|
};
|
|
|
|
|
2016-08-05 01:43:13 +00:00
|
|
|
export default Preferences;
|