1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-09-16 08:56:40 +02:00

Handle user timestamp

This commit is contained in:
Laurent Cozic
2017-08-20 22:11:32 +02:00
parent 671e8a3fc8
commit 36743bb4d7
14 changed files with 95 additions and 14 deletions

View File

@@ -321,6 +321,14 @@ msgid ""
"will be shared with any third party." "will be shared with any third party."
msgstr "" msgstr ""
#, javascript-format
msgid "Unknown log level: %s"
msgstr ""
#, javascript-format
msgid "Unknown level ID: %s"
msgstr ""
msgid "" msgid ""
"Cannot refresh token: authentication data is missing. Starting the " "Cannot refresh token: authentication data is missing. Starting the "
"synchronisation again may fix the problem." "synchronisation again may fix the problem."

View File

@@ -364,6 +364,14 @@ msgid ""
"will be shared with any third party." "will be shared with any third party."
msgstr "" msgstr ""
#, fuzzy, javascript-format
msgid "Unknown log level: %s"
msgstr "Paramètre inconnu : %s"
#, fuzzy, javascript-format
msgid "Unknown level ID: %s"
msgstr "Paramètre inconnu : %s"
msgid "" msgid ""
"Cannot refresh token: authentication data is missing. Starting the " "Cannot refresh token: authentication data is missing. Starting the "
"synchronisation again may fix the problem." "synchronisation again may fix the problem."

View File

@@ -321,6 +321,14 @@ msgid ""
"will be shared with any third party." "will be shared with any third party."
msgstr "" msgstr ""
#, javascript-format
msgid "Unknown log level: %s"
msgstr ""
#, javascript-format
msgid "Unknown level ID: %s"
msgstr ""
msgid "" msgid ""
"Cannot refresh token: authentication data is missing. Starting the " "Cannot refresh token: authentication data is missing. Starting the "
"synchronisation again may fix the problem." "synchronisation again may fix the problem."

View File

@@ -7,7 +7,7 @@
"url": "https://github.com/laurent22/joplin" "url": "https://github.com/laurent22/joplin"
}, },
"url": "git://github.com/laurent22/joplin.git", "url": "git://github.com/laurent22/joplin.git",
"version": "0.9.7", "version": "0.9.8",
"bin": { "bin": {
"joplin": "./main.js" "joplin": "./main.js"
}, },

View File

@@ -1 +1 @@
bd9c058875b3fa6fb7091aa9f3ee0e74 28897a284082f5be431a27ee5b1a26cb

View File

@@ -217,8 +217,14 @@ class BaseModel {
let query = {}; let query = {};
let modelId = o.id; let modelId = o.id;
const timeNow = time.unixMs();
if (options.autoTimestamp && this.hasField('updated_time')) { if (options.autoTimestamp && this.hasField('updated_time')) {
o.updated_time = time.unixMs(); o.updated_time = timeNow;
}
if (options.autoTimestamp && this.hasField('user_updated_time')) {
o.user_updated_time = timeNow;
} }
if (options.isNew) { if (options.isNew) {
@@ -228,7 +234,11 @@ class BaseModel {
} }
if (!o.created_time && this.hasField('created_time')) { if (!o.created_time && this.hasField('created_time')) {
o.created_time = time.unixMs(); o.created_time = timeNow;
}
if (!o.user_created_time && this.hasField('user_created_time')) {
o.user_created_time = timeNow;
} }
query = Database.insertQuery(this.tableName(), o); query = Database.insertQuery(this.tableName(), o);
@@ -266,6 +276,8 @@ class BaseModel {
o.id = modelId; o.id = modelId;
if ('updated_time' in saveQuery.modObject) o.updated_time = saveQuery.modObject.updated_time; if ('updated_time' in saveQuery.modObject) o.updated_time = saveQuery.modObject.updated_time;
if ('created_time' in saveQuery.modObject) o.created_time = saveQuery.modObject.created_time; if ('created_time' in saveQuery.modObject) o.created_time = saveQuery.modObject.created_time;
if ('user_updated_time' in saveQuery.modObject) o.user_updated_time = saveQuery.modObject.user_updated_time;
if ('user_created_time' in saveQuery.modObject) o.user_created_time = saveQuery.modObject.user_created_time;
o = this.addModelMd(o); o = this.addModelMd(o);
return this.filter(o); return this.filter(o);
}).catch((error) => { }).catch((error) => {

View File

@@ -61,7 +61,7 @@ class NoteListComponent extends Component {
for (let i = 0; i < notes.length; i++) { for (let i = 0; i < notes.length; i++) {
const note = notes[i]; const note = notes[i];
if (note.is_todo) { if (note.is_todo) {
if (todoFilter == 'recent' && note.updated_time < notRecentTime && !!note.todo_completed) continue; if (todoFilter == 'recent' && note.user_updated_time < notRecentTime && !!note.todo_completed) continue;
if (todoFilter == 'nonCompleted' && !!note.todo_completed) continue; if (todoFilter == 'nonCompleted' && !!note.todo_completed) continue;
} }
output.push(note); output.push(note);

View File

@@ -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 = [0, 1, 2, 3, 4]; const existingDatabaseVersions = [0, 1, 2, 3, 4, 5];
let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion); let currentVersionIndex = existingDatabaseVersions.indexOf(fromVersion);
if (currentVersionIndex == existingDatabaseVersions.length - 1) return false; if (currentVersionIndex == existingDatabaseVersions.length - 1) return false;
@@ -233,6 +233,18 @@ class JoplinDatabase extends Database {
queries.push('DELETE FROM settings WHERE `key` = "sync.context"'); queries.push('DELETE FROM settings WHERE `key` = "sync.context"');
} }
if (targetVersion == 5) {
const tableNames = ['notes', 'folders', 'tags', 'note_tags', 'resources'];
for (let i = 0; i < tableNames.length; i++) {
const n = tableNames[i];
queries.push('ALTER TABLE ' + n + ' ADD COLUMN user_created_time INT NOT NULL DEFAULT 0');
queries.push('ALTER TABLE ' + n + ' ADD COLUMN user_updated_time INT NOT NULL DEFAULT 0');
queries.push('UPDATE ' + n + ' SET user_created_time = created_time');
queries.push('UPDATE ' + n + ' SET user_updated_time = updated_time');
queries.push('CREATE INDEX ' + n + '_user_updated_time ON ' + n + ' (user_updated_time)');
}
}
queries.push({ sql: 'UPDATE version SET version = ?', params: [targetVersion] }); queries.push({ sql: 'UPDATE version SET version = ?', params: [targetVersion] });
await this.transactionExecBatch(queries); await this.transactionExecBatch(queries);

View File

@@ -144,7 +144,29 @@ class Logger {
if (s == 'warn') return Logger.LEVEL_WARN; if (s == 'warn') return Logger.LEVEL_WARN;
if (s == 'info') return Logger.LEVEL_INFO; if (s == 'info') return Logger.LEVEL_INFO;
if (s == 'debug') return Logger.LEVEL_DEBUG; if (s == 'debug') return Logger.LEVEL_DEBUG;
throw new Error('Unknown log level: %s', s); throw new Error(_('Unknown log level: %s', s));
}
static levelIdToString(id) {
if (id == Logger.LEVEL_NONE) return 'none';
if (id == Logger.LEVEL_ERROR) return 'error';
if (id == Logger.LEVEL_WARN) return 'warn';
if (id == Logger.LEVEL_INFO) return 'info';
if (id == Logger.LEVEL_DEBUG) return 'debug';
throw new Error(_('Unknown level ID: %s', id));
}
static levelIds() {
return [Logger.LEVEL_NONE, Logger.LEVEL_ERROR, Logger.LEVEL_WARN, Logger.LEVEL_INFO, Logger.LEVEL_DEBUG];
}
static levelEnum() {
let output = {};
const ids = this.levelIds();
for (let i = 0; i < ids.length; i++) {
output[ids[i]] = this.levelIdToString(ids[i]);
}
return output;
} }
} }

View File

@@ -180,7 +180,7 @@ class BaseItem extends BaseModel {
} }
static serialize_format(propName, propValue) { static serialize_format(propName, propValue) {
if (['created_time', 'updated_time', 'sync_time'].indexOf(propName) >= 0) { if (['created_time', 'updated_time', 'sync_time', 'user_updated_time', 'user_created_time'].indexOf(propName) >= 0) {
if (!propValue) return ''; if (!propValue) return '';
propValue = moment.unix(propValue / 1000).utc().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z'; propValue = moment.unix(propValue / 1000).utc().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z';
} else if (propValue === null || propValue === undefined) { } else if (propValue === null || propValue === undefined) {
@@ -195,7 +195,7 @@ class BaseItem extends BaseModel {
let ItemClass = this.itemClass(type); let ItemClass = this.itemClass(type);
if (['created_time', 'updated_time'].indexOf(propName) >= 0) { if (['created_time', 'updated_time', 'user_created_time', 'user_updated_time'].indexOf(propName) >= 0) {
if (!propValue) return 0; if (!propValue) return 0;
propValue = moment(propValue, 'YYYY-MM-DDTHH:mm:ss.SSSZ').format('x'); propValue = moment(propValue, 'YYYY-MM-DDTHH:mm:ss.SSSZ').format('x');
} else { } else {

View File

@@ -91,6 +91,7 @@ class Folder extends BaseItem {
id: this.conflictFolderId(), id: this.conflictFolderId(),
title: this.conflictFolderTitle(), title: this.conflictFolderTitle(),
updated_time: time.unixMs(), updated_time: time.unixMs(),
user_updated_time: time.unixMs(),
}; };
} }

View File

@@ -95,7 +95,7 @@ class Note extends BaseItem {
} }
static previewFields() { static previewFields() {
return ['id', 'title', 'body', 'is_todo', 'todo_completed', 'parent_id', 'updated_time']; return ['id', 'title', 'body', 'is_todo', 'todo_completed', 'parent_id', 'updated_time', 'user_updated_time'];
} }
static previewFieldsSql() { static previewFieldsSql() {
@@ -122,7 +122,7 @@ class Note extends BaseItem {
// is used to sort already loaded notes. // is used to sort already loaded notes.
if (!options) options = {}; if (!options) options = {};
if (!options.order) options.order = [{ by: 'updated_time', dir: 'DESC' }]; if (!options.order) options.order = [{ by: 'user_updated_time', dir: 'DESC' }];
if (!options.conditions) options.conditions = []; if (!options.conditions) options.conditions = [];
if (!options.conditionsParams) options.conditionsParams = []; if (!options.conditionsParams) options.conditionsParams = [];
if (!options.fields) options.fields = this.previewFields(); if (!options.fields) options.fields = this.previewFields();
@@ -269,11 +269,17 @@ class Note extends BaseItem {
static async moveToFolder(noteId, folderId) { static async moveToFolder(noteId, folderId) {
if (folderId == Folder.conflictFolderId()) throw new Error(_('Cannot move note to "%s" notebook', Folder.conflictFolderIdTitle())); if (folderId == Folder.conflictFolderId()) throw new Error(_('Cannot move note to "%s" notebook', Folder.conflictFolderIdTitle()));
return Note.save({ // When moving a note to a different folder, the user timestamp is not updated.
// However updated_time is updated so that the note can be synced later on.
const modifiedNote = {
id: noteId, id: noteId,
parent_id: folderId, parent_id: folderId,
is_conflict: 0, is_conflict: 0,
}); updated_time: time.unixMs(),
};
return Note.save(modifiedNote, { autoTimestamp: false });
} }
static toggleIsTodo(note) { static toggleIsTodo(note) {

View File

@@ -1,5 +1,6 @@
import { BaseModel } from 'lib/base-model.js'; import { BaseModel } from 'lib/base-model.js';
import { Database } from 'lib/database.js'; import { Database } from 'lib/database.js';
import { Logger } from 'lib/logger.js';
import { _, supportedLocalesToLanguages, defaultLocale } from 'lib/locale.js'; import { _, supportedLocalesToLanguages, defaultLocale } from 'lib/locale.js';
class Setting extends BaseModel { class Setting extends BaseModel {
@@ -318,6 +319,9 @@ Setting.metadata_ = {
'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();
}}, }},
// 'logLevel': { value: Logger.LEVEL_INFO, type: Setting.TYPE_STRING, isEnum: true, public: true, label: () => _('Log level'), options: () => {
// return Logger.levelEnum();
// }},
// Not used for now: // Not used for now:
'todoFilter': { value: 'all', type: Setting.TYPE_STRING, isEnum: true, public: false, appTypes: ['mobile'], label: () => _('Todo filter'), options: () => ({ 'todoFilter': { value: 'all', type: Setting.TYPE_STRING, isEnum: true, public: false, appTypes: ['mobile'], label: () => _('Todo filter'), options: () => ({
all: _('Show all'), all: _('Show all'),

View File

@@ -49,7 +49,7 @@ let defaultState = {
screens: {}, screens: {},
historyCanGoBack: false, historyCanGoBack: false,
notesOrder: [ notesOrder: [
{ by: 'updated_time', dir: 'DESC' }, { by: 'user_updated_time', dir: 'DESC' },
], ],
syncStarted: false, syncStarted: false,
syncReport: {}, syncReport: {},