mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Electron: Add support for file system sync
This commit is contained in:
parent
f3751e4ba6
commit
6f97747199
@ -9,6 +9,18 @@ const { _ } = require('lib/locale.js');
|
|||||||
|
|
||||||
class ConfigScreenComponent extends React.Component {
|
class ConfigScreenComponent extends React.Component {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
settings: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
this.setState({ settings: this.props.settings });
|
||||||
|
}
|
||||||
|
|
||||||
settingToComponent(key, value) {
|
settingToComponent(key, value) {
|
||||||
const theme = themeStyle(this.props.theme);
|
const theme = themeStyle(this.props.theme);
|
||||||
|
|
||||||
@ -28,7 +40,9 @@ class ConfigScreenComponent extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateSettingValue = (key, value) => {
|
const updateSettingValue = (key, value) => {
|
||||||
Setting.setValue(key, value);
|
const settings = Object.assign({}, this.state.settings);
|
||||||
|
settings[key] = value;
|
||||||
|
this.setState({ settings: settings });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Component key needs to be key+value otherwise it doesn't update when the settings change.
|
// Component key needs to be key+value otherwise it doesn't update when the settings change.
|
||||||
@ -52,22 +66,53 @@ class ConfigScreenComponent extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (md.type === Setting.TYPE_BOOL) {
|
} else if (md.type === Setting.TYPE_BOOL) {
|
||||||
|
const onCheckboxClick = (event) => {
|
||||||
|
updateSettingValue(key, !value)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={key+value} style={rowStyle}>
|
<div key={key+value} style={rowStyle}>
|
||||||
<div style={controlStyle}>
|
<div style={controlStyle}>
|
||||||
<label><input type="checkbox" defaultChecked={!!value} onChange={(event) => { updateSettingValue(key, !!event.target.checked) }}/><span style={labelStyle}> {md.label()}</span></label>
|
<input id={'setting_checkbox_' + key} type="checkbox" defaultChecked={!!value} onChange={(event) => { onCheckboxClick(event) }}/><label onClick={(event) => { onCheckboxClick(event) }} style={labelStyle} htmlFor={'setting_checkbox_' + key}>{md.label()}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
} else if (md.type === Setting.TYPE_STRING) {
|
||||||
|
const onTextChange = (event) => {
|
||||||
|
const settings = Object.assign({}, this.state.settings);
|
||||||
|
settings[key] = event.target.value;
|
||||||
|
this.setState({ settings: settings });
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={key+value} style={rowStyle}>
|
||||||
|
<div style={labelStyle}><label>{md.label()}</label></div>
|
||||||
|
<input type="text" style={controlStyle} value={this.state.settings[key]} onChange={(event) => {onTextChange(event)}} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.warn('Type not implemented: ' + key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
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' });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const theme = themeStyle(this.props.theme);
|
const theme = themeStyle(this.props.theme);
|
||||||
const style = this.props.style;
|
const style = this.props.style;
|
||||||
const settings = this.props.settings;
|
const settings = this.state.settings;
|
||||||
|
|
||||||
const headerStyle = {
|
const headerStyle = {
|
||||||
width: style.width,
|
width: style.width,
|
||||||
@ -77,15 +122,21 @@ class ConfigScreenComponent extends React.Component {
|
|||||||
padding: 10,
|
padding: 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const buttonStyle = {
|
||||||
|
display: this.state.settings === this.props.settings ? 'none' : 'inline-block',
|
||||||
|
marginRight: 10,
|
||||||
|
}
|
||||||
|
|
||||||
let settingComps = [];
|
let settingComps = [];
|
||||||
let keys = Setting.keys(true, 'desktop');
|
let keys = Setting.keys(true, 'desktop');
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
const key = keys[i];
|
const key = keys[i];
|
||||||
if (key === 'sync.target') continue;
|
|
||||||
if (!(key in settings)) {
|
if (!(key in settings)) {
|
||||||
console.warn('Missing setting: ' + key);
|
console.warn('Missing setting: ' + key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
const md = Setting.settingMetadata(key);
|
||||||
|
if (md.show && !md.show(settings)) continue;
|
||||||
const comp = this.settingToComponent(key, settings[key]);
|
const comp = this.settingToComponent(key, settings[key]);
|
||||||
if (!comp) continue;
|
if (!comp) continue;
|
||||||
settingComps.push(comp);
|
settingComps.push(comp);
|
||||||
@ -96,6 +147,8 @@ class ConfigScreenComponent extends React.Component {
|
|||||||
<Header style={headerStyle} />
|
<Header style={headerStyle} />
|
||||||
<div style={containerStyle}>
|
<div style={containerStyle}>
|
||||||
{ settingComps }
|
{ settingComps }
|
||||||
|
<button onClick={() => {this.onSaveClick()}} style={buttonStyle}>{_('Save')}</button>
|
||||||
|
<button onClick={() => {this.onCancelClick()}} style={buttonStyle}>{_('Cancel')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -22,15 +22,6 @@ class Setting extends BaseModel {
|
|||||||
this.metadata_ = {
|
this.metadata_ = {
|
||||||
'activeFolderId': { value: '', type: Setting.TYPE_STRING, public: false },
|
'activeFolderId': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
'firstStart': { value: true, type: Setting.TYPE_BOOL, public: false },
|
'firstStart': { value: true, type: Setting.TYPE_BOOL, public: false },
|
||||||
'sync.2.path': { value: '', type: Setting.TYPE_STRING, public: true, appTypes: ['cli'], label: () => _('File system synchronisation target directory'), description: () => _('The path to synchronise with when file system synchronisation is enabled. See `sync.target`.') },
|
|
||||||
'sync.3.auth': { value: '', type: Setting.TYPE_STRING, public: false },
|
|
||||||
'sync.4.auth': { value: '', type: Setting.TYPE_STRING, public: false },
|
|
||||||
'sync.1.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
|
||||||
'sync.2.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
|
||||||
'sync.3.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
|
||||||
'sync.4.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
|
||||||
'sync.5.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
|
||||||
'sync.6.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
|
||||||
'editor': { value: '', type: Setting.TYPE_STRING, public: true, appTypes: ['cli'], label: () => _('Text editor'), description: () => _('The editor that will be used to open a note. If none is provided it will try to auto-detect the default editor.') },
|
'editor': { value: '', type: Setting.TYPE_STRING, public: true, appTypes: ['cli'], label: () => _('Text editor'), description: () => _('The editor that will be used to open a note. If none is provided it will try to auto-detect the default editor.') },
|
||||||
'locale': { value: defaultLocale(), type: Setting.TYPE_STRING, isEnum: true, public: true, label: () => _('Language'), options: () => {
|
'locale': { value: defaultLocale(), type: Setting.TYPE_STRING, isEnum: true, public: true, label: () => _('Language'), options: () => {
|
||||||
return supportedLocalesToLanguages();
|
return supportedLocalesToLanguages();
|
||||||
@ -86,6 +77,15 @@ class Setting extends BaseModel {
|
|||||||
'sync.target': { value: SyncTargetRegistry.nameToId('onedrive'), type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation target'), description: () => _('The target to synchonise to. If synchronising with the file system, set `sync.2.path` to specify the target directory.'), options: () => {
|
'sync.target': { value: SyncTargetRegistry.nameToId('onedrive'), type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation target'), description: () => _('The target to synchonise to. If synchronising with the file system, set `sync.2.path` to specify the target directory.'), options: () => {
|
||||||
return SyncTargetRegistry.idAndLabelPlainObject();
|
return SyncTargetRegistry.idAndLabelPlainObject();
|
||||||
}},
|
}},
|
||||||
|
'sync.2.path': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('filesystem') }, public: true, label: () => _('Directory to synchronise with (absolute path)'), description: () => _('The path to synchronise with when file system synchronisation is enabled. See `sync.target`.') },
|
||||||
|
'sync.3.auth': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
|
'sync.4.auth': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
|
'sync.1.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
|
'sync.2.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
|
'sync.3.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
|
'sync.4.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
|
'sync.5.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
|
'sync.6.context': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.metadata_;
|
return this.metadata_;
|
||||||
|
Loading…
Reference in New Issue
Block a user