aboutsummaryrefslogtreecommitdiff
path: root/src/settings/components/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/components/index.tsx')
-rw-r--r--src/settings/components/index.tsx199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/settings/components/index.tsx b/src/settings/components/index.tsx
new file mode 100644
index 0000000..b4a0866
--- /dev/null
+++ b/src/settings/components/index.tsx
@@ -0,0 +1,199 @@
+import './site.scss';
+import React from 'react';
+import { connect } from 'react-redux';
+import Input from './ui/Input';
+import SearchForm from './form/SearchForm';
+import KeymapsForm from './form/KeymapsForm';
+import BlacklistForm from './form/BlacklistForm';
+import PropertiesForm from './form/PropertiesForm';
+import * as settingActions from '../../settings/actions/setting';
+import SettingData, {
+ JSONSettings, FormKeymaps, FormSearch, FormSettings,
+} from '../../shared/SettingData';
+import { State as AppState } from '../reducers/setting';
+import * as settings from '../../shared/Settings';
+import * as PropertyDefs from '../../shared/property-defs';
+
+const DO_YOU_WANT_TO_CONTINUE =
+ 'Some settings in JSON can be lost when migrating. ' +
+ 'Do you want to continue?';
+
+type StateProps = ReturnType<typeof mapStateToProps>;
+interface DispatchProps {
+ dispatch: (action: any) => void,
+}
+type Props = StateProps & DispatchProps & {
+ // FIXME
+ store: any;
+};
+
+class SettingsComponent extends React.Component<Props> {
+ componentDidMount() {
+ this.props.dispatch(settingActions.load());
+ }
+
+ renderFormFields(form: any) {
+ let types = PropertyDefs.defs.reduce(
+ (o: {[key: string]: string}, def) => {
+ o[def.name] = def.type;
+ return o;
+ }, {});
+ return <div>
+ <fieldset>
+ <legend>Keybindings</legend>
+ <KeymapsForm
+ value={form.keymaps}
+ onChange={this.bindKeymapsForm.bind(this)}
+ onBlur={this.save.bind(this)}
+ />
+ </fieldset>
+ <fieldset>
+ <legend>Search Engines</legend>
+ <SearchForm
+ value={form.search}
+ onChange={this.bindSearchForm.bind(this)}
+ onBlur={this.save.bind(this)}
+ />
+ </fieldset>
+ <fieldset>
+ <legend>Blacklist</legend>
+ <BlacklistForm
+ value={form.blacklist}
+ onChange={this.bindBlacklistForm.bind(this)}
+ onBlur={this.save.bind(this)}
+ />
+ </fieldset>
+ <fieldset>
+ <legend>Properties</legend>
+ <PropertiesForm
+ types={types}
+ value={form.properties}
+ onChange={this.bindPropertiesForm.bind(this)}
+ onBlur={this.save.bind(this)}
+ />
+ </fieldset>
+ </div>;
+ }
+
+ renderJsonFields(json: JSONSettings, error: string) {
+ return <div>
+ <Input
+ type='textarea'
+ name='json'
+ label='Plain JSON'
+ spellCheck={false}
+ error={error}
+ onValueChange={this.bindJson.bind(this)}
+ onBlur={this.save.bind(this)}
+ value={json.toJSON()}
+ />
+ </div>;
+ }
+
+ render() {
+ let fields = null;
+ let disabled = this.props.error.length > 0;
+ if (this.props.source === 'form') {
+ fields = this.renderFormFields(this.props.form);
+ } else if (this.props.source === 'json') {
+ fields = this.renderJsonFields(
+ this.props.json as JSONSettings, this.props.error);
+ }
+ return (
+ <div>
+ <h1>Configure Vim-Vixen</h1>
+ <form className='vimvixen-settings-form'>
+ <Input
+ type='radio'
+ id='setting-source-form'
+ name='source'
+ label='Use form'
+ checked={this.props.source === 'form'}
+ value='form'
+ onValueChange={this.bindSource.bind(this)}
+ disabled={disabled} />
+
+ <Input
+ type='radio'
+ name='source'
+ label='Use plain JSON'
+ checked={this.props.source === 'json'}
+ value='json'
+ onValueChange={this.bindSource.bind(this)}
+ disabled={disabled} />
+ { fields }
+ </form>
+ </div>
+ );
+ }
+
+ bindKeymapsForm(value: FormKeymaps) {
+ let data = new SettingData({
+ source: this.props.source,
+ form: (this.props.form as FormSettings).buildWithKeymaps(value),
+ });
+ this.props.dispatch(settingActions.set(data));
+ }
+
+ bindSearchForm(value: any) {
+ let data = new SettingData({
+ source: this.props.source,
+ form: (this.props.form as FormSettings).buildWithSearch(
+ FormSearch.valueOf(value)),
+ });
+ this.props.dispatch(settingActions.set(data));
+ }
+
+ bindBlacklistForm(value: any) {
+ let data = new SettingData({
+ source: this.props.source,
+ form: (this.props.form as FormSettings).buildWithBlacklist(
+ settings.blacklistValueOf(value)),
+ });
+ this.props.dispatch(settingActions.set(data));
+ }
+
+ bindPropertiesForm(value: any) {
+ let data = new SettingData({
+ source: this.props.source,
+ form: (this.props.form as FormSettings).buildWithProperties(
+ settings.propertiesValueOf(value)),
+ });
+ this.props.dispatch(settingActions.set(data));
+ }
+
+ bindJson(_name: string, value: string) {
+ let data = new SettingData({
+ source: this.props.source,
+ json: JSONSettings.valueOf(value),
+ });
+ this.props.dispatch(settingActions.set(data));
+ }
+
+ bindSource(_name: string, value: string) {
+ let from = this.props.source;
+ if (from === 'form' && value === 'json') {
+ this.props.dispatch(settingActions.switchToJson(
+ this.props.form as FormSettings));
+ } else if (from === 'json' && value === 'form') {
+ let b = window.confirm(DO_YOU_WANT_TO_CONTINUE);
+ if (!b) {
+ this.forceUpdate();
+ return;
+ }
+ this.props.dispatch(
+ settingActions.switchToForm(this.props.json as JSONSettings));
+ }
+ }
+
+ save() {
+ let { source, json, form } = this.props.store.getState();
+ this.props.dispatch(settingActions.save(
+ new SettingData({ source, json, form }),
+ ));
+ }
+}
+
+const mapStateToProps = (state: AppState) => ({ ...state });
+
+export default connect(mapStateToProps)(SettingsComponent);