1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-12 08:54:00 +02:00
joplin/ElectronClient/app/gui/ConfigScreen.jsx

205 lines
5.6 KiB
React
Raw Normal View History

2017-11-12 02:44:26 +02:00
const React = require('react');
const { connect } = require('react-redux');
const { reg } = require('lib/registry.js');
2017-12-14 20:12:14 +02:00
const Setting = require('lib/models/Setting.js');
2017-11-12 02:44:26 +02:00
const { bridge } = require('electron').remote.require('./bridge');
const { Header } = require('./Header.min.js');
const { themeStyle } = require('../theme.js');
const pathUtils = require('lib/path-utils.js');
2017-11-12 02:44:26 +02:00
const { _ } = require('lib/locale.js');
class ConfigScreenComponent extends React.Component {
constructor() {
super();
this.state = {
settings: {},
};
}
componentWillMount() {
this.setState({ settings: this.props.settings });
}
2017-12-17 13:30:32 +02:00
keyValueToArray(kv) {
let output = [];
for (let k in kv) {
if (!kv.hasOwnProperty(k)) continue;
output.push({
key: k,
label: kv[k],
});
}
output.sort((a, b) => {
return a.label.toLowerCase() < b.label.toLowerCase() ? -1 : +1;
});
return output;
}
2017-11-12 02:44:26 +02:00
settingToComponent(key, value) {
const theme = themeStyle(this.props.theme);
let output = null;
const rowStyle = {
marginBottom: 10,
};
const labelStyle = Object.assign({}, theme.textStyle, {
display: 'inline-block',
marginRight: 10,
});
const controlStyle = {
display: 'inline-block',
};
const updateSettingValue = (key, value) => {
const settings = Object.assign({}, this.state.settings);
settings[key] = value;
this.setState({ settings: settings });
2017-11-12 02:44:26 +02:00
}
2017-11-30 20:36:26 +02:00
// Component key needs to be key+value otherwise it doesn't update when the settings change.
2017-11-12 02:44:26 +02:00
const md = Setting.settingMetadata(key);
if (md.isEnum) {
let items = [];
const settingOptions = md.options();
2017-12-17 13:30:32 +02:00
let array = this.keyValueToArray(settingOptions);
for (let i = 0; i < array.length; i++) {
const e = array[i];
items.push(<option value={e.key.toString()} key={e.key}>{settingOptions[e.key]}</option>);
2017-11-12 02:44:26 +02:00
}
return (
2017-12-15 09:31:57 +02:00
<div key={key} style={rowStyle}>
2017-11-12 02:44:26 +02:00
<div style={labelStyle}><label>{md.label()}</label></div>
<select value={value} style={controlStyle} onChange={(event) => { updateSettingValue(key, event.target.value) }}>
{items}
</select>
</div>
);
} else if (md.type === Setting.TYPE_BOOL) {
const onCheckboxClick = (event) => {
updateSettingValue(key, !value)
}
// Hack: The {key+value.toString()} is needed as otherwise the checkbox doesn't update when the state changes.
// There's probably a better way to do this but can't figure it out.
2017-11-12 02:44:26 +02:00
return (
<div key={key+value.toString()} style={rowStyle}>
2017-11-12 02:44:26 +02:00
<div style={controlStyle}>
<input id={'setting_checkbox_' + key} type="checkbox" checked={!!value} onChange={(event) => { onCheckboxClick(event) }}/><label onClick={(event) => { onCheckboxClick(event) }} style={labelStyle} htmlFor={'setting_checkbox_' + key}>{md.label()}</label>
2017-11-12 02:44:26 +02:00
</div>
</div>
);
} else if (md.type === Setting.TYPE_STRING) {
const onTextChange = (event) => {
updateSettingValue(key, event.target.value);
}
const inputType = md.secure === true ? 'password' : 'text';
return (
2017-12-15 09:31:57 +02:00
<div key={key} style={rowStyle}>
<div style={labelStyle}><label>{md.label()}</label></div>
<input type={inputType} style={controlStyle} value={this.state.settings[key]} onChange={(event) => {onTextChange(event)}} />
</div>
);
2018-01-19 14:27:44 +02:00
} else if (md.type === Setting.TYPE_INT) {
const onNumChange = (event) => {
updateSettingValue(key, event.target.value);
2018-01-19 14:27:44 +02:00
};
return (
<div key={key} style={rowStyle}>
<div style={labelStyle}><label>{md.label()}</label></div>
<input type="number" style={controlStyle} value={this.state.settings[key]} onChange={(event) => {onNumChange(event)}} min={md.minimum} max={md.maximum} step={md.step}/>
</div>
2018-01-19 14:27:44 +02:00
);
} else {
console.warn('Type not implemented: ' + key);
2017-11-12 02:44:26 +02:00
}
return output;
}
onSaveClick() {
for (let n in this.state.settings) {
if (!this.state.settings.hasOwnProperty(n)) continue;
Setting.setValue(n, this.state.settings[n]);
}
this.props.dispatch({ type: 'NAV_BACK' });
}
onCancelClick() {
this.props.dispatch({ type: 'NAV_BACK' });
}
2017-11-12 02:44:26 +02:00
render() {
const theme = themeStyle(this.props.theme);
const style = this.props.style;
const settings = this.state.settings;
2017-11-12 02:44:26 +02:00
const headerStyle = {
width: style.width,
};
const containerStyle = {
padding: 10,
};
const buttonStyle = {
display: this.state.settings === this.props.settings ? 'none' : 'inline-block',
marginRight: 10,
}
2017-11-12 02:44:26 +02:00
let settingComps = [];
let keys = Setting.keys(true, 'desktop');
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (!(key in settings)) {
console.warn('Missing setting: ' + key);
continue;
}
const md = Setting.settingMetadata(key);
if (md.show && !md.show(settings)) continue;
2017-11-12 02:44:26 +02:00
const comp = this.settingToComponent(key, settings[key]);
if (!comp) continue;
settingComps.push(comp);
}
return (
<div style={style}>
<Header style={headerStyle} />
<div style={containerStyle}>
<div style={Object.assign({}, theme.textStyle, {marginBottom: 20})}>
{_('Notes and settings are stored in: %s', pathUtils.toSystemSlashes(Setting.value('profileDir'), process.platform))}
</div>
2017-11-12 02:44:26 +02:00
{ settingComps }
<button onClick={() => {this.onSaveClick()}} style={buttonStyle}>{_('Save')}</button>
<button onClick={() => {this.onCancelClick()}} style={buttonStyle}>{_('Cancel')}</button>
2017-11-12 02:44:26 +02:00
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
theme: state.settings.theme,
settings: state.settings,
locale: state.settings.locale,
};
};
const ConfigScreen = connect(mapStateToProps)(ConfigScreenComponent);
module.exports = { ConfigScreen };