const Setting = require('lib/models/Setting.js'); const SyncTargetRegistry = require('lib/SyncTargetRegistry'); const ObjectUtils = require('lib/ObjectUtils'); const { _ } = require('lib/locale.js'); const { createSelector } = require('reselect'); const { reg } = require('lib/registry'); const shared = {}; shared.init = function(comp) { if (!comp.state) comp.state = {}; comp.state.checkSyncConfigResult = null; comp.state.checkNextcloudAppResult = null; comp.state.settings = {}; comp.state.changedSettingKeys = []; comp.state.showNextcloudAppLog = false; comp.state.showAdvancedSettings = false; }; shared.advancedSettingsButton_click = (comp) => { comp.setState(state => { return { showAdvancedSettings: !state.showAdvancedSettings }; }); }; shared.checkSyncConfig = async function(comp, settings) { const syncTargetId = settings['sync.target']; const SyncTargetClass = SyncTargetRegistry.classById(syncTargetId); const options = Setting.subValues(`sync.${syncTargetId}`, settings); comp.setState({ checkSyncConfigResult: 'checking' }); const result = await SyncTargetClass.checkConfig(ObjectUtils.convertValuesToFunctions(options)); comp.setState({ checkSyncConfigResult: result }); if (result.ok) { await shared.checkNextcloudApp(comp, settings); // Users often expect config to be auto-saved at this point, if the config check was successful shared.saveSettings(comp); } }; shared.checkSyncConfigMessages = function(comp) { const result = comp.state.checkSyncConfigResult; const output = []; if (result === 'checking') { output.push(_('Checking... Please wait.')); } else if (result && result.ok) { output.push(_('Success! Synchronisation configuration appears to be correct.')); } else if (result && !result.ok) { output.push(_('Error. Please check that URL, username, password, etc. are correct and that the sync target is accessible. The reported error was:')); output.push(result.errorMessage); } return output; }; shared.checkNextcloudApp = async function(comp, settings) { if (settings['sync.target'] !== 5) return; comp.setState({ checkNextcloudAppResult: 'checking' }); let result = null; const appApi = await reg.syncTargetNextcloud().appApi(settings); try { result = await appApi.setupSyncTarget(settings['sync.5.path']); } catch (error) { reg.logger().error('Could not setup sync target:', error); result = { error: error.message }; } const newSyncTargets = Object.assign({}, settings['sync.5.syncTargets']); newSyncTargets[settings['sync.5.path']] = result; shared.updateSettingValue(comp, 'sync.5.syncTargets', newSyncTargets); // Also immediately save the result as this is most likely what the user would expect Setting.setValue('sync.5.syncTargets', newSyncTargets); comp.setState({ checkNextcloudAppResult: 'done' }); }; shared.updateSettingValue = function(comp, key, value) { comp.setState(state => { const settings = Object.assign({}, state.settings); const changedSettingKeys = state.changedSettingKeys.slice(); settings[key] = Setting.formatValue(key, value); if (changedSettingKeys.indexOf(key) < 0) changedSettingKeys.push(key); return { settings: settings, changedSettingKeys: changedSettingKeys, }; }); }; shared.saveSettings = function(comp) { for (let key in comp.state.settings) { if (!comp.state.settings.hasOwnProperty(key)) continue; if (comp.state.changedSettingKeys.indexOf(key) < 0) continue; console.info('Saving', key, comp.state.settings[key]); Setting.setValue(key, comp.state.settings[key]); } comp.setState({ changedSettingKeys: [] }); }; shared.settingsToComponents = function(comp, device, settings) { const keys = Setting.keys(true, device); const settingComps = []; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (!Setting.isPublic(key)) continue; const md = Setting.settingMetadata(key); if (md.show && !md.show(settings)) continue; const settingComp = comp.settingToComponent(key, settings[key]); if (!settingComp) continue; settingComps.push(settingComp); } return settingComps; }; const deviceSelector = (state) => state.device; const settingsSelector = (state) => state.settings; shared.settingsSections = createSelector( deviceSelector, settingsSelector, (device, settings) => { const keys = Setting.keys(true, device); const metadatas = []; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (!Setting.isPublic(key)) continue; const md = Setting.settingMetadata(key); if (md.show && !md.show(settings)) continue; metadatas.push(md); } const output = Setting.groupMetadatasBySections(metadatas); output.push({ name: 'encryption', metadatas: [], isScreen: true, }); output.push({ name: 'server', metadatas: [], isScreen: true, }); return output; } ); shared.settingsToComponents2 = function(comp, device, settings, selectedSectionName = '') { const sectionComps = []; const sections = shared.settingsSections({ device, settings }); for (let i = 0; i < sections.length; i++) { const section = sections[i]; const sectionComp = comp.sectionToComponent(section.name, section, settings, selectedSectionName === section.name); if (!sectionComp) continue; sectionComps.push(sectionComp); } return sectionComps; }; module.exports = shared;