2017-06-24 20:06:28 +02:00
|
|
|
import { BaseModel } from 'lib/base-model.js';
|
|
|
|
import { Log } from 'lib/log.js';
|
|
|
|
import { Folder } from 'lib/models/folder.js';
|
|
|
|
import { BaseItem } from 'lib/models/base-item.js';
|
2017-06-29 22:52:52 +02:00
|
|
|
import { Setting } from 'lib/models/setting.js';
|
2017-07-10 20:09:58 +02:00
|
|
|
import { shim } from 'lib/shim.js';
|
2017-06-11 23:11:14 +02:00
|
|
|
import moment from 'moment';
|
2017-06-29 22:52:52 +02:00
|
|
|
import lodash from 'lodash';
|
2017-05-10 21:21:09 +02:00
|
|
|
|
2017-06-15 20:18:48 +02:00
|
|
|
class Note extends BaseItem {
|
2017-05-10 21:21:09 +02:00
|
|
|
|
2017-05-10 21:51:43 +02:00
|
|
|
static tableName() {
|
|
|
|
return 'notes';
|
|
|
|
}
|
|
|
|
|
2017-07-02 17:46:03 +02:00
|
|
|
static async serialize(note, type = null, shownKeys = null) {
|
2017-06-29 22:52:52 +02:00
|
|
|
let fieldNames = this.fieldNames();
|
|
|
|
fieldNames.push('type_');
|
2017-07-02 14:02:07 +02:00
|
|
|
lodash.pull(fieldNames, 'is_conflict', 'sync_time', 'body'); // Exclude 'body' since it's going to be added separately at the top of the note
|
2017-06-29 22:52:52 +02:00
|
|
|
return super.serialize(note, 'note', fieldNames);
|
2017-05-12 21:54:06 +02:00
|
|
|
}
|
|
|
|
|
2017-07-04 21:12:30 +02:00
|
|
|
static async serializeForEdit(note) {
|
|
|
|
return super.serialize(note, 'note', []);
|
|
|
|
}
|
|
|
|
|
2017-07-05 20:31:11 +02:00
|
|
|
static async unserializeForEdit(content) {
|
|
|
|
content += "\n\ntype_: " + BaseModel.TYPE_NOTE;
|
|
|
|
return super.unserialize(content);
|
|
|
|
}
|
|
|
|
|
2017-07-03 21:50:45 +02:00
|
|
|
static modelType() {
|
|
|
|
return BaseModel.TYPE_NOTE;
|
2017-05-18 21:58:01 +02:00
|
|
|
}
|
|
|
|
|
2017-05-20 00:16:50 +02:00
|
|
|
static new(parentId = '') {
|
|
|
|
let output = super.new();
|
|
|
|
output.parent_id = parentId;
|
|
|
|
return output;
|
2017-05-10 21:51:43 +02:00
|
|
|
}
|
|
|
|
|
2017-05-24 22:51:50 +02:00
|
|
|
static newTodo(parentId = '') {
|
|
|
|
let output = this.new(parentId);
|
|
|
|
output.is_todo = true;
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2017-06-25 14:49:46 +02:00
|
|
|
static previewFields() {
|
|
|
|
return ['id', 'title', 'body', 'is_todo', 'todo_completed', 'parent_id', 'updated_time'];
|
|
|
|
}
|
|
|
|
|
2017-05-24 23:09:58 +02:00
|
|
|
static previewFieldsSql() {
|
2017-06-25 14:49:46 +02:00
|
|
|
return this.db().escapeFields(this.previewFields()).join(',');
|
2017-05-24 23:09:58 +02:00
|
|
|
}
|
|
|
|
|
2017-06-27 21:48:01 +02:00
|
|
|
static loadFolderNoteByField(folderId, field, value) {
|
|
|
|
return this.modelSelectOne('SELECT * FROM notes WHERE is_conflict = 0 AND `parent_id` = ? AND `' + field + '` = ?', [folderId, value]);
|
|
|
|
}
|
|
|
|
|
2017-06-25 11:00:54 +02:00
|
|
|
static previews(parentId, options = null) {
|
|
|
|
if (!options) options = {};
|
|
|
|
if (!options.orderBy) options.orderBy = 'updated_time';
|
|
|
|
if (!options.orderByDir) options.orderByDir = 'DESC';
|
2017-07-03 20:58:01 +02:00
|
|
|
if (!options.conditions) options.conditions = [];
|
|
|
|
if (!options.conditionsParams) options.conditionsParams = [];
|
|
|
|
if (!options.fields) options.fields = this.previewFields();
|
|
|
|
|
|
|
|
options.conditions.push('is_conflict = 0');
|
|
|
|
|
|
|
|
options.conditions.push('parent_id = ?');
|
|
|
|
options.conditionsParams.push(parentId);
|
2017-06-25 11:00:54 +02:00
|
|
|
|
|
|
|
if (options.itemTypes && options.itemTypes.length) {
|
|
|
|
if (options.itemTypes.indexOf('note') >= 0 && options.itemTypes.indexOf('todo') >= 0) {
|
|
|
|
// Fetch everything
|
|
|
|
} else if (options.itemTypes.indexOf('note') >= 0) {
|
2017-07-03 20:58:01 +02:00
|
|
|
options.conditions.push('is_todo = 0');
|
2017-06-25 11:00:54 +02:00
|
|
|
} else if (options.itemTypes.indexOf('todo') >= 0) {
|
2017-07-03 20:58:01 +02:00
|
|
|
options.conditions.push('is_todo = 1');
|
2017-06-25 11:00:54 +02:00
|
|
|
}
|
|
|
|
}
|
2017-06-25 14:49:46 +02:00
|
|
|
|
2017-07-03 20:58:01 +02:00
|
|
|
return this.search(options);
|
2017-05-11 22:14:01 +02:00
|
|
|
}
|
|
|
|
|
2017-05-24 23:09:58 +02:00
|
|
|
static preview(noteId) {
|
2017-06-23 23:32:24 +02:00
|
|
|
return this.modelSelectOne('SELECT ' + this.previewFieldsSql() + ' FROM notes WHERE is_conflict = 0 AND id = ?', [noteId]);
|
2017-06-20 21:18:19 +02:00
|
|
|
}
|
|
|
|
|
2017-06-20 21:25:01 +02:00
|
|
|
static conflictedNotes() {
|
2017-06-20 21:18:19 +02:00
|
|
|
return this.modelSelectAll('SELECT * FROM notes WHERE is_conflict = 1');
|
2017-05-24 23:09:58 +02:00
|
|
|
}
|
|
|
|
|
2017-07-02 23:01:37 +02:00
|
|
|
static unconflictedNotes() {
|
|
|
|
return this.modelSelectAll('SELECT * FROM notes WHERE is_conflict = 0');
|
|
|
|
}
|
|
|
|
|
2017-05-23 21:01:37 +02:00
|
|
|
static updateGeolocation(noteId) {
|
2017-07-10 20:09:58 +02:00
|
|
|
this.logger().info('Updating lat/long of note ' + noteId);
|
2017-05-15 21:46:34 +02:00
|
|
|
|
2017-05-23 21:01:37 +02:00
|
|
|
let geoData = null;
|
2017-07-10 20:09:58 +02:00
|
|
|
return shim.Geolocation.currentPosition().then((data) => {
|
|
|
|
this.logger().info('Got lat/long');
|
2017-05-23 21:01:37 +02:00
|
|
|
geoData = data;
|
|
|
|
return Note.load(noteId);
|
|
|
|
}).then((note) => {
|
2017-05-23 21:58:12 +02:00
|
|
|
if (!note) return; // Race condition - note has been deleted in the meantime
|
2017-05-23 21:01:37 +02:00
|
|
|
note.longitude = geoData.coords.longitude;
|
|
|
|
note.latitude = geoData.coords.latitude;
|
|
|
|
note.altitude = geoData.coords.altitude;
|
|
|
|
return Note.save(note);
|
|
|
|
}).catch((error) => {
|
2017-07-10 20:09:58 +02:00
|
|
|
this.logger().warn('Cannot get location:', error);
|
2017-05-23 21:01:37 +02:00
|
|
|
});
|
2017-05-15 21:46:34 +02:00
|
|
|
}
|
|
|
|
|
2017-06-24 19:40:03 +02:00
|
|
|
static filter(note) {
|
|
|
|
if (!note) return note;
|
|
|
|
|
2017-06-27 01:20:01 +02:00
|
|
|
let output = super.filter(note);
|
2017-06-24 19:40:03 +02:00
|
|
|
if ('longitude' in output) output.longitude = Number(!output.longitude ? 0 : output.longitude).toFixed(8);
|
|
|
|
if ('latitude' in output) output.latitude = Number(!output.latitude ? 0 : output.latitude).toFixed(8);
|
|
|
|
if ('altitude' in output) output.altitude = Number(!output.altitude ? 0 : output.altitude).toFixed(4);
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2017-05-22 22:22:50 +02:00
|
|
|
static save(o, options = null) {
|
2017-06-29 22:52:52 +02:00
|
|
|
let isNew = this.isNew(o, options);
|
|
|
|
if (isNew && !o.source) o.source = Setting.value('appName');
|
|
|
|
if (isNew && !o.source_application) o.source_application = Setting.value('appId');
|
|
|
|
|
2017-05-24 23:09:58 +02:00
|
|
|
return super.save(o, options).then((result) => {
|
|
|
|
// 'result' could be a partial one at this point (if, for example, only one property of it was saved)
|
|
|
|
// so call this.preview() so that the right fields are populated.
|
2017-06-14 21:59:46 +02:00
|
|
|
return this.load(result.id);
|
2017-05-24 23:09:58 +02:00
|
|
|
}).then((note) => {
|
2017-05-22 22:22:50 +02:00
|
|
|
this.dispatch({
|
|
|
|
type: 'NOTES_UPDATE_ONE',
|
|
|
|
note: note,
|
|
|
|
});
|
|
|
|
return note;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-05-10 21:21:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export { Note };
|