Rewrite editor (close #12), fix #11, close #13, close #14, close #15

master
Skylar Ittner 4 anni fa
parent a318a17c9f
commit b1c2d86d9a

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.netsyms.NotePostApp" version="1.2.0" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<widget id="com.netsyms.NotePostApp" version="1.3.0" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>NotePost</name>
<description>
A cross-platform client app for NotePost.
@ -51,5 +51,4 @@
<plugin name="cordova-plugin-app-version" spec="^0.1.9" />
<plugin name="cordova-plugin-inappbrowser" spec="^3.0.0" />
<engine name="browser" spec="^5.0.4" />
<engine name="android" spec="^7.1.4" />
</widget>

@ -1,7 +1,7 @@
{
"name": "com.netsyms.NotePostApp",
"displayName": "NotePost",
"version": "1.2.0",
"version": "1.3.0",
"description": "A cross-platform client app for NotePost.",
"main": "index.js",
"scripts": {
@ -10,7 +10,7 @@
"author": "Netsyms Technologies",
"license": "MPL-2.0",
"dependencies": {
"cordova-android": "^7.1.4",
"cordova-android": "^8.0.0",
"cordova-browser": "^5.0.4",
"cordova-plugin-app-version": "^0.1.9",
"cordova-plugin-headercolor": "^1.0.0",

@ -0,0 +1,21 @@
/*
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/.
*/
.popup {
background-color: var(--f7-page-bg-color);
}
.page[data-name="editor"] .page-content textarea#note {
width: 100%;
height: 100%;
resize: none;
border: none;
overflow: auto;
outline: none;
box-shadow: none;
font-size: 1rem;
padding: 0.75rem;
}

@ -8,8 +8,9 @@
<meta name="theme-color" content="#F44336">
<link rel="stylesheet" href="fonts/material/Material_Icons.css">
<link rel="stylesheet" href="fonts/roboto/Roboto.css">
<link rel="stylesheet" href="node_modules/framework7/css/framework7.min.css">
<link rel="stylesheet" href="node_modules/framework7/css/framework7.bundle.min.css">
<link rel="stylesheet" href="css/notecards.css">
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<title>NotePost</title>
@ -25,7 +26,7 @@
<script src="cordova.js"></script>
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/framework7/js/framework7.min.js"></script>
<script src="node_modules/framework7/js/framework7.bundle.min.js"></script>
<script src="node_modules/marked/marked.min.js"></script>
<script src="node_modules/shufflejs/dist/shuffle.min.js"></script>

@ -10,7 +10,7 @@ class Note {
if (typeof content != 'string') {
content = "";
}
if (typeof color != 'string') {
if (!/^[0-9A-F]{6}$/i.test(color)) {
color = "FFF59D";
}
if (typeof noteid != 'number') {
@ -186,7 +186,7 @@ class Note {
}
getTextColor() {
var color = this.getColor();
var color = this.getColor() + "";
var r = parseInt(color.substring(0, 2), 16);
var g = parseInt(color.substring(2, 4), 16);
var b = parseInt(color.substring(4, 6), 16);
@ -208,7 +208,7 @@ class Note {
}
setColor(color) {
if (typeof color !== 'string') {
if (!/^[0-9A-F]{6}$/i.test(color)) {
color = "FFF59D";
}
this.color = color;

@ -1,92 +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/.
*/
var save_in_progress = false;
function saveme(callback) {
if (save_in_progress) {
console.log("Warning: save already in progress, doing nothing.");
return;
}
app.toast.create({
text: '<i class="fas fa-sync fa-spin"></i> &nbsp; Saving...',
closeTimeout: 2 * 60 * 1000 // two whole minutes should be enough for *any* connection.
}).open();
save_in_progress = true;
sync(); // update textareas with correct content
var noteid = $("#note_content").data("noteid");
var note = new Note();
if (noteid != "") {
note = NOTES.get(noteid);
if (note.getSyncStatus() != "LOCAL_ONLY") {
note.setSyncStatus("LOCAL_EDITED");
}
}
note.setText($("#note_content").val());
note.setModified();
NOTES.set(note);
NOTES.syncAll(function () {
app.toast.create({
text: '<i class="fas fa-check"></i> &nbsp; Note saved.',
closeTimeout: 3000
}).open();
$("#orig_content").val(note.content);
save_in_progress = false;
if (typeof callback == "function") {
callback();
}
}, function () {
app.toast.create({
text: '<i class="fas fa-save"></i> &nbsp; Note saved locally.',
closeTimeout: 3000
}).open();
$("#orig_content").val(note.content);
save_in_progress = false;
if (typeof callback == "function") {
callback();
}
});
}
function init() {
document.getElementById("noteframe").contentWindow.initEditor($("#note_content").val());
}
/**
* Get the text from the editor iframe and put it in the hidden textarea
* @returns {undefined}
*/
function sync() {
$("#note_content").val(document.getElementById("noteframe").contentWindow.getMarkdown());
}
function exiteditor() {
sync();
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});
});
}
}
$(window).bind('keydown', function (event) {
if (event.ctrlKey || event.metaKey) {
switch (String.fromCharCode(event.which).toLowerCase()) {
case 's':
event.preventDefault();
sync();
saveme();
break;
}
}
});
$("#noteframe").on("load", function () {
init();
});

@ -1,4 +1,4 @@
/*
/*
* 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/.
@ -15,10 +15,11 @@ class MarkdownEditor {
for (var i = 0; i < buttons.length; i++) {
var div = document.createElement('div');
if (buttons[i]['spacer']) {
continue; // skip spacers
div.className = "toolbar-spacer";
div.innerHTML = "|";
} else {
div.className = "toolbar-button";
div.className = "link toolbar-button";
if (typeof buttons[i]['linestart'] == "string") {
div.setAttribute("data-linestart", buttons[i]['linestart']);
div.setAttribute("data-padspace", buttons[i]['padspace'] ? 1 : 0);
@ -140,4 +141,134 @@ class MarkdownEditor {
return text;
}
}
var editor;
function initEditor() {
editor = new MarkdownEditor(
document.getElementById('note'),
document.getElementById("editor-toolbar"),
[
{
label: "Bold",
icon: "fas fa-bold",
before: "**",
after: "**"
},
{
label: "Italic",
icon: "fas fa-italic",
before: "*",
after: "*"
},
{
label: "Heading",
icon: "fas fa-heading",
linestart: "#",
padspace: true,
maximum: 6
},
{
label: "Strikethrough",
icon: "fas fa-strikethrough",
before: "~~",
after: "~~"
},
{
spacer: true
},
{
label: "Quote",
icon: "fas fa-quote-left",
linestart: "> ",
padspace: false,
maximum: 6
},
{
label: "Checklist",
icon: "fas fa-tasks",
linestart: "- [ ]",
padspace: true,
maximum: 1
},
{
label: "List",
icon: "fas fa-list-ul",
linestart: "-",
padspace: true,
maximum: 1
}
]);
document.getElementById('note').addEventListener('keydown', function (event) {
if (event.ctrlKey || event.metaKey) {
switch (String.fromCharCode(event.which).toLowerCase()) {
case 's':
event.preventDefault();
savenote();
break;
}
}
});
}
function getMarkdown() {
return document.getElementById('note').value;
}
var save_in_progress = false;
function savenote(callback) {
if (save_in_progress) {
console.log("Warning: save already in progress, doing nothing.");
return;
}
app.toast.create({
text: '<i class="fas fa-sync fa-spin"></i> &nbsp; Saving...',
closeTimeout: 2 * 60 * 1000 // two whole minutes should be enough for *any* connection.
}).open();
save_in_progress = true;
var noteid = $("#note").data("noteid");
var note = new Note();
if (noteid != "") {
note = NOTES.get(noteid);
if (note.getSyncStatus() != "LOCAL_ONLY") {
note.setSyncStatus("LOCAL_EDITED");
}
}
note.setText($("#note").val());
note.setModified();
NOTES.set(note);
NOTES.syncAll(function () {
app.toast.create({
text: '<i class="fas fa-check"></i> &nbsp; Note saved.',
closeTimeout: 3000
}).open();
$("#orignote").val(note.content);
save_in_progress = false;
if (typeof callback == "function") {
callback();
}
}, function () {
app.toast.create({
text: '<i class="fas fa-save"></i> &nbsp; Note saved locally.',
closeTimeout: 3000
}).open();
$("#orignote").val(note.content);
save_in_progress = false;
if (typeof callback == "function") {
callback();
}
});
}
function exiteditor() {
if ($("#note").val() == "" || $("#note").val() === $("#orignote").val()) {
router.back({force: true, ignoreCache: true, reload: true});
} else {
savenote(function () {
router.back({force: true, ignoreCache: true, reload: true});
});
}
}

@ -147,7 +147,7 @@ function loadCards(callback) {
function editNote(id) {
var note = NOTES.get(id);
router.navigate("/editnote", {
router.navigate("/editor", {
context: {
noteid: id,
content: note.getText(),

@ -62,6 +62,10 @@ router.on("pageInit", function (pagedata) {
}
});
if (localStorage.getItem("darktheme") == "true") {
$("#app").addClass("theme-dark");
}
// Run platform-specific setup code for Cordova or NW.js
initPlatform();

@ -8,8 +8,10 @@ var platform_type = "";
var nw_tray = null;
var openBrowser = function (url) {
var app_version = "unknown";
var openBrowser = function (url) {
window.open(url);
}
var setTrayMenu = function (items) {
@ -154,6 +156,10 @@ function initNW() {
}
function initPlatform() {
$.getJSON("package.json", function (data) {
app_version = data.version;
});
if (typeof cordova !== 'undefined') {
initCordova();
} else if (typeof nw !== 'undefined') {

@ -7,6 +7,16 @@
$('.item-content[data-setting=editor] .toggle input').on("change", function () {
var checked = $(this).prop('checked');
console.log(checked);
localStorage.setItem("alternateeditor", checked);
})
});
$('.item-content[data-setting=darktheme] .toggle input').on("change", function () {
var checked = $(this).prop('checked');
localStorage.setItem("darktheme", checked);
if (localStorage.getItem("darktheme") == "true") {
$("#app").addClass("theme-dark");
} else {
$("#app").removeClass("theme-dark");
}
});

@ -1,16 +1,16 @@
{
"name": "com.netsyms.NotePostApp",
"displayName": "NotePost",
"version": "1.2.0",
"version": "1.3.0",
"description": "A cross-platform client app for NotePost.",
"author": "Netsyms Technologies",
"license": "MPL-2.0",
"dependencies": {
"@fortawesome/fontawesome-free": "^5.6.3",
"easymde": "^2.4.2",
"framework7": "^3.6.5",
"jquery": "^3.3.1",
"marked": "^0.6.0",
"shufflejs": "^5.2.1"
"@fortawesome/fontawesome-free": "^5.10.2",
"easymde": "^2.8.0",
"framework7": "^5.1.3",
"jquery": "^3.4.1",
"marked": "^0.7.0",
"shufflejs": "^5.2.3"
}
}

@ -4,6 +4,7 @@
<div class="page" data-name="credits">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only back">

@ -1,9 +1,10 @@
<!-- 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/. -->
<div class="page" data-name="editnote">
<div class="page" data-name="editor">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only" onclick="exiteditor()">
@ -19,21 +20,24 @@
{{/if}}</div>
<div class="right">
<a href="#" onclick="saveme()" class="link icon-only">
<a href="#" onclick="savenote()" class="link icon-only">
<i class="fas fa-save"></i>
</a>
</div>
</div>
</div>
<div class="page-content">
<textarea id="note_content" style="display: none;" data-noteid="{{noteid}}">{{content}}</textarea>
<textarea id="orig_content" style="display: none;">{{content}}</textarea>
<iframe id="noteframe" src="{{editorframe}}" style="width: 100%; height: 98%; border: 0px; padding: 0px; margin: 0px;"></iframe>
<div class="toolbar toolbar-top">
<div class="toolbar-inner" id="editor-toolbar">
</div>
</div>
<div class="page-content">
<textarea style="display: none;" id="orignote" data-noteid="{{noteid}}">{{content}}</textarea>
<textarea id="note" data-noteid="{{noteid}}">{{content}}</textarea>
</div>
<script src="js/editnote.js"></script>
<script src="js/editor.js"></script>
</div>

@ -1,84 +0,0 @@
<!DOCTYPE html>
<!--
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/.
-->
<title>Editor</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="../node_modules/easymde/dist/easymde.min.css">
<script src="../node_modules/easymde/dist/easymde.min.js"></script>
<style>
body {
margin: 0px;
font-family: Roboto, Noto, Helvetica, Arial, sans-serif;
}
.CodeMirror {
border: none;
margin-top: 45px;
height: calc(100vh - 45px);
}
.editor-toolbar {
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: 99999;
background-color: white;
border: none;
border-radius: 0px;
/* Following lines are from Framework7 .elevation-2 */
-webkit-box-shadow: 0px 3px 1px -2px rgba(0,0,0,.2),0px 2px 2px 0px rgba(0,0,0,.14),0px 1px 5px 0px rgba(0,0,0,.12);
box-shadow: 0px 3px 1px -2px rgba(0,0,0,.2),0px 2px 2px 0px rgba(0,0,0,.14),0px 1px 5px 0px rgba(0,0,0,.12);
/* end Framework7 code */
}
</style>
<textarea id="note"></textarea>
<script>
var easymde;
function initEditor(markdown) {
document.getElementById('note').value = markdown;
easymde = new EasyMDE({
element: document.getElementById("note"),
autoDownloadFontAwesome: false,
autofocus: true,
forceSync: true,
status: false,
spellChecker: false,
toolbar: [
"bold",
"italic",
"heading",
"strikethrough",
"|",
"quote",
"unordered-list",
"ordered-list",
"horizontal-rule"
]
});
window.addEventListener('keydown', function (event) {
if (event.ctrlKey || event.metaKey) {
switch (String.fromCharCode(event.which).toLowerCase()) {
case 's':
event.preventDefault();
window.parent.sync();
window.parent.saveme();
break;
}
}
});
}
function getMarkdown() {
return document.getElementById('note').value;
}
</script>

@ -1,152 +0,0 @@
<!DOCTYPE html>
<!--
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/.
-->
<title>Editor</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../node_modules/@fortawesome/fontawesome-free/css/all.min.css">
<script src="../js/markdowneditor.js"></script>
<style>
html, body {
margin: 0px;
font-family: Roboto, Noto, Helvetica, Arial, sans-serif;
width: 100%;
height: 100%;
overflow: hidden;
}
.editor-toolbar {
position: fixed;
top: 0;
right: 0;
left: 0;
height: 2.5rem;
z-index: 99999;
background-color: white;
border: none;
border-radius: 0px;
/* Following lines are from Framework7 .elevation-2 */
-webkit-box-shadow: 0px 3px 1px -2px rgba(0,0,0,.2),0px 2px 2px 0px rgba(0,0,0,.14),0px 1px 5px 0px rgba(0,0,0,.12);
box-shadow: 0px 3px 1px -2px rgba(0,0,0,.2),0px 2px 2px 0px rgba(0,0,0,.14),0px 1px 5px 0px rgba(0,0,0,.12);
/* end Framework7 code */
display: flex;
flex-direction: row;
padding-left: 0.5rem;
}
.toolbar-button {
cursor: pointer;
line-height: 2.5rem;
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.toolbar-spacer {
line-height: 2.5rem;
padding-left: 0.25rem;
padding-right: 0.25rem;
color: rgba(0,0,0,.5);
}
#note {
width: 100%;
height: calc(100% - 2rem);
margin-top: 2.5rem;
resize: none;
border: none;
overflow: auto;
outline: none;
box-shadow: none;
font-size: 1rem;
padding: 0.75rem;
}
</style>
<div class="editor-toolbar" id="toolbar">
<!--<div class="toolbar-button" data-before="**" data-after="**">
<i class="fas fa-bold fa-fw"></i>
</div>-->
</div>
<textarea id="note"></textarea>
<script>
var editor;
function initEditor(markdown) {
document.getElementById('note').value = markdown;
editor = new MarkdownEditor(
document.getElementById('note'),
document.getElementById("toolbar"),
[
{
label: "Bold",
icon: "fas fa-bold",
before: "**",
after: "**"
},
{
label: "Italic",
icon: "fas fa-italic",
before: "*",
after: "*"
},
{
label: "Heading",
icon: "fas fa-heading",
linestart: "#",
padspace: true,
maximum: 6
},
{
label: "Strikethrough",
icon: "fas fa-strikethrough",
before: "~~",
after: "~~"
},
{
spacer: true
},
{
label: "Quote",
icon: "fas fa-quote-left",
linestart: "> ",
padspace: false,
maximum: 6
},
{
label: "Checklist",
icon: "fas fa-tasks",
linestart: "- [ ]",
padspace: true,
maximum: 1
},
{
label: "List",
icon: "fas fa-list-ul",
linestart: "-",
padspace: true,
maximum: 1
}
]);
window.addEventListener('keydown', function (event) {
if (event.ctrlKey || event.metaKey) {
switch (String.fromCharCode(event.which).toLowerCase()) {
case 's':
event.preventDefault();
window.parent.sync();
window.parent.saveme();
break;
}
}
});
}
function getMarkdown() {
return document.getElementById('note').value;
}
</script>

@ -4,6 +4,7 @@
<div class="page" data-name="home">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="title">NotePost</div>
@ -59,7 +60,7 @@
</div>
<div class="fab fab-right-bottom">
<a href="/editnote">
<a href="/editor">
<i class="material-icons">add</i>
</a>
</div>

@ -5,6 +5,7 @@
<div class="page" data-name="prefs">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only back">
@ -17,10 +18,20 @@
<div class="page-content">
<div class="list media-list">
<div class="list media-list no-margin-top no-hairlines tablet-inset">
<ul>
{{#each settings}}
<li>
{{#if link}}
<div class="item-content item-link" data-setting="{{setting}}" onclick="{{onclick}}">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">{{title}}</div>
</div>
<div class="item-text">{{text}}</div>
</div>
</div>
{{else}}
{{#if toggle}}
<div class="item-content" data-setting="{{setting}}">
<div class="item-inner">
@ -39,6 +50,34 @@
</div>
</div>
{{else}}
{{#if slider}}
<div class="item-content" data-setting="{{setting}}">
<div class="item-inner">
<div class="item-title" style="background-color: rgba(0,0,0,0);">
{{title}}
</div>
<div class="item-subtitle padding-horizontal padding-top">
<div class="range-slider range-slider-init padding-top margin-top" data-label="true">
<input type="range" min="{{min}}" max="{{max}}" step="{{step}}" value="{{value}}">
</div>
</div>
</div>
</div>
{{else}}
{{#if select}}
<a class="item-link smart-select smart-select-init" data-open-in="popover" data-setting="{{setting}}">
<select>
{{#each options}}
<option value="{{value}}"{{#if selected}} selected{{/if}}>{{label}}</option>
{{/each}}
</select>
<div class="item-content">
<div class="item-inner">
<div class="item-title">{{title}}</div>
</div>
</div>
</a>
{{else}}
<div class="item-content" data-setting="{{setting}}" onclick="{{onclick}}">
<div class="item-inner">
<div class="item-title-row">
@ -48,6 +87,9 @@
</div>
</div>
{{/if}}
{{/if}}
{{/if}}
{{/if}}
</li>
{{/each}}
</ul>

@ -5,6 +5,7 @@
<div class="page" data-name="setup0">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only back">

@ -5,6 +5,7 @@
<div class="page" data-name="setup1">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left">
<a href="#" class="link icon-only back">

@ -81,19 +81,20 @@ var routes = [
{
setting: "account",
title: "Sign in to a different account",
link: true,
onclick: "router.navigate('/setup/0')"
},
{
setting: "editor",
title: "Use alternative editor",
text: "Turn on if you're having issues editing notes.",
setting: "darktheme",
title: "Use dark theme",
text: "Reduces eyestrain and saves power on some devices.",
toggle: true,
checked: localStorage.getItem("alternateeditor") == "true",
checked: localStorage.getItem("darktheme") == "true",
onclick: ""
},
{
setting: "versions",
title: "NotePost app v1.2.0",
title: "NotePost app v" + app_version,
text: "Copyright &copy; 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: ""
},
@ -101,12 +102,14 @@ var routes = [
setting: "opensource",
title: "Open Source Information",
text: "",
link: true,
onclick: "router.navigate('/credits')"
},
{
setting: "privacy",
title: "Privacy Policy",
text: "",
link: true,
onclick: "openBrowser('https://netsyms.com/legal?pk_campaign=NotePostApp')"
}]
}
@ -119,18 +122,14 @@ var routes = [
name: 'credits'
},
{
path: '/editnote',
name: 'editnote',
async: function (routeTo, routeFrom, resolve, reject) {
var editor = "pages/editor_full.html";
var alternative = "pages/editor_lite.html";
resolve({
templateUrl: './pages/editnote.html'
}, {
context: {
editorframe: localStorage.getItem("alternateeditor") == "true" ? alternative : editor
}
});
path: '/editor',
name: 'editor',
templateUrl: './pages/editor.html',
alias: '/editnote', // in case I missed any links
on: {
pageAfterIn: function () {
initEditor();
}
}
}
];
Caricamento…
Annulla
Salva