Add better offline sync support
This commit is contained in:
parent
3050862c7f
commit
022ff4d113
@ -31,6 +31,8 @@
|
|||||||
<script src="node_modules/easymde/dist/easymde.min.js"></script>
|
<script src="node_modules/easymde/dist/easymde.min.js"></script>
|
||||||
<script src="node_modules/shufflejs/dist/shuffle.min.js"></script>
|
<script src="node_modules/shufflejs/dist/shuffle.min.js"></script>
|
||||||
|
|
||||||
|
<script src="js/delta.js"></script>
|
||||||
|
|
||||||
<script src="js/Notes.class.js"></script>
|
<script src="js/Notes.class.js"></script>
|
||||||
<script src="js/NotePostNotes.class.js"></script>
|
<script src="js/NotePostNotes.class.js"></script>
|
||||||
<script src="js/notes.js"></script>
|
<script src="js/notes.js"></script>
|
||||||
|
@ -13,10 +13,10 @@ class NotePostNotes extends Notes {
|
|||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
del(noteid, callback) {
|
del(noteid, success, error) {
|
||||||
super.del(noteid);
|
super.del(noteid);
|
||||||
var self = this;
|
var self = this;
|
||||||
$.ajax({
|
return $.ajax({
|
||||||
url: this.server + "/api/deletenote",
|
url: this.server + "/api/deletenote",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
cache: false,
|
cache: false,
|
||||||
@ -30,25 +30,98 @@ class NotePostNotes extends Notes {
|
|||||||
if (val.status == "OK") {
|
if (val.status == "OK") {
|
||||||
self.notes = val.notes;
|
self.notes = val.notes;
|
||||||
}
|
}
|
||||||
if (typeof callback == 'function') {
|
if (typeof success == 'function') {
|
||||||
callback();
|
success();
|
||||||
|
}
|
||||||
|
}, error: function () {
|
||||||
|
if (typeof error == 'function') {
|
||||||
|
error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add(note, callback) {
|
add(note, success, error) {
|
||||||
note.norealid = true;
|
note.norealid = true;
|
||||||
super.add(note, callback);
|
this.saveNote(note, success, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
fix(note) {
|
getNote(noteid, success, error) {
|
||||||
super.fix(note);
|
return $.ajax({
|
||||||
note.id = note.noteid;
|
url: this.server + "/api/getnote",
|
||||||
this.set(note);
|
dataType: "json",
|
||||||
|
method: "POST",
|
||||||
|
data: {
|
||||||
|
id: noteid
|
||||||
|
},
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
|
||||||
|
}, success: function (val) {
|
||||||
|
if (val.status == "OK") {
|
||||||
|
if (typeof success == 'function') {
|
||||||
|
success(val.note);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (typeof error == 'function') {
|
||||||
|
error(val.msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, error: function () {
|
||||||
|
if (typeof error == 'function') {
|
||||||
|
error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
load(callback) {
|
saveNote(note, success, error) {
|
||||||
|
var self = this;
|
||||||
|
var data = {
|
||||||
|
text: note.content,
|
||||||
|
color: note.color,
|
||||||
|
modified: note.modified,
|
||||||
|
favorite: (note.favorite ? "1" : "0")
|
||||||
|
};
|
||||||
|
// Don't send ID if it's a locally-made note
|
||||||
|
if (note.norealid != true) {
|
||||||
|
data.id = note.noteid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.ajax({
|
||||||
|
url: this.server + "/api/savenote",
|
||||||
|
dataType: "json",
|
||||||
|
method: "POST",
|
||||||
|
data: data,
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
|
||||||
|
}, success: function (val) {
|
||||||
|
if (val.status == "OK") {
|
||||||
|
if (typeof success == 'function') {
|
||||||
|
success(val.note);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (typeof error == 'function') {
|
||||||
|
error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, error: function () {
|
||||||
|
if (typeof error == 'function') {
|
||||||
|
error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync notes with the NotePost server, resolving conflicts in the process.
|
||||||
|
*
|
||||||
|
* @param {function} success(notes) called when everything's synced up.
|
||||||
|
* @param {function} error
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
sync(success, error) {
|
||||||
|
super.sync();
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: this.server + "/api/getnotes",
|
url: this.server + "/api/getnotes",
|
||||||
@ -59,54 +132,40 @@ class NotePostNotes extends Notes {
|
|||||||
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
|
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
|
||||||
}, success: function (val) {
|
}, success: function (val) {
|
||||||
if (val.status == "OK") {
|
if (val.status == "OK") {
|
||||||
self.notes = val.notes;
|
|
||||||
}
|
console.log("Comparing notes...");
|
||||||
if (typeof callback == 'function') {
|
console.log("Local copy:", self.notes);
|
||||||
callback();
|
console.log("Remote copy:", val.notes);
|
||||||
|
var delta = getDelta(self.notes, val.notes);
|
||||||
|
console.log("Comparison: ", delta);
|
||||||
|
|
||||||
|
var notes = delta.noChange;
|
||||||
|
notes = notes.concat(delta.addedRemote);
|
||||||
|
notes = notes.concat(delta.changedRemote);
|
||||||
|
|
||||||
|
// Sync locally-created or modified notes
|
||||||
|
var notesToUpload = delta.addedLocal;
|
||||||
|
notesToUpload = notesToUpload.concat(delta.changedLocal);
|
||||||
|
var addedOrChangedLocallyAjax = [];
|
||||||
|
for (var i = 0; i < notesToUpload.length; i++) {
|
||||||
|
addedOrChangedLocallyAjax.push(self.saveNote(self.fix(notesToUpload[i]), function (n) {
|
||||||
|
notes.push(n);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
$.when(addedOrChangedLocallyAjax).then(function () {
|
||||||
|
self.notes = notes;
|
||||||
|
self.fixAll();
|
||||||
|
localStorage.setItem("notes", JSON.stringify(notes));
|
||||||
|
console.log(JSON.parse(localStorage.getItem("notes")));
|
||||||
|
if (typeof success == 'function') {
|
||||||
|
success(notes);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}, error: function () {
|
||||||
saveNote(note, callback) {
|
if (typeof error == 'function') {
|
||||||
var self = this;
|
error();
|
||||||
var data = {
|
|
||||||
text: note.content,
|
|
||||||
color: note.color,
|
|
||||||
modified: note.modified,
|
|
||||||
favorite: (note.favorite ? "1" : "0")
|
|
||||||
};
|
|
||||||
// Don't send ID if it's a locally-made note
|
|
||||||
if (note.norealid != true) {
|
|
||||||
data.id = note.id;
|
|
||||||
}
|
}
|
||||||
$.ajax({
|
|
||||||
url: this.server + "/api/savenote",
|
|
||||||
dataType: "json",
|
|
||||||
method: "POST",
|
|
||||||
data: data,
|
|
||||||
beforeSend: function (xhr) {
|
|
||||||
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
|
|
||||||
}
|
|
||||||
}).always(function () {
|
|
||||||
if (typeof callback == 'function') {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
save(callback) {
|
|
||||||
this.fixAll();
|
|
||||||
super.save();
|
|
||||||
|
|
||||||
var ajaxcalls = [];
|
|
||||||
for (var i = 0; i < this.notes.length; i++) {
|
|
||||||
ajaxcalls.push(this.saveNote(this.notes[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
$.when(ajaxcalls).always(function () {
|
|
||||||
if (typeof callback == 'function') {
|
|
||||||
callback();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,9 @@ class Notes {
|
|||||||
this.notes = [];
|
this.notes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
get(id) {
|
get(noteid) {
|
||||||
for (var i = 0; i < this.notes.length; i++) {
|
for (var i = 0; i < this.notes.length; i++) {
|
||||||
if (this.notes[i].id == id) {
|
if (this.notes[i].noteid == noteid) {
|
||||||
return this.notes[i];
|
return this.notes[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,38 +25,51 @@ class Notes {
|
|||||||
|
|
||||||
set(note) {
|
set(note) {
|
||||||
for (var i = 0; i < this.notes.length; i++) {
|
for (var i = 0; i < this.notes.length; i++) {
|
||||||
if (this.notes[i].id == note.id) {
|
if (this.notes[i].noteid == note.noteid) {
|
||||||
// Refresh HTML rendering
|
// Refresh HTML rendering
|
||||||
note.html = marked(note.content);
|
note.html = marked(note.content);
|
||||||
|
|
||||||
this.notes[i] = note;
|
this.notes[i] = note;
|
||||||
|
this.save();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.notes.push(note);
|
this.notes.push(note);
|
||||||
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
del(noteid, callback) {
|
del(noteid, success, error) {
|
||||||
var newnotearr = [];
|
var newnotearr = [];
|
||||||
for (var i = 0; i < this.notes.length; i++) {
|
for (var i = 0; i < this.notes.length; i++) {
|
||||||
if (this.notes[i].id != noteid) {
|
if (this.notes[i].noteid != noteid) {
|
||||||
newnotearr.push(this.notes[i]);
|
newnotearr.push(this.notes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.notes = newnotearr;
|
this.notes = newnotearr;
|
||||||
if (typeof callback == 'function') {
|
this.save();
|
||||||
callback();
|
if (typeof success == 'function') {
|
||||||
|
success();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add(note, callback) {
|
add(note, success, error) {
|
||||||
|
var noteid = null;
|
||||||
|
do {
|
||||||
|
noteid = Math.floor(Math.random() * (9999999999 - 1000000000) + 1000000000);
|
||||||
|
console.log("Generating random note ID: " + noteid);
|
||||||
|
} while (this.get(noteid) != null);
|
||||||
|
note["noteid"] = noteid;
|
||||||
this.notes.push(note);
|
this.notes.push(note);
|
||||||
if (typeof callback == 'function') {
|
this.save();
|
||||||
callback();
|
if (typeof success == 'function') {
|
||||||
|
success(note);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fix(note) {
|
fix(note) {
|
||||||
|
if (typeof note.noteid !== 'number') {
|
||||||
|
note.noteid = null;
|
||||||
|
}
|
||||||
// Set background color
|
// Set background color
|
||||||
if (typeof note.color !== 'string') {
|
if (typeof note.color !== 'string') {
|
||||||
note.color = "FFF59D";
|
note.color = "FFF59D";
|
||||||
@ -85,39 +98,58 @@ class Notes {
|
|||||||
if (typeof note.title !== 'string') {
|
if (typeof note.title !== 'string') {
|
||||||
note.title = note.content.split('\n')[0].replace(/[#\-]+/gi, "").trim();
|
note.title = note.content.split('\n')[0].replace(/[#\-]+/gi, "").trim();
|
||||||
}
|
}
|
||||||
if (typeof note.modified !== 'string') {
|
if (typeof note.modified !== 'number') {
|
||||||
note.modified = (new Date()).toISOString();
|
note.modified = Math.round((new Date()).getTime() / 1000);
|
||||||
}
|
}
|
||||||
// Render Markdown to HTML
|
// Render Markdown to HTML
|
||||||
if (typeof note.html !== 'string') {
|
if (typeof note.html !== 'string') {
|
||||||
note.html = marked(note.content);
|
note.html = marked(note.content);
|
||||||
}
|
}
|
||||||
// Save
|
// Save
|
||||||
this.set(note);
|
return note;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixAll() {
|
fixAll() {
|
||||||
for (var i = 0; i < this.notes.length; i++) {
|
for (var i = 0; i < this.notes.length; i++) {
|
||||||
this.fix(this.notes[i]);
|
this.notes[i] = this.fix(this.notes[i]);
|
||||||
|
}
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync notes with the storage backend.
|
||||||
|
*
|
||||||
|
* @param {type} success
|
||||||
|
* @param {type} error
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
sync(success, error) {
|
||||||
|
if (localStorage.getItem("notes") !== null) { // There is localstorage
|
||||||
|
var storage = JSON.parse(localStorage.getItem("notes"));
|
||||||
|
|
||||||
|
console.log("Memory copy:", this.notes);
|
||||||
|
console.log("Storage copy:", storage);
|
||||||
|
var delta = getDelta(this.notes, storage);
|
||||||
|
console.log("Comparison: ", delta);
|
||||||
|
|
||||||
|
var notes = delta.noChange;
|
||||||
|
notes = notes.concat(delta.addedRemote);
|
||||||
|
notes = notes.concat(delta.changedRemote);
|
||||||
|
notes = notes.concat(delta.addedLocal);
|
||||||
|
notes = notes.concat(delta.changedLocal);
|
||||||
|
// If localStorage is missing something, we still want it
|
||||||
|
notes = notes.concat(delta.deletedRemote);
|
||||||
|
|
||||||
|
this.notes = notes;
|
||||||
|
this.fixAll();
|
||||||
|
}
|
||||||
|
this.save();
|
||||||
|
if (typeof success == 'function') {
|
||||||
|
success(this.notes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
load(callback) {
|
save() {
|
||||||
if (localStorage.getItem("notes") !== null) {
|
|
||||||
var data = JSON.parse(localStorage.getItem("notes"));
|
|
||||||
if (data.length > 0) {
|
|
||||||
this.notes = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof callback == 'function') {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save(callback) {
|
|
||||||
localStorage.setItem("notes", JSON.stringify(this.notes));
|
localStorage.setItem("notes", JSON.stringify(this.notes));
|
||||||
if (typeof callback == 'function') {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
83
www/js/delta.js
Normal file
83
www/js/delta.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* The code in this file is by StackOverflow user Juan Mendes.
|
||||||
|
* License: Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0).
|
||||||
|
* Source: https://stackoverflow.com/a/14966749
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a map out of an array be choosing what property to key by
|
||||||
|
* @param {object[]} array Array that will be converted into a map
|
||||||
|
* @param {string} prop Name of property to key by
|
||||||
|
* @return {object} The mapped array. Example:
|
||||||
|
* mapFromArray([{a:1,b:2}, {a:3,b:4}], 'a')
|
||||||
|
* returns {1: {a:1,b:2}, 3: {a:3,b:4}}
|
||||||
|
*/
|
||||||
|
function mapFromArray(array, prop) {
|
||||||
|
var map = {};
|
||||||
|
for (var i = 0; i < array.length; i++) {
|
||||||
|
map[ array[i][prop] ] = array[i];
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object[]} o old array of notes (local copy)
|
||||||
|
* @param {object[]} n new array of notes (remote copy)
|
||||||
|
* @param {object} An object with changes
|
||||||
|
*/
|
||||||
|
function getDelta(o, n) {
|
||||||
|
var delta = {
|
||||||
|
addedRemote: [],
|
||||||
|
addedLocal: [],
|
||||||
|
deletedRemote: [],
|
||||||
|
deletedLocal: [],
|
||||||
|
changedRemote: [],
|
||||||
|
changedLocal: [],
|
||||||
|
noChange: []
|
||||||
|
};
|
||||||
|
oSane = [];
|
||||||
|
for (var i = 0; i < o.length; i++) {
|
||||||
|
if (o[i].noteid == null) { // Note has no real `noteid`
|
||||||
|
delta.addedLocal.push(o[i]);
|
||||||
|
} else {
|
||||||
|
oSane.push(o[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var local = mapFromArray(oSane, 'noteid');
|
||||||
|
var remote = mapFromArray(n, 'noteid');
|
||||||
|
|
||||||
|
for (var id in local) {
|
||||||
|
if (!remote.hasOwnProperty(id)) { // Notes that are only present locally
|
||||||
|
delta.addedLocal.push(local[id]);
|
||||||
|
// TODO: Figure out which notes were actually added locally and which were deleted on the server
|
||||||
|
/*if (local[id].norealid) { // Note hasn't been synced to the remote yet
|
||||||
|
delta.addedLocal.push(local[id]);
|
||||||
|
} else { // Note has been synced to remote but isn't there anymore
|
||||||
|
delta.deletedRemote.push(local[id]);
|
||||||
|
}*/
|
||||||
|
} else { // Notes that are present on both
|
||||||
|
if (local[id].modified > remote[id].modified) { // Local copy is newer
|
||||||
|
delta.changedLocal.push(local[id]);
|
||||||
|
} else if (local[id].modified < remote[id].modified) { // Remote copy is newer
|
||||||
|
delta.changedRemote.push(remote[id]);
|
||||||
|
} else { // Modified date is same, let's check content
|
||||||
|
if (local[id].content == remote[id].content) {
|
||||||
|
delta.noChange.push(local[id]);
|
||||||
|
} else if (local[id].content.length > remote[id].content.length) {
|
||||||
|
delta.changedLocal.push(local[id]);
|
||||||
|
} else {
|
||||||
|
delta.changedRemote.push(remote[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add notes that are only on the remote
|
||||||
|
for (var id in remote) {
|
||||||
|
if (!local.hasOwnProperty(id)) {
|
||||||
|
delta.addedRemote.push(remote[id]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return delta;
|
||||||
|
}
|
@ -4,30 +4,10 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
function saveme(callback) {
|
function saveme(callback) {
|
||||||
var noteid = $("#note_content").data("noteid");
|
function finishSave(note, callback) {
|
||||||
if (noteid == "") {
|
NOTES.fixAll();
|
||||||
// Make a very random ID number and check that it won't collide,
|
NOTES.sync(function () {
|
||||||
// in case the user is good at winning the lottery
|
|
||||||
do {
|
|
||||||
noteid = Math.floor(Math.random() * (9999999999 - 1000000000) + 1000000000);
|
|
||||||
console.log("Generating random note ID: " + noteid);
|
|
||||||
} while (notes.get(noteid) != null);
|
|
||||||
|
|
||||||
var note = {id: noteid};
|
|
||||||
note.content = $("#note_content").val();
|
|
||||||
note.modified = (new Date()).toISOString();
|
|
||||||
notes.add(note);
|
|
||||||
$("#note_content").data("noteid", noteid);
|
|
||||||
} else {
|
|
||||||
var note = notes.get(noteid);
|
|
||||||
note.content = $("#note_content").val();
|
|
||||||
note.modified = (new Date()).toISOString();
|
|
||||||
notes.set(note);
|
|
||||||
}
|
|
||||||
notes.fix(note);
|
|
||||||
notes.save(function () {
|
|
||||||
app.toast.create({
|
app.toast.create({
|
||||||
text: 'Note saved.',
|
text: 'Note saved.',
|
||||||
closeTimeout: 2000
|
closeTimeout: 2000
|
||||||
@ -37,6 +17,25 @@ function saveme(callback) {
|
|||||||
if (typeof callback == "function") {
|
if (typeof callback == "function") {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var noteid = $("#note_content").data("noteid");
|
||||||
|
if (noteid == "") {
|
||||||
|
var note = {
|
||||||
|
content: $("#note_content").val(),
|
||||||
|
modified: Math.round((new Date()).getTime() / 1000)
|
||||||
|
};
|
||||||
|
NOTES.add(note, function (n) {
|
||||||
|
$("#note_content").data("noteid", n.noteid);
|
||||||
|
finishSave(n, callback);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var note = NOTES.get(noteid);
|
||||||
|
note.content = $("#note_content").val();
|
||||||
|
note.modified = Math.round((new Date()).getTime() / 1000);
|
||||||
|
NOTES.set(note);
|
||||||
|
finishSave(note, callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function exiteditor() {
|
function exiteditor() {
|
||||||
|
@ -10,7 +10,7 @@ $(".view-main").on("ptr:refresh", ".ptr-content", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function editNote(id) {
|
function editNote(id) {
|
||||||
var note = notes.get(id);
|
var note = NOTES.get(id);
|
||||||
router.navigate("/editnote", {
|
router.navigate("/editnote", {
|
||||||
context: {
|
context: {
|
||||||
noteid: id,
|
noteid: id,
|
||||||
@ -31,7 +31,7 @@ function makeList(id) {
|
|||||||
|
|
||||||
function deleteNote(id) {
|
function deleteNote(id) {
|
||||||
app.dialog.confirm('Are you sure?', 'Delete Note', function () {
|
app.dialog.confirm('Are you sure?', 'Delete Note', function () {
|
||||||
notes.del(id, function () {
|
NOTES.del(id, function () {
|
||||||
app.ptr.refresh();
|
app.ptr.refresh();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,6 +19,10 @@ var mainView = app.views.create('.view-main', {
|
|||||||
|
|
||||||
var router = mainView.router;
|
var router = mainView.router;
|
||||||
|
|
||||||
|
var NOTES = null;
|
||||||
|
|
||||||
|
var OFFLINE = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thanks to https://stackoverflow.com/a/13542669
|
* Thanks to https://stackoverflow.com/a/13542669
|
||||||
* @param {type} color
|
* @param {type} color
|
||||||
@ -54,9 +58,13 @@ router.on("pageInit", function (pagedata) {
|
|||||||
// Run platform-specific setup code for Cordova or NW.js
|
// Run platform-specific setup code for Cordova or NW.js
|
||||||
initPlatform();
|
initPlatform();
|
||||||
|
|
||||||
|
|
||||||
if (localStorage.getItem("configured") == null) {
|
if (localStorage.getItem("configured") == null) {
|
||||||
// Open the setup page
|
// Open the setup page
|
||||||
router.navigate("/setup/0");
|
router.navigate("/setup/0");
|
||||||
} else {
|
} else {
|
||||||
|
createNotesObject(function (n) {
|
||||||
|
NOTES = n;
|
||||||
router.navigate("/home");
|
router.navigate("/home");
|
||||||
|
});
|
||||||
}
|
}
|
@ -4,8 +4,33 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (localStorage.getItem("serverurl") == null) {
|
function createNotesObject(callback) {
|
||||||
var notes = new Notes();
|
if (localStorage.getItem("serverurl") == null) {
|
||||||
} else {
|
callback(new Notes());
|
||||||
var notes = new NotePostNotes(localStorage.getItem("serverurl"), localStorage.getItem("username"), localStorage.getItem("password"));
|
} else {
|
||||||
|
var checkurl = localStorage.getItem("serverurl") + "/api/ping";
|
||||||
|
$.ajax({
|
||||||
|
url: checkurl,
|
||||||
|
dataType: "json",
|
||||||
|
cache: false,
|
||||||
|
method: "POST",
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader("Authorization", "Basic " + btoa(localStorage.getItem("username") + ":" + localStorage.getItem("password")));
|
||||||
|
}, success: function (data) {
|
||||||
|
if (data.status == "OK") {
|
||||||
|
callback(new NotePostNotes(localStorage.getItem("serverurl"), localStorage.getItem("username"), localStorage.getItem("password")));
|
||||||
|
} else if (data.status == "ERROR") {
|
||||||
|
app.dialog.alert(data.msg, "Error");
|
||||||
|
OFFLINE = true;
|
||||||
|
callback(new Notes());
|
||||||
|
} else {
|
||||||
|
OFFLINE = true;
|
||||||
|
callback(new Notes());
|
||||||
|
}
|
||||||
|
}, error: function () {
|
||||||
|
OFFLINE = true;
|
||||||
|
callback(new Notes());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
@ -28,9 +28,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row notecards-row" id="notecards-bin">
|
<div class="row notecards-row" id="notecards-bin">
|
||||||
|
{{#if offline}}
|
||||||
|
<div class="col-100 tablet-50 desktop-33 notecard-col">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content card-content-padding text-align-center text-color-gray">
|
||||||
|
<div><i class="material-icons" style="font-size: 40pt;">cloud_off</i></div>
|
||||||
|
Offline
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{#each notecards}}
|
{{#each notecards}}
|
||||||
<div class="col-100 tablet-50 desktop-33 notecard-col">
|
<div class="col-100 tablet-50 desktop-33 notecard-col">
|
||||||
<div class="card notecard" id="notecard-{{id}}" data-id="{{id}}" data-bg="{{color}}" data-fg="{{textcolor}}" style="background-color: #{{color}}; color: #{{textcolor}};">
|
<div class="card notecard" id="notecard-{{noteid}}" data-id="{{noteid}}" data-bg="{{color}}" data-fg="{{textcolor}}" style="background-color: #{{color}}; color: #{{textcolor}};">
|
||||||
<div class="menubtn">
|
<div class="menubtn">
|
||||||
<i class="material-icons">more_vert</i>
|
<i class="material-icons">more_vert</i>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,21 +10,31 @@ var routes = [
|
|||||||
path: '/home',
|
path: '/home',
|
||||||
name: 'home',
|
name: 'home',
|
||||||
async: function (routeTo, routeFrom, resolve, reject) {
|
async: function (routeTo, routeFrom, resolve, reject) {
|
||||||
notes.load(function () {
|
var pageinfo = {
|
||||||
console.log("Loading");
|
templateUrl: './pages/home.html',
|
||||||
notes.fixAll();
|
reloadCurrent: (routeFrom.name == "home")
|
||||||
var notecards = notes.getAll();
|
};
|
||||||
|
var context = {
|
||||||
|
showrefreshbtn: (platform_type != "cordova"),
|
||||||
|
offline: OFFLINE
|
||||||
|
};
|
||||||
|
NOTES.sync(function (notes) {
|
||||||
|
context["notecards"] = notes;
|
||||||
if (routeFrom.name == "home") {
|
if (routeFrom.name == "home") {
|
||||||
app.ptr.done();
|
app.ptr.done();
|
||||||
}
|
}
|
||||||
resolve({
|
resolve(pageinfo, {
|
||||||
templateUrl: './pages/home.html',
|
context: context
|
||||||
reloadCurrent: (routeFrom.name == "home")
|
});
|
||||||
}, {
|
}, function () {
|
||||||
context: {
|
NOTES.fixAll();
|
||||||
notecards: notecards,
|
context["notecards"] = NOTES.getAll();
|
||||||
showrefreshbtn: (platform_type != "cordova")
|
if (routeFrom.name == "home") {
|
||||||
|
app.ptr.done();
|
||||||
}
|
}
|
||||||
|
context["offline"] = true;
|
||||||
|
resolve(pageinfo, {
|
||||||
|
context: context
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -66,15 +76,9 @@ var routes = [
|
|||||||
title: "Sign in to a different account",
|
title: "Sign in to a different account",
|
||||||
onclick: "router.navigate('/setup/0')"
|
onclick: "router.navigate('/setup/0')"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
setting: "opensource",
|
|
||||||
title: "Open Source Information",
|
|
||||||
text: "",
|
|
||||||
onclick: "router.navigate('/credits')"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
setting: "versions",
|
setting: "versions",
|
||||||
title: "NotePost app v0.1",
|
title: "NotePost app v1.0.0",
|
||||||
text: "Copyright © 2018-2019 Netsyms Technologies. License: <span style=\"text-decoration: underline;\" onclick=\"openBrowser('https://source.netsyms.com/Apps/NotePostApp?pk_campaign=NotePostApp');\">Mozilla Public License 2.0</span>.",
|
text: "Copyright © 2018-2019 Netsyms Technologies. License: <span style=\"text-decoration: underline;\" onclick=\"openBrowser('https://source.netsyms.com/Apps/NotePostApp?pk_campaign=NotePostApp');\">Mozilla Public License 2.0</span>.",
|
||||||
onclick: ""
|
onclick: ""
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user