1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-03 08:35:29 +02:00
joplin/ReactNativeClient/lib/models/setting.js

272 lines
7.2 KiB
JavaScript
Raw Normal View History

2017-06-24 20:06:28 +02:00
import { BaseModel } from 'lib/base-model.js';
import { Database } from 'lib/database.js';
2017-07-24 23:29:40 +02:00
import { _, supportedLocalesToLanguages, defaultLocale } from 'lib/locale.js';
2017-05-12 22:17:23 +02:00
class Setting extends BaseModel {
static tableName() {
return 'settings';
}
2017-07-03 21:50:45 +02:00
static modelType() {
return BaseModel.TYPE_SETTING;
2017-06-19 21:26:27 +02:00
}
2017-07-24 20:58:11 +02:00
static settingMetadata(key) {
if (!(key in this.metadata_)) throw new Error('Unknown key: ' + key);
let output = Object.assign({}, this.metadata_[key]);
2017-05-12 22:17:23 +02:00
output.key = key;
return output;
}
2017-05-16 23:46:21 +02:00
static keys() {
if (this.keys_) return this.keys_;
this.keys_ = [];
2017-07-24 20:58:11 +02:00
for (let n in this.metadata_) {
if (!this.metadata_.hasOwnProperty(n)) continue;
2017-05-16 23:46:21 +02:00
this.keys_.push(n);
}
return this.keys_;
}
2017-06-27 22:16:03 +02:00
static publicKeys() {
let output = [];
2017-07-24 20:58:11 +02:00
for (let n in this.metadata_) {
if (!this.metadata_.hasOwnProperty(n)) continue;
if (this.metadata_[n].public) output.push(n);
2017-06-27 22:16:03 +02:00
}
return output;
}
2017-05-12 22:17:23 +02:00
static load() {
2017-06-19 21:26:27 +02:00
this.cancelScheduleUpdate();
2017-05-12 22:17:23 +02:00
this.cache_ = [];
2017-06-19 21:26:27 +02:00
return this.modelSelectAll('SELECT * FROM settings').then((rows) => {
2017-06-11 23:11:14 +02:00
this.cache_ = rows;
2017-07-24 22:36:49 +02:00
// TEMPORARY TO CONVERT ALL CLIENT SETTINGS
for (let i = 0; i < this.cache_.length; i++) {
if (this.cache_[i].key == 'sync.target' && this.cache_[i].value == 'onedrive') {
this.cache_[i].value = 3;
}
}
2017-05-12 22:17:23 +02:00
});
}
2017-06-24 20:51:43 +02:00
static setConstant(key, value) {
2017-07-06 23:30:45 +02:00
if (!(key in this.constants_)) throw new Error('Unknown constant key: ' + key);
2017-06-24 20:51:43 +02:00
this.constants_[key] = value;
}
2017-05-12 22:17:23 +02:00
static setValue(key, value) {
2017-06-19 20:58:49 +02:00
if (!this.cache_) throw new Error('Settings have not been initialized!');
2017-05-12 22:17:23 +02:00
for (let i = 0; i < this.cache_.length; i++) {
2017-07-24 20:58:11 +02:00
let c = this.cache_[i];
if (c.key == key) {
const md = this.settingMetadata(key);
if (md.type == 'enum') {
if (!this.isAllowedEnumOption(key, value)) {
throw new Error(_('Invalid option value: "%s". Possible values are: %s.', value, this.enumOptionsDoc(key)));
}
}
if (c.value === value) return;
c.value = value;
2017-05-19 21:12:09 +02:00
this.scheduleUpdate();
2017-05-12 22:17:23 +02:00
return;
}
}
2017-07-24 20:58:11 +02:00
let s = this.settingMetadata(key);
2017-05-12 22:17:23 +02:00
s.value = value;
this.cache_.push(s);
2017-05-19 21:12:09 +02:00
this.scheduleUpdate();
2017-05-12 22:17:23 +02:00
}
2017-07-25 20:57:06 +02:00
static formatValue(type, value) {
if (type == 'int') return Math.floor(Number(value));
return value;
}
2017-05-12 22:17:23 +02:00
static value(key) {
if (key in this.constants_) {
let output = this.constants_[key];
if (output == 'SET_ME') throw new Error('Setting constant has not been set: ' + key);
return output;
}
2017-06-24 20:51:43 +02:00
2017-06-19 20:58:49 +02:00
if (!this.cache_) throw new Error('Settings have not been initialized!');
2017-07-25 20:57:06 +02:00
const md = this.settingMetadata(key);
2017-05-12 22:17:23 +02:00
for (let i = 0; i < this.cache_.length; i++) {
if (this.cache_[i].key == key) {
2017-07-25 20:57:06 +02:00
return this.formatValue(md.type, this.cache_[i].value);
2017-05-12 22:17:23 +02:00
}
}
2017-07-25 20:57:06 +02:00
return this.formatValue(md.type, md.value);
2017-05-12 22:17:23 +02:00
}
2017-07-24 20:58:11 +02:00
static isEnum(key) {
const md = this.settingMetadata(key);
return md.type == 'enum';
}
static enumOptionValues(key) {
const options = this.enumOptions(key);
let output = [];
for (let n in options) {
if (!options.hasOwnProperty(n)) continue;
output.push(n);
}
return output;
}
static enumOptionLabel(key, value) {
const options = this.enumOptions(key);
for (let n in options) {
if (n == value) return options[n];
}
return '';
}
static enumOptions(key) {
if (!this.metadata_[key]) throw new Error('Unknown key: ' + key);
if (!this.metadata_[key].options) throw new Error('No options for: ' + key);
return this.metadata_[key].options();
}
static enumOptionsDoc(key) {
const options = this.enumOptions(key);
let output = [];
for (let n in options) {
if (!options.hasOwnProperty(n)) continue;
output.push(_('%s (%s)', n, options[n]));
}
return output.join(', ');
}
static isAllowedEnumOption(key, value) {
const options = this.enumOptions(key);
return !!options[value];
}
2017-05-16 23:46:21 +02:00
// Currently only supports objects with properties one level deep
static object(key) {
let output = {};
let keys = this.keys();
for (let i = 0; i < keys.length; i++) {
let k = keys[i].split('.');
if (k[0] == key) {
output[k[1]] = this.value(keys[i]);
}
}
return output;
}
// Currently only supports objects with properties one level deep
static setObject(key, object) {
for (let n in object) {
if (!object.hasOwnProperty(n)) continue;
this.setValue(key + '.' + n, object[n]);
}
}
2017-05-19 21:12:09 +02:00
static saveAll() {
if (!this.updateTimeoutId_) return Promise.resolve();
2017-06-25 12:41:03 +02:00
this.logger().info('Saving settings...');
2017-05-19 21:12:09 +02:00
clearTimeout(this.updateTimeoutId_);
this.updateTimeoutId_ = null;
2017-06-11 23:11:14 +02:00
let queries = [];
queries.push('DELETE FROM settings');
for (let i = 0; i < this.cache_.length; i++) {
2017-06-27 22:58:27 +02:00
let s = Object.assign({}, this.cache_[i]);
delete s.public;
2017-07-23 20:26:50 +02:00
delete s.appTypes;
delete s.label;
delete s.options;
2017-07-25 20:57:06 +02:00
s.value = this.formatValue(s.type, s.value);
2017-06-27 22:58:27 +02:00
queries.push(Database.insertQuery(this.tableName(), s));
2017-06-11 23:11:14 +02:00
}
return BaseModel.db().transactionExecBatch(queries).then(() => {
2017-06-25 12:41:03 +02:00
this.logger().info('Settings have been saved.');
2017-05-19 21:12:09 +02:00
});
}
2017-05-12 22:17:23 +02:00
static scheduleUpdate() {
2017-05-19 21:12:09 +02:00
if (this.updateTimeoutId_) clearTimeout(this.updateTimeoutId_);
this.updateTimeoutId_ = setTimeout(() => {
this.saveAll();
2017-05-12 22:17:23 +02:00
}, 500);
}
2017-06-19 21:26:27 +02:00
static cancelScheduleUpdate() {
if (this.updateTimeoutId_) clearTimeout(this.updateTimeoutId_);
this.updateTimeoutId_ = null;
}
2017-07-23 20:26:50 +02:00
static publicSettings(appType) {
if (!appType) throw new Error('appType is required');
let output = {};
2017-07-24 20:58:11 +02:00
for (let key in Setting.metadata_) {
if (!Setting.metadata_.hasOwnProperty(key)) continue;
let s = Object.assign({}, Setting.metadata_[key]);
2017-07-23 20:26:50 +02:00
if (!s.public) continue;
if (s.appTypes && s.appTypes.indexOf(appType) < 0) continue;
s.value = this.value(key);
output[key] = s;
}
return output;
}
2017-05-12 22:17:23 +02:00
}
2017-07-24 20:58:11 +02:00
Setting.SYNC_TARGET_MEMORY = 1;
Setting.SYNC_TARGET_FILESYSTEM = 2;
Setting.SYNC_TARGET_ONEDRIVE = 3;
Setting.metadata_ = {
2017-06-27 22:16:03 +02:00
'activeFolderId': { value: '', type: 'string', public: false },
2017-07-25 20:57:06 +02:00
'firstStart': { value: 1, type: 'int', public: false },
2017-07-24 20:58:11 +02:00
'sync.2.path': { value: '', type: 'string', public: true, appTypes: ['cli'] },
'sync.3.auth': { value: '', type: 'string', public: false },
2017-07-24 22:36:49 +02:00
'sync.target': { value: Setting.SYNC_TARGET_ONEDRIVE, type: 'enum', public: true, label: () => _('Synchronisation target'), options: () => {
2017-07-24 20:58:11 +02:00
let output = {};
output[Setting.SYNC_TARGET_MEMORY] = 'Memory';
output[Setting.SYNC_TARGET_FILESYSTEM] = _('File system');
output[Setting.SYNC_TARGET_ONEDRIVE] = _('OneDrive');
return output;
}},
2017-07-18 21:57:49 +02:00
'sync.context': { value: '', type: 'string', public: false },
2017-07-23 20:26:50 +02:00
'editor': { value: '', type: 'string', public: true, appTypes: ['cli'] },
2017-07-24 23:29:40 +02:00
'locale': { value: defaultLocale(), type: 'enum', public: true, label: () => _('Language'), options: () => {
return supportedLocalesToLanguages();
}},
2017-07-23 20:26:50 +02:00
'todoFilter': { value: 'all', type: 'enum', public: true, appTypes: ['mobile'], label: () => _('Todo filter'), options: () => ({
all: _('Show all'),
recent: _('Non-completed and recently completed ones'),
nonCompleted: _('Non-completed ones only'),
})},
2017-06-06 22:01:43 +02:00
};
2017-06-24 20:51:43 +02:00
// Contains constants that are set by the application and
// cannot be modified by the user:
Setting.constants_ = {
2017-07-08 00:25:03 +02:00
'env': 'SET_ME',
2017-06-24 20:51:43 +02:00
'appName': 'joplin',
2017-06-29 22:52:52 +02:00
'appId': 'SET_ME', // Each app should set this identifier
'appType': 'SET_ME', // 'cli' or 'mobile'
2017-07-06 23:30:45 +02:00
'resourceDir': '',
'profileDir': '',
2017-07-10 22:03:46 +02:00
'tempDir': '',
2017-06-24 20:51:43 +02:00
}
2017-05-12 22:17:23 +02:00
export { Setting };