Merge branch 'main' into feat/sharehandler

This commit is contained in:
quenousimporte 2023-08-28 11:35:01 +02:00
commit 38b30eec43
3 changed files with 86 additions and 14 deletions

46
main.js
View File

@ -98,6 +98,15 @@ var themes =
lineheight: "24px", lineheight: "24px",
accentcolor: "#5AA7CE" accentcolor: "#5AA7CE"
}, },
"White monkey":
{
bgcolor: "white",
fontfamily: "'Inconsolata', 'Consolas', monospace",
fontsize: "18px",
fontcolor: "black",
lineheight: "150%",
accentcolor: "#5AA7CE"
},
Mariana: Mariana:
{ {
bgcolor: "rgb(48,56,65)", bgcolor: "rgb(48,56,65)",
@ -207,6 +216,12 @@ var commands = [
hint: "Restore note", hint: "Restore note",
action: restore action: restore
}, },
{
shortcut: "ctrl+h",
hint: "Insert markdown header",
action: insertheader,
allowunsaved: true
},
{ {
shortcut: "F1", shortcut: "F1",
hint: "Show help", hint: "Show help",
@ -495,6 +510,11 @@ function formatsize(size)
return size.toFixed(2) + " " + unit; return size.toFixed(2) + " " + unit;
} }
function pospercent()
{
return md.value.length > 0 ?(100 * md.selectionStart / md.value.length).toFixed(2) : 100;
}
function showinfo() function showinfo()
{ {
var tags = gettags(currentnote); var tags = gettags(currentnote);
@ -503,7 +523,7 @@ function showinfo()
"vault: " + currentvault, "vault: " + currentvault,
"saved: " + saved, "saved: " + saved,
"title: " + currentnote.title, "title: " + currentnote.title,
"cursor position: " + md.selectionStart + " (" + (100 * md.selectionStart / md.value.length).toFixed(2) + "%)", "cursor position: " + md.selectionStart + " (" + pospercent() + "%)",
(tags ? "tags: " + tags : ""), (tags ? "tags: " + tags : ""),
"spell check: " + (md.spellcheck ? "en" : "dis") + "abled", "spell check: " + (md.spellcheck ? "en" : "dis") + "abled",
"notes count: " + localdata.length, "notes count: " + localdata.length,
@ -1130,7 +1150,7 @@ function loadsettings()
applystyle(); applystyle();
if (settings.titlebydefault) if (settings.titlebydefault && title.hidden)
{ {
toggletitle(); toggletitle();
} }
@ -2096,6 +2116,17 @@ function restore()
} }
} }
function insertheader()
{
if (preview.hidden && !md.value.startsWith("---\n"))
{
var headers = "---\ndate: " + (new Date).toISOString().substring(0, 10) + "\ntags: \n---\n\n";
md.value = headers + md.value;
setpos(27);
}
resize();
}
function splitshortcut(s) function splitshortcut(s)
{ {
var r = {}; var r = {};
@ -2210,14 +2241,23 @@ function ontitlechange()
datachanged(); datachanged();
setwindowtitle(); setwindowtitle();
if (!settings.titlebydefault)
{
toggletitle(); toggletitle();
} }
}
function simplifystring(str)
{
return str.toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, "");
}
function applyfilter() function applyfilter()
{ {
[...filteredlist.children].forEach(div => [...filteredlist.children].forEach(div =>
{ {
div.hidden = div.textContent.toLowerCase().indexOf(filter.value.toLowerCase()) < 0; div.hidden = simplifystring(div.textContent).indexOf(simplifystring(filter.value)) < 0;
}); });
fileindex = 0; fileindex = 0;

View File

@ -1,6 +1,7 @@
const axios = require("axios"); const axios = require("axios");
const readline = require("readline"); const readline = require("readline");
const fs = require("fs"); const fs = require("fs");
const openpgp = require("openpgp");
var cp = require("child_process"); var cp = require("child_process");
var rl = readline.createInterface({ var rl = readline.createInterface({
@ -9,14 +10,43 @@ var rl = readline.createInterface({
}); });
var settings = JSON.parse(fs.readFileSync("settings.json", { encoding: "utf8", flag: "r" })); var settings = JSON.parse(fs.readFileSync("settings.json", { encoding: "utf8", flag: "r" }));
var pgpkey = fs.readFileSync("key.acs", { encoding: "utf8", flag: "r" });
var filter = process.argv.length > 2 ? process.argv[2] : ""; var filter = process.argv.length > 2 ? process.argv[2] : "";
var intervalid = null; var intervalid = null;
var notes = null; var notes = null;
function simplifystring(str)
{
return str.toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, "");
}
async function decrypt(str)
{
var key = pgpkey.split("-----END PGP PUBLIC KEY BLOCK-----")[1];
var privateKey = await openpgp.readKey({ armoredKey: key });
var decrypted = await openpgp.decrypt({
message: await openpgp.readMessage({ armoredMessage: str }),
decryptionKeys: privateKey });
const chunks = [];
for await (const chunk of decrypted.data) {
chunks.push(chunk);
}
return chunks.join('');
}
async function encrypt(str)
{
var key = pgpkey.split("-----BEGIN PGP PRIVATE KEY BLOCK-----")[0];
var publicKey = await openpgp.readKey({ armoredKey: key });
return await openpgp.encrypt({
message: await openpgp.createMessage({ text: str }),
encryptionKeys: publicKey });
}
function filteredlist() function filteredlist()
{ {
return notes return notes
.filter(n => n.title.toLowerCase().includes(filter.toLowerCase())); .filter(n => simplifystring(n.title).includes(simplifystring(filter)));
} }
axios.post(`${settings.url}/handler.php`, axios.post(`${settings.url}/handler.php`,
@ -30,27 +60,27 @@ axios.post(`${settings.url}/handler.php`,
"Content-type": "application/x-www-form-urlencoded" "Content-type": "application/x-www-form-urlencoded"
} }
}) })
.then(res => .then(async function(res)
{ {
notes = res.data; notes = JSON.parse(await decrypt(res.data));
filteredlist() filteredlist()
.every( (note, i) => .every( (note, i) =>
{ {
console.log(`[${i}] ${note.title}`) console.log(`[${i}] ${note.title}`)
return i < settings.maxcount; return Boolean(filter) || i < settings.maxcountifnofilter;
}); });
// todo: open if only one match. quit if no match // todo: open if only one match. quit if no match
rl.prompt(); rl.prompt();
rl.on("line", (line) => rl.on("line", async function (line)
{ {
var note = filteredlist()[line]; var note = filteredlist()[line];
// todo: use title instead? To put in data folder? // todo: use title instead? To put in data folder?
fs.writeFileSync("note.md", note.content); fs.writeFileSync("note.md", note.content);
cp.exec(`${settings.command} note.md`, function (err, stdout, stderr) cp.exec(`${settings.command} note.md`, async function (err, stdout, stderr)
{ {
clearInterval(intervalid); clearInterval(intervalid);
var newcontent = fs.readFileSync("note.md", { encoding: "utf8", flag: "r" }); var newcontent = fs.readFileSync("note.md", { encoding: "utf8", flag: "r" });
@ -62,11 +92,12 @@ axios.post(`${settings.url}/handler.php`,
notes.unshift(note); notes.unshift(note);
console.log("sending data file to server..."); console.log("sending data file to server...");
var encrypted = await encrypt(JSON.stringify(notes));
axios.post(`${settings.url}/handler.php`, axios.post(`${settings.url}/handler.php`,
{ {
action: "push", action: "push",
password: settings.password, password: settings.password,
data: JSON.stringify(notes) data: encrypted
}, },
{ {
headers: headers:
@ -83,7 +114,7 @@ axios.post(`${settings.url}/handler.php`,
} }
}) })
intervalid = setInterval(function() intervalid = setInterval(async function()
{ {
//todo: refactor "save" //todo: refactor "save"
var newcontent = fs.readFileSync("note.md", { encoding: "utf8", flag: "r" }); var newcontent = fs.readFileSync("note.md", { encoding: "utf8", flag: "r" });
@ -95,11 +126,12 @@ axios.post(`${settings.url}/handler.php`,
notes.unshift(note); notes.unshift(note);
console.log("sending data file to server..."); console.log("sending data file to server...");
var encrypted = await encrypt(JSON.stringify(notes));
axios.post(`${settings.url}/handler.php`, axios.post(`${settings.url}/handler.php`,
{ {
action: "push", action: "push",
password: settings.password, password: settings.password,
data: JSON.stringify(notes) data: encrypted
}, },
{ {
headers: headers:

View File

@ -1,6 +1,6 @@
{ {
"password": "", "password": "",
"url": "http://localhost:8000", "url": "http://localhost:8000",
"maxcount": 50, "maxcountifnofilter": 10,
"command": "sublime_text.exe -w" "command": "sublime_text.exe -w"
} }