Browse Source

Use Babel to convert ES6 classes for older Android devices

tags/v1.1.0
Skylar Ittner 11 months ago
parent
commit
0415de945f

+ 3
- 0
.gitignore View File

@@ -5,3 +5,6 @@
/plugins
npm-debug.log
nbproject/private/
/www/js
/yarn-error.log
/www/yarn-error.log

+ 1
- 0
config.xml View File

@@ -19,6 +19,7 @@
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<preference name="android-minSdkVersion" value="21" />
<preference name="android-targetSdkVersion" value="27" />
<allow-intent href="market:*" />
<preference name="HeaderColor" value="#F44336" />

+ 13
- 0
www/babel.config.js View File

@@ -0,0 +1,13 @@
const presets = [
[
"@babel/env",
{
targets: {
chrome: "33",
},
useBuiltIns: "usage",
},
],
];

module.exports = { presets };

+ 0
- 173
www/js/NotePostNotes.class.js View File

@@ -1,173 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

class NotePostNotes extends Notes {

constructor(server, username, password) {
super();
this.server = server;
this.username = username;
this.password = password;
}

del(noteid, success, error) {
super.del(noteid);
var self = this;
return $.ajax({
url: this.server + "/api/deletenote",
dataType: "json",
cache: false,
method: "POST",
data: {
id: noteid
},
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
}, success: function (val) {
if (val.status == "OK") {
self.notes = val.notes;
}
if (typeof success == 'function') {
success();
}
}, error: function () {
if (typeof error == 'function') {
error();
}
}
});
}

add(note, success, error) {
note.norealid = true;
this.saveNote(note, success, error);
}

getNote(noteid, success, error) {
return $.ajax({
url: this.server + "/api/getnote",
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();
}
}
});
}

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;
$.ajax({
url: this.server + "/api/getnotes",
dataType: "json",
cache: false,
method: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
}, success: function (val) {
if (val.status == "OK") {

console.log("Comparing notes...");
console.log("Local copy:", self.notes);
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 () {
if (typeof error == 'function') {
error();
}
}
});
}

}

+ 0
- 155
www/js/Notes.class.js View File

@@ -1,155 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

class Notes {

constructor() {
this.notes = [];
}

get(noteid) {
for (var i = 0; i < this.notes.length; i++) {
if (this.notes[i].noteid == noteid) {
return this.notes[i];
}
}
return null;
}

getAll() {
return this.notes;
}

set(note) {
for (var i = 0; i < this.notes.length; i++) {
if (this.notes[i].noteid == note.noteid) {
// Refresh HTML rendering
note.html = marked(note.content);

this.notes[i] = note;
this.save();
return;
}
}
this.notes.push(note);
this.save();
}

del(noteid, success, error) {
var newnotearr = [];
for (var i = 0; i < this.notes.length; i++) {
if (this.notes[i].noteid != noteid) {
newnotearr.push(this.notes[i]);
}
}
this.notes = newnotearr;
this.save();
if (typeof success == 'function') {
success();
}
}

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.save();
if (typeof success == 'function') {
success(note);
}
}

fix(note) {
if (typeof note.noteid !== 'number') {
note.noteid = null;
}
// Set background color
if (typeof note.color !== 'string') {
note.color = "FFF59D";
}
// Set text color based on background
if (typeof note.textcolor !== 'string') {
var r = parseInt(note.color.substring(0, 2), 16);
var g = parseInt(note.color.substring(2, 4), 16);
var b = parseInt(note.color.substring(4, 6), 16);
var contrast = Math.sqrt(
r * r * 0.241 +
g * g * 0.691 +
b * b * 0.068
);
if (contrast > 130) {
note.textcolor = "000000";
} else {
note.textcolor = "FFFFFF";
}
}
// Just in case
if (typeof note.content !== 'string') {
note.content = "";
}
// Set title
if (typeof note.title !== 'string') {
note.title = note.content.split('\n')[0].replace(/[#\-]+/gi, "").trim();
}
if (typeof note.modified !== 'number') {
note.modified = Math.round((new Date()).getTime() / 1000);
}
// Render Markdown to HTML
if (typeof note.html !== 'string') {
note.html = marked(note.content);
}
// Save
return note;
}

fixAll() {
for (var i = 0; i < this.notes.length; 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);
}
}

save() {
localStorage.setItem("notes", JSON.stringify(this.notes));
}
}

+ 67
- 54
www/js/delta.js View File

@@ -1,10 +1,11 @@
"use strict";

/*
* 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
@@ -14,70 +15,82 @@
* 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;
}
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 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');
}

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

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]);
}
}
/*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

// Add notes that are only on the remote
for (var id in remote) {
if (!local.hasOwnProperty(id)) {
delta.addedRemote.push(remote[id]);
}

for (var id in remote) {
if (!local.hasOwnProperty(id)) {
delta.addedRemote.push(remote[id]);
}
return delta;
}

return delta;
}

+ 48
- 37
www/js/editnote.js View File

@@ -1,49 +1,60 @@
"use strict";

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

function saveme(callback) {
function finishSave(note, callback) {
NOTES.fixAll();
NOTES.sync(function () {
app.toast.create({
text: 'Note saved.',
closeTimeout: 2000
}).open();
$("#orig_content").val(note.content);
});
if (typeof callback == "function") {
callback();
}
}
function finishSave(note, callback) {
NOTES.fixAll();
NOTES.sync(function () {
app.toast.create({
text: 'Note saved.',
closeTimeout: 2000
}).open();
$("#orig_content").val(note.content);
});

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);
if (typeof callback == "function") {
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() {
if ($("#note_content").val() == "" || $("#note_content").val() === $("#orig_content").val()) {
router.back({force: true, ignoreCache: true, reload: true});
} else {
saveme(function () {
router.back({force: true, ignoreCache: true, reload: true});
});
}
if ($("#note_content").val() == "" || $("#note_content").val() === $("#orig_content").val()) {
router.back({
force: true,
ignoreCache: true,
reload: true
});
} else {
saveme(function () {
router.back({
force: true,
ignoreCache: true,
reload: true
});
});
}
}

+ 71
- 92
www/js/home.js View File

@@ -1,126 +1,105 @@
"use strict";

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/


$(".view-main").on("ptr:refresh", ".ptr-content", function () {
restartApplication();
restartApplication();
});

function editNote(id) {
var note = NOTES.get(id);
router.navigate("/editnote", {
context: {
noteid: id,
content: note.content,
notetitle: note.title,
}
});
console.log("Editing " + id);
}

function favoriteNote(id) {

var note = NOTES.get(id);
router.navigate("/editnote", {
context: {
noteid: id,
content: note.content,
notetitle: note.title
}
});
console.log("Editing " + id);
}

function makeList(id) {
function favoriteNote(id) {}

}
function makeList(id) {}

function deleteNote(id) {
app.dialog.confirm('Are you sure?', 'Delete Note', function () {
NOTES.del(id, function () {
app.ptr.refresh();
});
app.dialog.confirm('Are you sure?', 'Delete Note', function () {
NOTES.del(id, function () {
app.ptr.refresh();
});
});
}

$("#app").on("click", ".edit-note-btn", function () {
editNote($(this).data("note"));
app.popover.close();
editNote($(this).data("note"));
app.popover.close();
});

$("#app").on("click", ".favorite-note-btn", function () {
favoriteNote($(this).data("note"));
app.popover.close();
favoriteNote($(this).data("note"));
app.popover.close();
});

$("#app").on("click", ".listify-note-btn", function () {
makeList($(this).data("note"));
app.popover.close();
makeList($(this).data("note"));
app.popover.close();
});

$("#app").on("click", ".delete-note-btn", function () {
deleteNote($(this).data("note"));
app.popover.close();
deleteNote($(this).data("note"));
app.popover.close();
});

function openNoteActionMenu(notecard) {
var noteid = notecard.data("id");
if (window.innerWidth < 768) {
var actionsheet = app.actions.create({
buttons: [
{
text: "Edit",
bold: true,
icon: '<i class="fas fa-edit fa-fw"></i>',
onClick: function () {
editNote(noteid);
}
},
// {
// text: "Favorite",
// icon: '<i class="fas fa-star fa-fw"></i>',
// onClick: function () {
// favoriteNote(noteid);
// }
// },
// {
// text: "Make a List",
// icon: '<i class="fas fa-tasks fa-fw"></i>',
// onClick: function () {
// makeList(noteid);
// }
// },
{
text: "Delete",
icon: '<i class="fas fa-trash fa-fw"></i>',
onClick: function () {
deleteNote(noteid);
}
}
]
});

actionsheet.open();
return false;
} else {
var contextPopover = app.popover.create({
targetEl: notecard.children(".menubtn"),
content: '<div class="popover">' +
'<div class="popover-inner">' +
'<div class="list">' +
'<ul>' +
'<li><a class="list-button item-link edit-note-btn" data-note="' + noteid + '"><i class="fas fa-edit fa-fw"></i> Edit</a></li>' +
'<li><a class="list-button item-link favorite-note-btn" data-note="' + noteid + '"><i class="fas fa-star fa-fw"></i> Favorite</a></li>' +
'<li><a class="list-button item-link listify-note-btn" data-note="' + noteid + '"><i class="fas fa-tasks fa-fw"></i> Make a List</a></li>' +
'<li><a class="list-button item-link delete-note-btn" data-note="' + noteid + '"><i class="fas fa-trash fa-fw"></i> Delete</a></li>' +
'</ul>' +
'</div>' +
'</div>' +
'</div>'
});
contextPopover.open();
}
var noteid = notecard.data("id");

if (window.innerWidth < 768) {
var actionsheet = app.actions.create({
buttons: [{
text: "Edit",
bold: true,
icon: '<i class="fas fa-edit fa-fw"></i>',
onClick: function onClick() {
editNote(noteid);
}
}, // {
// text: "Favorite",
// icon: '<i class="fas fa-star fa-fw"></i>',
// onClick: function () {
// favoriteNote(noteid);
// }
// },
// {
// text: "Make a List",
// icon: '<i class="fas fa-tasks fa-fw"></i>',
// onClick: function () {
// makeList(noteid);
// }
// },
{
text: "Delete",
icon: '<i class="fas fa-trash fa-fw"></i>',
onClick: function onClick() {
deleteNote(noteid);
}
}]
});
actionsheet.open();
return false;
} else {
var contextPopover = app.popover.create({
targetEl: notecard.children(".menubtn"),
content: '<div class="popover">' + '<div class="popover-inner">' + '<div class="list">' + '<ul>' + '<li><a class="list-button item-link edit-note-btn" data-note="' + noteid + '"><i class="fas fa-edit fa-fw"></i> Edit</a></li>' + '<li><a class="list-button item-link favorite-note-btn" data-note="' + noteid + '"><i class="fas fa-star fa-fw"></i> Favorite</a></li>' + '<li><a class="list-button item-link listify-note-btn" data-note="' + noteid + '"><i class="fas fa-tasks fa-fw"></i> Make a List</a></li>' + '<li><a class="list-button item-link delete-note-btn" data-note="' + noteid + '"><i class="fas fa-trash fa-fw"></i> Delete</a></li>' + '</ul>' + '</div>' + '</div>' + '</div>'
});
contextPopover.open();
}

return false;
}

$(".view-main").on("click", ".notecard .menubtn", function () {
return openNoteActionMenu($(this).parent());
return openNoteActionMenu($(this).parent());
});

$(".view-main").on("contextmenu", ".notecard", function () {
return openNoteActionMenu($(this));
return openNoteActionMenu($(this));
});

+ 43
- 39
www/js/main.js View File

@@ -1,70 +1,74 @@
"use strict";

require("core-js/modules/es6.array.find");

require("core-js/modules/es6.regexp.to-string");

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

var $$ = Dom7;

var app = new Framework7({
root: "#app",
name: "NotePost",
id: "com.netsyms.NotePostApp",
init: true,
initOnDeviceReady: false,
routes: routes
root: "#app",
name: "NotePost",
id: "com.netsyms.NotePostApp",
init: true,
initOnDeviceReady: false,
routes: routes
});

var mainView = app.views.create('.view-main', {
url: "/"
url: "/"
});

var router = mainView.router;

var NOTES = null;

var OFFLINE = false;

/**
* Thanks to https://stackoverflow.com/a/13542669
* @param {type} color
* @param {type} percent
* @returns {String}
*/

function shadeColor2(color, percent) {
var f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF;
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
var f = parseInt(color.slice(1), 16),
t = percent < 0 ? 0 : 255,
p = percent < 0 ? percent * -1 : percent,
R = f >> 16,
G = f >> 8 & 0x00FF,
B = f & 0x0000FF;
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
}

function restartApplication() {
window.location = "index.html";
window.location = "index.html";
}

router.on("pageInit", function (pagedata) {
pagedata.$el.find('script').each(function (el) {
if ($$(this).attr('src')) {
var s = document.createElement('script');
s.src = $$(this).attr('src');
$$('head').append(s);
} else {
eval($$(this).text());
}
});
switch (pagedata.name) {
case "settings":
updateSettingsData();
break;
pagedata.$el.find('script').each(function (el) {
if ($$(this).attr('src')) {
var s = document.createElement('script');
s.src = $$(this).attr('src');
$$('head').append(s);
} else {
eval($$(this).text());
}
});
});

// Run platform-specific setup code for Cordova or NW.js
initPlatform();
switch (pagedata.name) {
case "settings":
updateSettingsData();
break;
}
}); // Run platform-specific setup code for Cordova or NW.js

initPlatform();

if (localStorage.getItem("configured") == null) {
// Open the setup page
router.navigate("/setup/0");
// Open the setup page
router.navigate("/setup/0");
} else {
createNotesObject(function (n) {
NOTES = n;
router.navigate("/home");
});
createNotesObject(function (n) {
NOTES = n;
router.navigate("/home");
});
}

+ 31
- 28
www/js/notes.js View File

@@ -1,36 +1,39 @@
"use strict";

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

function createNotesObject(callback) {
if (localStorage.getItem("serverurl") == null) {
if (localStorage.getItem("serverurl") == null) {
callback(new Notes());
} else {
var checkurl = localStorage.getItem("serverurl") + "/api/ping";
$.ajax({
url: checkurl,
dataType: "json",
cache: false,
method: "POST",
beforeSend: function beforeSend(xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(localStorage.getItem("username") + ":" + localStorage.getItem("password")));
},
success: function success(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 error() {
OFFLINE = true;
callback(new Notes());
} 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());
}
});
}
}
});
}
}

+ 51
- 52
www/js/platform.js View File

@@ -1,71 +1,70 @@
"use strict";

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

var platform_type = "";

var openBrowser = function (url) {

}
var openBrowser = function openBrowser(url) {};

function initCordova() {
platform_type = "cordova";

// Handle back button to close things
document.addEventListener("backbutton", function (event) {
router.navigate("/home");
}, false);

document.addEventListener("deviceready", function () {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#D32F2F");
StatusBar.styleLightContent();
}
}, false);
platform_type = "cordova"; // Handle back button to close things

openBrowser = function (url) {
cordova.InAppBrowser.open(url, '_blank', 'location=yes');
document.addEventListener("backbutton", function (event) {
router.navigate("/home");
}, false);
document.addEventListener("deviceready", function () {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#D32F2F");
StatusBar.styleLightContent();
}
}, false);

openBrowser = function openBrowser(url) {
cordova.InAppBrowser.open(url, '_blank', 'location=yes');
};
}

function initNW() {
platform_type = "nw";
platform_type = "nw";

openBrowser = function (url) {
nw.Window.open(url, {
id: url
}, function (browserwin) {
// Add menubar so the user can navigate around if they click a link
var browsermenu = new nw.Menu({type: 'menubar'});
browsermenu.append(new nw.MenuItem({
label: "Back",
click: function () {
browserwin.window.history.back();
}
}));
browsermenu.append(new nw.MenuItem({
label: "Forward",
click: function () {
browserwin.window.history.forward();
}
}));
browsermenu.append(new nw.MenuItem({
label: "Home",
click: function () {
browserwin.window.location.href = url;
}
}));
browserwin.menu = browsermenu;
});
}
openBrowser = function openBrowser(url) {
nw.Window.open(url, {
id: url
}, function (browserwin) {
// Add menubar so the user can navigate around if they click a link
var browsermenu = new nw.Menu({
type: 'menubar'
});
browsermenu.append(new nw.MenuItem({
label: "Back",
click: function click() {
browserwin.window.history.back();
}
}));
browsermenu.append(new nw.MenuItem({
label: "Forward",
click: function click() {
browserwin.window.history.forward();
}
}));
browsermenu.append(new nw.MenuItem({
label: "Home",
click: function click() {
browserwin.window.location.href = url;
}
}));
browserwin.menu = browsermenu;
});
};
}

function initPlatform() {
if (typeof cordova !== 'undefined') {
initCordova();
} else if (typeof nw !== 'undefined') {
initNW();
}
if (typeof cordova !== 'undefined') {
initCordova();
} else if (typeof nw !== 'undefined') {
initNW();
}
}

+ 85
- 79
www/js/setup1.js View File

@@ -1,103 +1,109 @@
"use strict";

require("core-js/modules/es6.regexp.replace");

require("core-js/modules/es6.string.starts-with");

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/


netsymscomurl = "https://apps.netsyms.com/notepost";
netsymsbizurl = "https://BIZID.netsyms.biz/notepost";


$('#use-security-checkbox-li').click(function () {
// Event fires before the checkbox is changed, so we need to do the opposite
if ($("#use-security").prop("checked")) {
$('#protocol-select').text("https://");
} else {
$('#protocol-select').text("http://");
}
// Event fires before the checkbox is changed, so we need to do the opposite
if ($("#use-security").prop("checked")) {
$('#protocol-select').text("https://");
} else {
$('#protocol-select').text("http://");
}
});

/* Detect if the user typed "http[s]://" into the URL box and correct for it */

$("#url").blur(function () {
if ($('#url').val().toLowerCase().startsWith("https://")) {
$('#url').val($('#url').val().replace(/https\:\/\//ig, ""));
$('#protocol-select').text("https://");
$('#use-security').prop('checked', true);
} else if ($('#url').val().toLowerCase().startsWith("http://")) {
$('#url').val($('#url').val().replace(/http\:\/\//ig, ""));
$('#protocol-select').text("http://");
$('#use-security').prop('checked', false);
}
if ($('#url').val().toLowerCase().startsWith("https://")) {
$('#url').val($('#url').val().replace(/https\:\/\//ig, ""));
$('#protocol-select').text("https://");
$('#use-security').prop('checked', true);
} else if ($('#url').val().toLowerCase().startsWith("http://")) {
$('#url').val($('#url').val().replace(/http\:\/\//ig, ""));
$('#protocol-select').text("http://");
$('#use-security').prop('checked', false);
}
});

$('#username').on("keyup", function () {
$('#username').val($('#username').val().toLowerCase());
$('#username').val($('#username').val().toLowerCase());
});

function checkAndSave(url, username, password, nextcloud) {
app.preloader.show();
app.preloader.show();

if (typeof nextcloud === 'undefined') {
nextcloud = false;
}
if (typeof nextcloud === 'undefined') {
nextcloud = false;
}

var checkurl = url + "/api/ping";
var checkurl = url + "/api/ping";

if (nextcloud) {
// TODO
}
if (nextcloud) {// TODO
}

$.ajax({
url: checkurl,
dataType: "json",
cache: false,
method: "POST",
beforeSend: function beforeSend(xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
},
success: function success(data) {
app.preloader.hide();

$.ajax({
url: checkurl,
dataType: "json",
cache: false,
method: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
}, success: function (data) {
app.preloader.hide();
if (data.status == "OK") {
localStorage.setItem("username", username);
localStorage.setItem("password", password);
localStorage.setItem("serverurl", url);
localStorage.setItem("configured", true);
// Restart the app to re-read the config
restartApplication();
} else if (data.status == "ERROR") {
app.dialog.alert(data.msg, "Error");
} else {
app.dialog.alert("", "Error");
}
}, error: function () {
app.preloader.hide();
app.dialog.alert("Could not sign in. Check your credentials and connection.", "Error");
}
});
if (data.status == "OK") {
localStorage.setItem("username", username);
localStorage.setItem("password", password);
localStorage.setItem("serverurl", url);
localStorage.setItem("configured", true); // Restart the app to re-read the config

restartApplication();
} else if (data.status == "ERROR") {
app.dialog.alert(data.msg, "Error");
} else {
app.dialog.alert("", "Error");
}
},
error: function error() {
app.preloader.hide();
app.dialog.alert("Could not sign in. Check your credentials and connection.", "Error");
}
});
}

function setupAccount() {
var type = $("#accttype").val();

var username = $("#username").val();
var password = $("#password").val();

switch (type) {
case "personal":
checkAndSave(netsymscomurl, username, password);
break;
case "business":
var url = netsymsbizurl.replace("BIZID", $("#bizid").val());
checkAndSave(url, username, password);
break;
case "selfhosted":
if (/^(https?:\/\/)/.test($('#url').val())) {
var url = $('#url').val();
} else {
var url = $('#protocol-select').text() + $('#url').val();
}
url = url.replace(/\/$/, ""); // Remove trailing slash
checkAndSave(url, username, password);
break;
}
var type = $("#accttype").val();
var username = $("#username").val();
var password = $("#password").val();

switch (type) {
case "personal":
checkAndSave(netsymscomurl, username, password);
break;

case "business":
var url = netsymsbizurl.replace("BIZID", $("#bizid").val());
checkAndSave(url, username, password);
break;

case "selfhosted":
if (/^(https?:\/\/)/.test($('#url').val())) {
var url = $('#url').val();
} else {
var url = $('#protocol-select').text() + $('#url').val();
}

url = url.replace(/\/$/, ""); // Remove trailing slash

checkAndSave(url, username, password);
break;
}
}

+ 180
- 0
www/js_src/NotePostNotes.class.js View File

@@ -0,0 +1,180 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
class NotePostNotes extends Notes {
constructor(server, username, password) {
super();
this.server = server;
this.username = username;
this.password = password;
}

del(noteid, success, error) {
super.del(noteid);
var self = this;
return $.ajax({
url: this.server + "/api/deletenote",
dataType: "json",
cache: false,
method: "POST",
data: {
id: noteid
},
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
},
success: function (val) {
if (val.status == "OK") {
self.notes = val.notes;
}

if (typeof success == 'function') {
success();
}
},
error: function () {
if (typeof error == 'function') {
error();
}
}
});
}

add(note, success, error) {
note.norealid = true;
this.saveNote(note, success, error);
}

getNote(noteid, success, error) {
return $.ajax({
url: this.server + "/api/getnote",
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();
}
}
});
}

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;
$.ajax({
url: this.server + "/api/getnotes",
dataType: "json",
cache: false,
method: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa(self.username + ":" + self.password));
},
success: function (val) {
if (val.status == "OK") {
console.log("Comparing notes...");
console.log("Local copy:", self.notes);
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 () {
if (typeof error == 'function') {
error();
}
}
});
}

}

+ 167
- 0
www/js_src/Notes.class.js View File

@@ -0,0 +1,167 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
class Notes {
constructor() {
this.notes = [];
}

get(noteid) {
for (var i = 0; i < this.notes.length; i++) {
if (this.notes[i].noteid == noteid) {
return this.notes[i];
}
}

return null;
}

getAll() {
return this.notes;
}

set(note) {
for (var i = 0; i < this.notes.length; i++) {
if (this.notes[i].noteid == note.noteid) {
// Refresh HTML rendering
note.html = marked(note.content);
this.notes[i] = note;
this.save();
return;
}
}

this.notes.push(note);
this.save();
}

del(noteid, success, error) {
var newnotearr = [];

for (var i = 0; i < this.notes.length; i++) {
if (this.notes[i].noteid != noteid) {
newnotearr.push(this.notes[i]);
}
}

this.notes = newnotearr;
this.save();

if (typeof success == 'function') {
success();
}
}

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.save();

if (typeof success == 'function') {
success(note);
}
}

fix(note) {
if (typeof note.noteid !== 'number') {
note.noteid = null;
} // Set background color


if (typeof note.color !== 'string') {
note.color = "FFF59D";
} // Set text color based on background


if (typeof note.textcolor !== 'string') {
var r = parseInt(note.color.substring(0, 2), 16);
var g = parseInt(note.color.substring(2, 4), 16);
var b = parseInt(note.color.substring(4, 6), 16);
var contrast = Math.sqrt(r * r * 0.241 + g * g * 0.691 + b * b * 0.068);

if (contrast > 130) {
note.textcolor = "000000";
} else {
note.textcolor = "FFFFFF";
}
} // Just in case


if (typeof note.content !== 'string') {
note.content = "";
} // Set title


if (typeof note.title !== 'string') {
note.title = note.content.split('\n')[0].replace(/[#\-]+/gi, "").trim();
}

if (typeof note.modified !== 'number') {
note.modified = Math.round(new Date().getTime() / 1000);
} // Render Markdown to HTML


if (typeof note.html !== 'string') {
note.html = marked(note.content);
} // Save


return note;
}

fixAll() {
for (var i = 0; i < this.notes.length; 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);
}
}

save() {
localStorage.setItem("notes", JSON.stringify(this.notes));
}

}

+ 83
- 0
www/js_src/delta.js View 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;
}

+ 49
- 0
www/js_src/editnote.js View File

@@ -0,0 +1,49 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

function saveme(callback) {
function finishSave(note, callback) {
NOTES.fixAll();
NOTES.sync(function () {
app.toast.create({
text: 'Note saved.',
closeTimeout: 2000
}).open();
$("#orig_content").val(note.content);
});
if (typeof callback == "function") {
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() {
if ($("#note_content").val() == "" || $("#note_content").val() === $("#orig_content").val()) {
router.back({force: true, ignoreCache: true, reload: true});
} else {
saveme(function () {
router.back({force: true, ignoreCache: true, reload: true});
});
}
}

+ 126
- 0
www/js_src/home.js View File

@@ -0,0 +1,126 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/


$(".view-main").on("ptr:refresh", ".ptr-content", function () {
restartApplication();
});

function editNote(id) {
var note = NOTES.get(id);
router.navigate("/editnote", {
context: {
noteid: id,
content: note.content,
notetitle: note.title,
}
});
console.log("Editing " + id);
}

function favoriteNote(id) {

}

function makeList(id) {

}

function deleteNote(id) {
app.dialog.confirm('Are you sure?', 'Delete Note', function () {
NOTES.del(id, function () {
app.ptr.refresh();
});
});
}

$("#app").on("click", ".edit-note-btn", function () {
editNote($(this).data("note"));
app.popover.close();
});

$("#app").on("click", ".favorite-note-btn", function () {
favoriteNote($(this).data("note"));
app.popover.close();
});

$("#app").on("click", ".listify-note-btn", function () {
makeList($(this).data("note"));
app.popover.close();
});

$("#app").on("click", ".delete-note-btn", function () {
deleteNote($(this).data("note"));
app.popover.close();
});

function openNoteActionMenu(notecard) {
var noteid = notecard.data("id");
if (window.innerWidth < 768) {
var actionsheet = app.actions.create({
buttons: [
{
text: "Edit",
bold: true,
icon: '<i class="fas fa-edit fa-fw"></i>',
onClick: function () {
editNote(noteid);
}
},
// {
// text: "Favorite",
// icon: '<i class="fas fa-star fa-fw"></i>',
// onClick: function () {
// favoriteNote(noteid);
// }
// },
// {
// text: "Make a List",
// icon: '<i class="fas fa-tasks fa-fw"></i>',
// onClick: function () {
// makeList(noteid);
// }
// },
{
text: "Delete",
icon: '<i class="fas fa-trash fa-fw"></i>',
onClick: function () {
deleteNote(noteid);
}
}
]
});

actionsheet.open();
return false;
} else {
var contextPopover = app.popover.create({
targetEl: notecard.children(".menubtn"),
content: '<div class="popover">' +
'<div class="popover-inner">' +
'<div class="list">' +
'<ul>' +
'<li><a class="list-button item-link edit-note-btn" data-note="' + noteid + '"><i class="fas fa-edit fa-fw"></i> Edit</a></li>' +
'<li><a class="list-button item-link favorite-note-btn" data-note="' + noteid + '"><i class="fas fa-star fa-fw"></i> Favorite</a></li>' +
'<li><a class="list-button item-link listify-note-btn" data-note="' + noteid + '"><i class="fas fa-tasks fa-fw"></i> Make a List</a></li>' +
'<li><a class="list-button item-link delete-note-btn" data-note="' + noteid + '"><i class="fas fa-trash fa-fw"></i> Delete</a></li>' +
'</ul>' +
'</div>' +
'</div>' +
'</div>'
});
contextPopover.open();
}
return false;
}

$(".view-main").on("click", ".notecard .menubtn", function () {
return openNoteActionMenu($(this).parent());
});

$(".view-main").on("contextmenu", ".notecard", function () {
return openNoteActionMenu($(this));
});

+ 70
- 0
www/js_src/main.js View File

@@ -0,0 +1,70 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

var $$ = Dom7;

var app = new Framework7({
root: "#app",
name: "NotePost",
id: "com.netsyms.NotePostApp",
init: true,
initOnDeviceReady: false,
routes: routes
});

var mainView = app.views.create('.view-main', {
url: "/"
});

var router = mainView.router;

var NOTES = null;

var OFFLINE = false;

/**
* Thanks to https://stackoverflow.com/a/13542669
* @param {type} color
* @param {type} percent
* @returns {String}
*/
function shadeColor2(color, percent) {
var f = parseInt(color.slice(1), 16), t = percent < 0 ? 0 : 255, p = percent < 0 ? percent * -1 : percent, R = f >> 16, G = f >> 8 & 0x00FF, B = f & 0x0000FF;
return "#" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
}

function restartApplication() {
window.location = "index.html";
}

router.on("pageInit", function (pagedata) {
pagedata.$el.find('script').each(function (el) {
if ($$(this).attr('src')) {
var s = document.createElement('script');
s.src = $$(this).attr('src');
$$('head').append(s);
} else {
eval($$(this).text());
}
});
switch (pagedata.name) {
case "settings":
updateSettingsData();
break;
}
});

// Run platform-specific setup code for Cordova or NW.js
initPlatform();


if (localStorage.getItem("configured") == null) {
// Open the setup page
router.navigate("/setup/0");
} else {
createNotesObject(function (n) {
NOTES = n;
router.navigate("/home");
});
}

+ 36
- 0
www/js_src/notes.js View File

@@ -0,0 +1,36 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

function createNotesObject(callback) {
if (localStorage.getItem("serverurl") == null) {
callback(new Notes());
} 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());
}
});
}
}

+ 71
- 0
www/js_src/platform.js View File

@@ -0,0 +1,71 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

var platform_type = "";

var openBrowser = function (url) {

}

function initCordova() {
platform_type = "cordova";

// Handle back button to close things
document.addEventListener("backbutton", function (event) {
router.navigate("/home");
}, false);

document.addEventListener("deviceready", function () {
if (cordova.platformId == 'android') {
StatusBar.backgroundColorByHexString("#D32F2F");
StatusBar.styleLightContent();
}
}, false);

openBrowser = function (url) {
cordova.InAppBrowser.open(url, '_blank', 'location=yes');
}
}

function initNW() {
platform_type = "nw";

openBrowser = function (url) {
nw.Window.open(url, {
id: url
}, function (browserwin) {
// Add menubar so the user can navigate around if they click a link
var browsermenu = new nw.Menu({type: 'menubar'});
browsermenu.append(new nw.MenuItem({
label: "Back",
click: function () {
browserwin.window.history.back();
}
}));
browsermenu.append(new nw.MenuItem({
label: "Forward",
click: function () {
browserwin.window.history.forward();
}
}));
browsermenu.append(new nw.MenuItem({
label: "Home",
click: function () {
browserwin.window.location.href = url;
}
}));
browserwin.menu = browsermenu;
});
}
}

function initPlatform() {
if (typeof cordova !== 'undefined') {
initCordova();
} else if (typeof nw !== 'undefined') {
initNW();
}
}

+ 103
- 0
www/js_src/setup1.js View File

@@ -0,0 +1,103 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/


netsymscomurl = "https://apps.netsyms.com/notepost";
netsymsbizurl = "https://BIZID.netsyms.biz/notepost";


$('#use-security-checkbox-li').click(function () {
// Event fires before the checkbox is changed, so we need to do the opposite
if ($("#use-security").prop("checked")) {
$('#protocol-select').text("https://");
} else {
$('#protocol-select').text("http://");
}
});

/* Detect if the user typed "http[s]://" into the URL box and correct for it */
$("#url").blur(function () {
if ($('#url').val().toLowerCase().startsWith("https://")) {