mirror of
https://github.com/laurent22/joplin.git
synced 2024-11-27 08:21:03 +02:00
Various bug fixes, optimisations and improvements
This commit is contained in:
parent
81d4810018
commit
76914d6c28
@ -90,8 +90,8 @@ android {
|
|||||||
applicationId "net.cozic.joplin"
|
applicationId "net.cozic.joplin"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 22
|
targetSdkVersion 22
|
||||||
versionCode 32
|
versionCode 33
|
||||||
versionName "0.9.19"
|
versionName "0.9.20"
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", "x86"
|
abiFilters "armeabi-v7a", "x86"
|
||||||
}
|
}
|
||||||
|
@ -279,6 +279,7 @@ const ScreenHeader = connect(
|
|||||||
(state) => {
|
(state) => {
|
||||||
return {
|
return {
|
||||||
historyCanGoBack: state.historyCanGoBack,
|
historyCanGoBack: state.historyCanGoBack,
|
||||||
|
locale: state.settings.locale,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)(ScreenHeaderComponent)
|
)(ScreenHeaderComponent)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { View, Switch, StyleSheet, Picker, Text, Button } from 'react-native';
|
import { View, Switch, Slider, StyleSheet, Picker, Text, Button } from 'react-native';
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { ScreenHeader } from 'lib/components/screen-header.js';
|
import { ScreenHeader } from 'lib/components/screen-header.js';
|
||||||
import { _, setLocale } from 'lib/locale.js';
|
import { _, setLocale } from 'lib/locale.js';
|
||||||
@ -21,10 +21,17 @@ let styles = {
|
|||||||
color: globalStyle.color,
|
color: globalStyle.color,
|
||||||
},
|
},
|
||||||
settingControl: {
|
settingControl: {
|
||||||
//color: globalStyle.color,
|
color: globalStyle.color,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
styles.switchSettingContainer = Object.assign({}, styles.settingContainer);
|
||||||
|
styles.switchSettingContainer.flexDirection = 'row';
|
||||||
|
styles.switchSettingContainer.justifyContent = 'space-between';
|
||||||
|
|
||||||
|
styles.switchSettingControl = Object.assign({}, styles.settingControl);
|
||||||
|
delete styles.switchSettingControl.color;
|
||||||
|
|
||||||
styles = StyleSheet.create(styles);
|
styles = StyleSheet.create(styles);
|
||||||
|
|
||||||
class ConfigScreenComponent extends BaseScreenComponent {
|
class ConfigScreenComponent extends BaseScreenComponent {
|
||||||
@ -82,12 +89,19 @@ class ConfigScreenComponent extends BaseScreenComponent {
|
|||||||
);
|
);
|
||||||
} else if (setting.type == Setting.TYPE_BOOL) {
|
} else if (setting.type == Setting.TYPE_BOOL) {
|
||||||
return (
|
return (
|
||||||
<View key={key} style={styles.settingContainer}>
|
<View key={key} style={styles.switchSettingContainer}>
|
||||||
<Text key="label" style={styles.settingText}>{setting.label()}</Text>
|
<Text key="label" style={styles.settingText}>{setting.label()}</Text>
|
||||||
<Switch key="control" style={styles.settingControl} value={value} onValueChange={(value) => updateSettingValue(key, value)} />
|
<Switch key="control" style={styles.switchSettingControl} value={value} onValueChange={(value) => updateSettingValue(key, value)} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
} else if (setting.type == Setting.TYPE_INT) {
|
||||||
|
return (
|
||||||
|
<View key={key} style={styles.settingContainer}>
|
||||||
|
<Text key="label" style={styles.settingText}>{setting.label()}</Text>
|
||||||
|
<Slider key="control" style={styles.settingControl} value={value} onValueChange={(value) => updateSettingValue(key, value)} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
//throw new Error('Unsupported setting type: ' + setting.type);
|
//throw new Error('Unsupported setting type: ' + setting.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,6 +231,7 @@ const SideMenuContent = connect(
|
|||||||
selectedFolderId: state.selectedFolderId,
|
selectedFolderId: state.selectedFolderId,
|
||||||
selectedTagId: state.selectedTagId,
|
selectedTagId: state.selectedTagId,
|
||||||
notesParentType: state.notesParentType,
|
notesParentType: state.notesParentType,
|
||||||
|
locale: state.settings.locale,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)(SideMenuContentComponent)
|
)(SideMenuContentComponent)
|
||||||
|
@ -147,6 +147,7 @@ class Database {
|
|||||||
}
|
}
|
||||||
if (type == 'fieldType') {
|
if (type == 'fieldType') {
|
||||||
if (s == 'INTEGER') s = 'INT';
|
if (s == 'INTEGER') s = 'INT';
|
||||||
|
if (!(('TYPE_' + s) in this)) throw new Error('Unkonwn fieldType: ' + s);
|
||||||
return this['TYPE_' + s];
|
return this['TYPE_' + s];
|
||||||
}
|
}
|
||||||
if (type == 'syncTarget') {
|
if (type == 'syncTarget') {
|
||||||
@ -238,19 +239,32 @@ class Database {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
alterColumnQueries(tableName, fieldsAfter) {
|
alterColumnQueries(tableName, fields) {
|
||||||
|
let fieldsNoType = [];
|
||||||
|
for (let n in fields) {
|
||||||
|
if (!fields.hasOwnProperty(n)) continue;
|
||||||
|
fieldsNoType.push(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
let fieldsWithType = [];
|
||||||
|
for (let n in fields) {
|
||||||
|
if (!fields.hasOwnProperty(n)) continue;
|
||||||
|
fieldsWithType.push(this.escapeField(n) + ' ' + fields[n]);
|
||||||
|
}
|
||||||
|
|
||||||
let sql = `
|
let sql = `
|
||||||
CREATE TEMPORARY TABLE _BACKUP_TABLE_NAME_(_FIELDS_AFTER_);
|
CREATE TEMPORARY TABLE _BACKUP_TABLE_NAME_(_FIELDS_TYPE_);
|
||||||
INSERT INTO _BACKUP_TABLE_NAME_ SELECT _FIELDS_AFTER_ FROM _TABLE_NAME_;
|
INSERT INTO _BACKUP_TABLE_NAME_ SELECT _FIELDS_NO_TYPE_ FROM _TABLE_NAME_;
|
||||||
DROP TABLE _TABLE_NAME_;
|
DROP TABLE _TABLE_NAME_;
|
||||||
CREATE TABLE _TABLE_NAME_(_FIELDS_AFTER_);
|
CREATE TABLE _TABLE_NAME_(_FIELDS_TYPE_);
|
||||||
INSERT INTO _TABLE_NAME_ SELECT _FIELDS_AFTER_ FROM _BACKUP_TABLE_NAME_;
|
INSERT INTO _TABLE_NAME_ SELECT _FIELDS_NO_TYPE_ FROM _BACKUP_TABLE_NAME_;
|
||||||
DROP TABLE _BACKUP_TABLE_NAME_;
|
DROP TABLE _BACKUP_TABLE_NAME_;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
sql = sql.replace(/_BACKUP_TABLE_NAME_/g, this.escapeField(tableName + '_backup'));
|
sql = sql.replace(/_BACKUP_TABLE_NAME_/g, this.escapeField(tableName + '_backup'));
|
||||||
sql = sql.replace(/_TABLE_NAME_/g, this.escapeField(tableName));
|
sql = sql.replace(/_TABLE_NAME_/g, this.escapeField(tableName));
|
||||||
sql = sql.replace(/_FIELDS_AFTER_/g, this.escapeFields(fieldsAfter).join(','));
|
sql = sql.replace(/_FIELDS_NO_TYPE_/g, this.escapeFields(fieldsNoType).join(','));
|
||||||
|
sql = sql.replace(/_FIELDS_TYPE_/g, fieldsWithType.join(','));
|
||||||
|
|
||||||
return sql.trim().split("\n");
|
return sql.trim().split("\n");
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ class JoplinDatabase extends Database {
|
|||||||
// 1. Add the new version number to the existingDatabaseVersions array
|
// 1. Add the new version number to the existingDatabaseVersions array
|
||||||
// 2. Add the upgrade logic to the "switch (targetVersion)" statement below
|
// 2. Add the upgrade logic to the "switch (targetVersion)" statement below
|
||||||
|
|
||||||
const existingDatabaseVersions = [1, 2, 3];
|
const existingDatabaseVersions = [0, 1, 2, 3];
|
||||||
|
|
||||||
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
|
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
|
||||||
if (currentVersionIndex == existingDatabaseVersions.length - 1) return false;
|
if (currentVersionIndex == existingDatabaseVersions.length - 1) return false;
|
||||||
@ -203,6 +203,10 @@ class JoplinDatabase extends Database {
|
|||||||
this.logger().info("Converting database to version " + targetVersion);
|
this.logger().info("Converting database to version " + targetVersion);
|
||||||
|
|
||||||
let queries = [];
|
let queries = [];
|
||||||
|
|
||||||
|
if (targetVersion == 1) {
|
||||||
|
queries = this.wrapQueries(this.sqlStringToLines(structureSql));
|
||||||
|
}
|
||||||
|
|
||||||
if (targetVersion == 2) {
|
if (targetVersion == 2) {
|
||||||
const newTableSql = `
|
const newTableSql = `
|
||||||
@ -221,7 +225,7 @@ class JoplinDatabase extends Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (targetVersion == 3) {
|
if (targetVersion == 3) {
|
||||||
queries = this.alterColumnQueries('settings', ['key', 'value']);
|
queries = this.alterColumnQueries('settings', { key: 'TEXT PRIMARY KEY', value: 'TEXT' });
|
||||||
}
|
}
|
||||||
|
|
||||||
queries.push({ sql: 'UPDATE version SET version = ?', params: [targetVersion] });
|
queries.push({ sql: 'UPDATE version SET version = ?', params: [targetVersion] });
|
||||||
@ -236,53 +240,32 @@ class JoplinDatabase extends Database {
|
|||||||
async initialize() {
|
async initialize() {
|
||||||
this.logger().info('Checking for database schema update...');
|
this.logger().info('Checking for database schema update...');
|
||||||
|
|
||||||
for (let initLoopCount = 1; initLoopCount <= 2; initLoopCount++) {
|
let versionRow = null;
|
||||||
try {
|
try {
|
||||||
let row = await this.selectOne('SELECT * FROM version LIMIT 1');
|
// Will throw if the database has not been created yet, but this is handled below
|
||||||
let currentVersion = row.version;
|
versionRow = await this.selectOne('SELECT * FROM version LIMIT 1');
|
||||||
this.logger().info('Current database version', currentVersion);
|
} catch (error) {
|
||||||
|
console.info(error);
|
||||||
|
}
|
||||||
|
|
||||||
const upgraded = await this.upgradeDatabase(currentVersion);
|
const version = !versionRow ? 0 : versionRow.version;
|
||||||
if (upgraded) await this.refreshTableFields();
|
this.logger().info('Current database version', version);
|
||||||
} catch (error) {
|
|
||||||
if (error && error.code != 0 && error.code != 'SQLITE_ERROR') throw this.sqliteErrorToJsError(error);
|
|
||||||
|
|
||||||
// Assume that error was:
|
|
||||||
// { message: 'no such table: version (code 1): , while compiling: SELECT * FROM version', code: 0 }
|
|
||||||
// which means the database is empty and the tables need to be created.
|
|
||||||
// If it's any other error there's nothing we can do anyway.
|
|
||||||
|
|
||||||
this.logger().info('Database is new - creating the schema...');
|
const upgraded = await this.upgradeDatabase(version);
|
||||||
|
if (upgraded) await this.refreshTableFields();
|
||||||
|
|
||||||
let queries = this.wrapQueries(this.sqlStringToLines(structureSql));
|
this.tableFields_ = {};
|
||||||
|
|
||||||
try {
|
let rows = await this.selectAll('SELECT * FROM table_fields');
|
||||||
await this.transactionExecBatch(queries);
|
|
||||||
this.logger().info('Database schema created successfully');
|
|
||||||
await this.refreshTableFields();
|
|
||||||
} catch (error) {
|
|
||||||
throw this.sqliteErrorToJsError(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now that the database has been created, go through the normal initialisation process
|
for (let i = 0; i < rows.length; i++) {
|
||||||
continue;
|
let row = rows[i];
|
||||||
}
|
if (!this.tableFields_[row.table_name]) this.tableFields_[row.table_name] = [];
|
||||||
|
this.tableFields_[row.table_name].push({
|
||||||
this.tableFields_ = {};
|
name: row.field_name,
|
||||||
|
type: row.field_type,
|
||||||
let rows = await this.selectAll('SELECT * FROM table_fields');
|
default: Database.formatValue(row.field_type, row.field_default),
|
||||||
|
});
|
||||||
for (let i = 0; i < rows.length; i++) {
|
|
||||||
let row = rows[i];
|
|
||||||
if (!this.tableFields_[row.table_name]) this.tableFields_[row.table_name] = [];
|
|
||||||
this.tableFields_[row.table_name].push({
|
|
||||||
name: row.field_name,
|
|
||||||
type: row.field_type,
|
|
||||||
default: Database.formatValue(row.field_type, row.field_default),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ class Setting extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static load() {
|
static load() {
|
||||||
this.cancelScheduleUpdate();
|
this.cancelScheduleSave();
|
||||||
this.cache_ = [];
|
this.cache_ = [];
|
||||||
return this.modelSelectAll('SELECT * FROM settings').then((rows) => {
|
return this.modelSelectAll('SELECT * FROM settings').then((rows) => {
|
||||||
this.cache_ = rows;
|
this.cache_ = rows;
|
||||||
@ -49,11 +49,25 @@ class Setting extends BaseModel {
|
|||||||
|
|
||||||
if (c.key == 'clientId') continue; // For older clients
|
if (c.key == 'clientId') continue; // For older clients
|
||||||
if (c.key == 'sync.onedrive.auth') continue; // For older clients
|
if (c.key == 'sync.onedrive.auth') continue; // For older clients
|
||||||
|
if (c.key == 'syncInterval') continue; // For older clients
|
||||||
|
|
||||||
|
// console.info(c.key + ' = ' + c.value);
|
||||||
|
|
||||||
c.value = this.formatValue(c.key, c.value);
|
c.value = this.formatValue(c.key, c.value);
|
||||||
|
|
||||||
this.cache_[i] = c;
|
this.cache_[i] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const keys = this.keys();
|
||||||
|
let keyToValues = {};
|
||||||
|
for (let i = 0; i < keys.length; i++) {
|
||||||
|
keyToValues[keys[i]] = this.value(keys[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dispatch({
|
||||||
|
type: 'SETTINGS_UPDATE_ALL',
|
||||||
|
settings: keyToValues,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +95,14 @@ class Setting extends BaseModel {
|
|||||||
this.logger().info('Setting: ' + key + ' = ' + value);
|
this.logger().info('Setting: ' + key + ' = ' + value);
|
||||||
|
|
||||||
c.value = this.formatValue(key, value);
|
c.value = this.formatValue(key, value);
|
||||||
this.scheduleUpdate();
|
|
||||||
|
this.dispatch({
|
||||||
|
type: 'SETTINGS_UPDATE_ONE',
|
||||||
|
key: key,
|
||||||
|
value: c.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.scheduleSave();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,13 +112,30 @@ class Setting extends BaseModel {
|
|||||||
value: this.formatValue(key, value),
|
value: this.formatValue(key, value),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.scheduleUpdate();
|
this.dispatch({
|
||||||
|
type: 'SETTINGS_UPDATE_ONE',
|
||||||
|
key: key,
|
||||||
|
value: this.formatValue(key, value),
|
||||||
|
});
|
||||||
|
|
||||||
|
this.scheduleSave();
|
||||||
|
}
|
||||||
|
|
||||||
|
static valueToString(key, value) {
|
||||||
|
const md = this.settingMetadata(key);
|
||||||
|
value = this.formatValue(key, value);
|
||||||
|
if (md.type == Setting.TYPE_INT) return value.toFixed(0);
|
||||||
|
if (md.type == Setting.TYPE_BOOL) return value ? '1' : '0';
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static formatValue(key, value) {
|
static formatValue(key, value) {
|
||||||
const md = this.settingMetadata(key);
|
const md = this.settingMetadata(key);
|
||||||
if (md.type == Setting.TYPE_INT) return Math.floor(Number(value));
|
if (md.type == Setting.TYPE_INT) return Math.floor(Number(value));
|
||||||
if (md.type == Setting.TYPE_BOOL) return !!value;
|
if (md.type == Setting.TYPE_BOOL) {
|
||||||
|
if (typeof value === 'string') value = Number(value);
|
||||||
|
return !!value;
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,16 +224,18 @@ class Setting extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static saveAll() {
|
static saveAll() {
|
||||||
if (!this.updateTimeoutId_) return Promise.resolve();
|
if (!this.saveTimeoutId_) return Promise.resolve();
|
||||||
|
|
||||||
this.logger().info('Saving settings...');
|
this.logger().info('Saving settings...');
|
||||||
clearTimeout(this.updateTimeoutId_);
|
clearTimeout(this.saveTimeoutId_);
|
||||||
this.updateTimeoutId_ = null;
|
this.saveTimeoutId_ = null;
|
||||||
|
|
||||||
let queries = [];
|
let queries = [];
|
||||||
queries.push('DELETE FROM settings');
|
queries.push('DELETE FROM settings');
|
||||||
for (let i = 0; i < this.cache_.length; i++) {
|
for (let i = 0; i < this.cache_.length; i++) {
|
||||||
queries.push(Database.insertQuery(this.tableName(), this.cache_[i]));
|
let s = Object.assign({}, this.cache_[i]);
|
||||||
|
s.value = this.valueToString(s.key, s.value);
|
||||||
|
queries.push(Database.insertQuery(this.tableName(), s));
|
||||||
}
|
}
|
||||||
|
|
||||||
return BaseModel.db().transactionExecBatch(queries).then(() => {
|
return BaseModel.db().transactionExecBatch(queries).then(() => {
|
||||||
@ -203,17 +243,17 @@ class Setting extends BaseModel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static scheduleUpdate() {
|
static scheduleSave() {
|
||||||
if (this.updateTimeoutId_) clearTimeout(this.updateTimeoutId_);
|
if (this.saveTimeoutId_) clearTimeout(this.saveTimeoutId_);
|
||||||
|
|
||||||
this.updateTimeoutId_ = setTimeout(() => {
|
this.saveTimeoutId_ = setTimeout(() => {
|
||||||
this.saveAll();
|
this.saveAll();
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cancelScheduleUpdate() {
|
static cancelScheduleSave() {
|
||||||
if (this.updateTimeoutId_) clearTimeout(this.updateTimeoutId_);
|
if (this.saveTimeoutId_) clearTimeout(this.saveTimeoutId_);
|
||||||
this.updateTimeoutId_ = null;
|
this.saveTimeoutId_ = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static publicSettings(appType) {
|
static publicSettings(appType) {
|
||||||
@ -264,6 +304,16 @@ Setting.metadata_ = {
|
|||||||
nonCompleted: _('Non-completed ones only'),
|
nonCompleted: _('Non-completed ones only'),
|
||||||
})},
|
})},
|
||||||
'trackLocation': { value: true, type: Setting.TYPE_BOOL, public: true, label: () => _('Save location with notes') },
|
'trackLocation': { value: true, type: Setting.TYPE_BOOL, public: true, label: () => _('Save location with notes') },
|
||||||
|
'sync.interval': { value: 300, type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation interval'), options: () => {
|
||||||
|
return {
|
||||||
|
300: _('%d minutes', 5),
|
||||||
|
600: _('%d minutes', 10),
|
||||||
|
1800: _('%d minutes', 30),
|
||||||
|
3600: _('%d hour', 1),
|
||||||
|
43200: _('%d hour', 12),
|
||||||
|
86400: _('%d hours', 24),
|
||||||
|
};
|
||||||
|
}},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Contains constants that are set by the application and
|
// Contains constants that are set by the application and
|
||||||
|
@ -8,6 +8,7 @@ import { Synchronizer } from 'lib/synchronizer.js';
|
|||||||
import { FileApiDriverOneDrive } from 'lib/file-api-driver-onedrive.js';
|
import { FileApiDriverOneDrive } from 'lib/file-api-driver-onedrive.js';
|
||||||
import { shim } from 'lib/shim.js';
|
import { shim } from 'lib/shim.js';
|
||||||
import { FileApiDriverMemory } from 'lib/file-api-driver-memory.js';
|
import { FileApiDriverMemory } from 'lib/file-api-driver-memory.js';
|
||||||
|
import { PoorManIntervals } from 'lib/poor-man-intervals.js';
|
||||||
|
|
||||||
const reg = {};
|
const reg = {};
|
||||||
|
|
||||||
@ -96,6 +97,14 @@ reg.synchronizer = async (syncTargetId) => {
|
|||||||
return sync;
|
return sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg.syncHasAuth = async (syncTargetId) => {
|
||||||
|
if (syncTargetId == Setting.SYNC_TARGET_ONEDRIVE && !reg.oneDriveApi().auth()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
reg.scheduleSync = async (delay = null) => {
|
reg.scheduleSync = async (delay = null) => {
|
||||||
if (delay === null) delay = 1000 * 10;
|
if (delay === null) delay = 1000 * 10;
|
||||||
|
|
||||||
@ -110,12 +119,14 @@ reg.scheduleSync = async (delay = null) => {
|
|||||||
reg.scheduleSyncId_ = null;
|
reg.scheduleSyncId_ = null;
|
||||||
reg.logger().info('Doing scheduled sync');
|
reg.logger().info('Doing scheduled sync');
|
||||||
|
|
||||||
if (!reg.oneDriveApi().auth()) {
|
const syncTargetId = Setting.value('sync.target');
|
||||||
|
|
||||||
|
if (!reg.syncHasAuth()) {
|
||||||
reg.logger().info('Synchronizer is missing credentials - manual sync required to authenticate.');
|
reg.logger().info('Synchronizer is missing credentials - manual sync required to authenticate.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sync = await reg.synchronizer(Setting.value('sync.target'));
|
const sync = await reg.synchronizer(syncTargetId);
|
||||||
|
|
||||||
let context = Setting.value('sync.context');
|
let context = Setting.value('sync.context');
|
||||||
context = context ? JSON.parse(context) : {};
|
context = context ? JSON.parse(context) : {};
|
||||||
@ -129,6 +140,8 @@ reg.scheduleSync = async (delay = null) => {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg.setupRecurrentSync();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (delay === 0) {
|
if (delay === 0) {
|
||||||
@ -138,6 +151,26 @@ reg.scheduleSync = async (delay = null) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reg.syncStarted = async () => {
|
||||||
|
if (!reg.syncHasAuth()) return false;
|
||||||
|
const sync = await reg.synchronizer(Setting.value('sync.target'));
|
||||||
|
return sync.state() != 'idle';
|
||||||
|
}
|
||||||
|
|
||||||
|
reg.setupRecurrentSync = () => {
|
||||||
|
if (this.recurrentSyncId_) {
|
||||||
|
PoorManIntervals.clearInterval(this.recurrentSyncId_);
|
||||||
|
this.recurrentSyncId_ = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info('Setting up recurrent sync with interval ' + Setting.value('sync.interval'));
|
||||||
|
|
||||||
|
this.recurrentSyncId_ = PoorManIntervals.setInterval(() => {
|
||||||
|
reg.logger().info('Running background sync on timer...');
|
||||||
|
reg.scheduleSync(0);
|
||||||
|
}, 1000 * Setting.value('sync.interval'));
|
||||||
|
}
|
||||||
|
|
||||||
reg.setDb = (v) => {
|
reg.setDb = (v) => {
|
||||||
reg.db_ = v;
|
reg.db_ = v;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ let defaultState = {
|
|||||||
syncStarted: false,
|
syncStarted: false,
|
||||||
syncReport: {},
|
syncReport: {},
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
|
settings: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialRoute = {
|
const initialRoute = {
|
||||||
@ -164,13 +165,7 @@ const reducer = (state = defaultState, action) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
newState.route = action;
|
newState.route = action;
|
||||||
|
|
||||||
newState.historyCanGoBack = !!navHistory.length;
|
newState.historyCanGoBack = !!navHistory.length;
|
||||||
|
|
||||||
if (newState.route.routeName == 'Notes') {
|
|
||||||
Setting.setValue('activeFolderId', newState.selectedFolderId);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Replace all the notes with the provided array
|
// Replace all the notes with the provided array
|
||||||
@ -180,6 +175,20 @@ const reducer = (state = defaultState, action) => {
|
|||||||
newState.loading = false;
|
newState.loading = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'SETTINGS_UPDATE_ALL':
|
||||||
|
|
||||||
|
newState = Object.assign({}, state);
|
||||||
|
newState.settings = action.settings;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'SETTINGS_UPDATE_ONE':
|
||||||
|
|
||||||
|
newState = Object.assign({}, state);
|
||||||
|
let newSettings = Object.assign({}, state.settings);
|
||||||
|
newSettings[action.key] = action.value;
|
||||||
|
newState.settings = newSettings;
|
||||||
|
break;
|
||||||
|
|
||||||
// Replace all the notes with the provided array
|
// Replace all the notes with the provided array
|
||||||
case 'NOTES_UPDATE_ALL':
|
case 'NOTES_UPDATE_ALL':
|
||||||
|
|
||||||
@ -319,23 +328,32 @@ const reducer = (state = defaultState, action) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
error.message = 'In reducer: ' + error.message;
|
error.message = 'In reducer: ' + error.message + ' Action: ' + JSON.stringify(action);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const generalMiddleware = store => next => action => {
|
const generalMiddleware = store => next => async (action) => {
|
||||||
reg.logger().info('Reducer action', action.type);
|
reg.logger().info('Reducer action', action.type);
|
||||||
PoorManIntervals.update(); // This function needs to be called regularly so put it here
|
PoorManIntervals.update(); // This function needs to be called regularly so put it here
|
||||||
|
|
||||||
const result = next(action);
|
const result = next(action);
|
||||||
|
const newState = store.getState();
|
||||||
|
|
||||||
if (action.type == 'NAV_GO') Keyboard.dismiss();
|
if (action.type == 'NAV_GO') Keyboard.dismiss();
|
||||||
|
|
||||||
if (['NOTES_UPDATE_ONE', 'NOTES_DELETE', 'FOLDERS_UPDATE_ONE', 'FOLDER_DELETE'].indexOf(action.type) >= 0) {
|
if (['NOTES_UPDATE_ONE', 'NOTES_DELETE', 'FOLDERS_UPDATE_ONE', 'FOLDER_DELETE'].indexOf(action.type) >= 0) {
|
||||||
reg.scheduleSync();
|
if (!await reg.syncStarted()) reg.scheduleSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.type == 'SETTINGS_UPDATE_ONE' && action.key == 'sync.interval' || action.type == 'SETTINGS_UPDATE_ALL') {
|
||||||
|
reg.setupRecurrentSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.type == 'NAV_GO' && action.routeName == 'Notes') {
|
||||||
|
Setting.setValue('activeFolderId', newState.selectedFolderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -399,8 +417,7 @@ async function initialize(dispatch, backButtonHandler) {
|
|||||||
if (Setting.value('env') == 'prod') {
|
if (Setting.value('env') == 'prod') {
|
||||||
await db.open({ name: 'joplin.sqlite' })
|
await db.open({ name: 'joplin.sqlite' })
|
||||||
} else {
|
} else {
|
||||||
//await db.open({ name: 'joplin-56.sqlite' })
|
await db.open({ name: 'joplin-66.sqlite' })
|
||||||
await db.open({ name: 'joplin-56.sqlite' })
|
|
||||||
|
|
||||||
// await db.exec('DELETE FROM notes');
|
// await db.exec('DELETE FROM notes');
|
||||||
// await db.exec('DELETE FROM folders');
|
// await db.exec('DELETE FROM folders');
|
||||||
@ -465,10 +482,7 @@ async function initialize(dispatch, backButtonHandler) {
|
|||||||
return backButtonHandler();
|
return backButtonHandler();
|
||||||
});
|
});
|
||||||
|
|
||||||
PoorManIntervals.setInterval(() => {
|
reg.setupRecurrentSync();
|
||||||
reg.logger().info('Running background sync on timer...');
|
|
||||||
reg.scheduleSync(0);
|
|
||||||
}, 1000 * 60 * 5);
|
|
||||||
|
|
||||||
if (Setting.value('env') == 'dev') {
|
if (Setting.value('env') == 'dev') {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user