196 lines
5.5 KiB
TypeScript
196 lines
5.5 KiB
TypeScript
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, {
|
|
FormKeymaps, FormSearch, FormSettings, JSONTextSettings,
|
|
} from '../../shared/SettingData';
|
|
import { State as AppState } from '../reducers/setting';
|
|
import Properties from '../../shared/settings/Properties';
|
|
import Blacklist from '../../shared/settings/Blacklist';
|
|
|
|
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) {
|
|
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={Properties.types()}
|
|
value={form.properties}
|
|
onChange={this.bindPropertiesForm.bind(this)}
|
|
onBlur={this.save.bind(this)}
|
|
/>
|
|
</fieldset>
|
|
</div>;
|
|
}
|
|
|
|
renderJsonFields(json: JSONTextSettings, 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.toJSONText()}
|
|
/>
|
|
</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 JSONTextSettings, 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(
|
|
Blacklist.fromJSON(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(
|
|
Properties.fromJSON(value))
|
|
});
|
|
this.props.dispatch(settingActions.set(data));
|
|
}
|
|
|
|
bindJson(_name: string, value: string) {
|
|
let data = new SettingData({
|
|
source: this.props.source,
|
|
json: JSONTextSettings.fromText(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));
|
|
this.save();
|
|
} 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 JSONTextSettings));
|
|
this.save();
|
|
}
|
|
}
|
|
|
|
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);
|