mirror of
https://github.com/zadam/trilium.git
synced 2025-10-30 09:56:36 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69cbfaae17 | ||
|
|
aebce8f12b | ||
|
|
045ca1f0bf | ||
|
|
bf2db6eac7 | ||
|
|
cf84114f91 | ||
|
|
6426157bb3 | ||
|
|
332fc16852 | ||
|
|
da2cd57428 | ||
|
|
de9bab1181 | ||
|
|
136375cf11 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "trilium",
|
"name": "trilium",
|
||||||
"description": "Trilium Notes",
|
"description": "Trilium Notes",
|
||||||
"version": "0.1.1",
|
"version": "0.1.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./bin/www",
|
"start": "node ./bin/www",
|
||||||
"test-electron": "xo",
|
"test-electron": "xo",
|
||||||
|
|||||||
@@ -57,6 +57,42 @@ $(document).bind('keydown', 'ctrl+f', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).bind('keydown', "ctrl+shift+left", () => {
|
||||||
|
const node = noteTree.getCurrentNode();
|
||||||
|
node.navigate($.ui.keyCode.LEFT, true);
|
||||||
|
|
||||||
|
$("#note-detail").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('keydown', "ctrl+shift+right", () => {
|
||||||
|
const node = noteTree.getCurrentNode();
|
||||||
|
node.navigate($.ui.keyCode.RIGHT, true);
|
||||||
|
|
||||||
|
$("#note-detail").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('keydown', "ctrl+shift+up", () => {
|
||||||
|
const node = noteTree.getCurrentNode();
|
||||||
|
node.navigate($.ui.keyCode.UP, true);
|
||||||
|
|
||||||
|
$("#note-detail").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('keydown', "ctrl+shift+down", () => {
|
||||||
|
const node = noteTree.getCurrentNode();
|
||||||
|
node.navigate($.ui.keyCode.DOWN, true);
|
||||||
|
|
||||||
|
$("#note-detail").focus();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
$(window).on('beforeunload', () => {
|
$(window).on('beforeunload', () => {
|
||||||
// this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved
|
// this makes sure that when user e.g. reloads the page or navigates away from the page, the note's content is saved
|
||||||
// this sends the request asynchronously and doesn't wait for result
|
// this sends the request asynchronously and doesn't wait for result
|
||||||
|
|||||||
@@ -128,6 +128,9 @@ const noteEditor = (function() {
|
|||||||
setNoteBackgroundIfProtected(currentNote);
|
setNoteBackgroundIfProtected(currentNote);
|
||||||
noteTree.setNoteTreeBackgroundBasedOnProtectedStatus(noteId);
|
noteTree.setNoteTreeBackgroundBasedOnProtectedStatus(noteId);
|
||||||
|
|
||||||
|
// after loading new note make sure editor is scrolled to the top
|
||||||
|
noteDetailWrapperEl.scrollTop(0);
|
||||||
|
|
||||||
showAppIfHidden();
|
showAppIfHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const noteTree = (function() {
|
|||||||
const treeEl = $("#tree");
|
const treeEl = $("#tree");
|
||||||
const parentListEl = $("#parent-list");
|
const parentListEl = $("#parent-list");
|
||||||
const parentListListEl = $("#parent-list-list");
|
const parentListListEl = $("#parent-list-list");
|
||||||
|
const noteDetailEl = $("#note-detail");
|
||||||
|
|
||||||
let startNotePath = null;
|
let startNotePath = null;
|
||||||
let notesTreeMap = {};
|
let notesTreeMap = {};
|
||||||
@@ -59,23 +60,6 @@ const noteTree = (function() {
|
|||||||
return treeUtils.getNotePath(node);
|
return treeUtils.getNotePath(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCurrentNoteId() {
|
|
||||||
const node = getCurrentNode();
|
|
||||||
|
|
||||||
return node ? node.data.note_id : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentClones() {
|
|
||||||
const noteId = getCurrentNoteId();
|
|
||||||
|
|
||||||
if (noteId) {
|
|
||||||
return getNodesByNoteId(noteId);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNodesByNoteTreeId(noteTreeId) {
|
function getNodesByNoteTreeId(noteTreeId) {
|
||||||
assertArguments(noteTreeId);
|
assertArguments(noteTreeId);
|
||||||
|
|
||||||
@@ -185,13 +169,15 @@ const noteTree = (function() {
|
|||||||
const noteTreeId = getNoteTreeId(parentNoteId, noteId);
|
const noteTreeId = getNoteTreeId(parentNoteId, noteId);
|
||||||
const noteTree = notesTreeMap[noteTreeId];
|
const noteTree = notesTreeMap[noteTreeId];
|
||||||
|
|
||||||
|
const title = (noteTree.prefix ? (noteTree.prefix + " - ") : "") + noteIdToTitle[noteTree.note_id];
|
||||||
|
|
||||||
const node = {
|
const node = {
|
||||||
note_id: noteTree.note_id,
|
note_id: noteTree.note_id,
|
||||||
parent_note_id: noteTree.parent_note_id,
|
parent_note_id: noteTree.parent_note_id,
|
||||||
note_tree_id: noteTree.note_tree_id,
|
note_tree_id: noteTree.note_tree_id,
|
||||||
is_protected: noteTree.is_protected,
|
is_protected: noteTree.is_protected,
|
||||||
prefix: noteTree.prefix,
|
prefix: noteTree.prefix,
|
||||||
title: (noteTree.prefix ? (noteTree.prefix + " - ") : "") + noteIdToTitle[noteTree.note_id],
|
title: escapeHtml(title),
|
||||||
extraClasses: getExtraClasses(noteTree),
|
extraClasses: getExtraClasses(noteTree),
|
||||||
refKey: noteTree.note_id,
|
refKey: noteTree.note_id,
|
||||||
expanded: noteTree.is_expanded
|
expanded: noteTree.is_expanded
|
||||||
@@ -432,6 +418,30 @@ const noteTree = (function() {
|
|||||||
"alt+-": node => {
|
"alt+-": node => {
|
||||||
collapseTree(node);
|
collapseTree(node);
|
||||||
},
|
},
|
||||||
|
"ctrl+c": node => {
|
||||||
|
contextMenu.copy(node);
|
||||||
|
|
||||||
|
showMessage("Note copied into clipboard.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"ctrl+x": node => {
|
||||||
|
contextMenu.cut(node);
|
||||||
|
|
||||||
|
showMessage("Note cut into clipboard.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"ctrl+v": node => {
|
||||||
|
contextMenu.pasteInto(node);
|
||||||
|
|
||||||
|
showMessage("Note pasted from clipboard into current note.");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
"ctrl+return": node => {
|
||||||
|
noteDetailEl.focus();
|
||||||
|
},
|
||||||
// code below shouldn't be necessary normally, however there's some problem with interaction with context menu plugin
|
// code below shouldn't be necessary normally, however there's some problem with interaction with context menu plugin
|
||||||
// after opening context menu, standard shortcuts don't work, but they are detected here
|
// after opening context menu, standard shortcuts don't work, but they are detected here
|
||||||
// so we essentially takeover the standard handling with our implementation.
|
// so we essentially takeover the standard handling with our implementation.
|
||||||
@@ -513,57 +523,6 @@ const noteTree = (function() {
|
|||||||
mode: "hide" // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
|
mode: "hide" // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
|
||||||
},
|
},
|
||||||
dnd: dragAndDropSetup,
|
dnd: dragAndDropSetup,
|
||||||
keydown: (event, data) => {
|
|
||||||
const node = data.node;
|
|
||||||
// Eat keyboard events, when a menu is open
|
|
||||||
if ($(".contextMenu:visible").length > 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (event.which) {
|
|
||||||
// Open context menu on [Space] key (simulate right click)
|
|
||||||
case 32: // [Space]
|
|
||||||
$(node.span).trigger("mousedown", {
|
|
||||||
preventDefault: true,
|
|
||||||
button: 2
|
|
||||||
})
|
|
||||||
.trigger("mouseup", {
|
|
||||||
preventDefault: true,
|
|
||||||
pageX: node.span.offsetLeft,
|
|
||||||
pageY: node.span.offsetTop,
|
|
||||||
button: 2
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Handle Ctrl+C, +X and +V
|
|
||||||
case 67:
|
|
||||||
if (event.ctrlKey) { // Ctrl+C
|
|
||||||
contextMenu.copy(node);
|
|
||||||
|
|
||||||
showMessage("Note copied into clipboard.");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 88:
|
|
||||||
if (event.ctrlKey) { // Ctrl+X
|
|
||||||
contextMenu.cut(node);
|
|
||||||
|
|
||||||
showMessage("Note cut into clipboard.");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 86:
|
|
||||||
if (event.ctrlKey) { // Ctrl+V
|
|
||||||
contextMenu.pasteInto(node);
|
|
||||||
|
|
||||||
showMessage("Note pasted from clipboard into current note.");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
lazyLoad: function(event, data){
|
lazyLoad: function(event, data){
|
||||||
const node = data.node.data;
|
const node = data.node.data;
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,12 @@ const treeChanges = (function() {
|
|||||||
await server.put('notes/' + node.data.note_tree_id + '/move-to/' + toNode.data.note_id);
|
await server.put('notes/' + node.data.note_tree_id + '/move-to/' + toNode.data.note_id);
|
||||||
|
|
||||||
changeNode(node, node => {
|
changeNode(node, node => {
|
||||||
node.moveTo(toNode);
|
// first expand which will force lazy load and only then move the node
|
||||||
|
// if this is not expanded before moving, then lazy load won't happen because it already contains node
|
||||||
toNode.setExpanded(true);
|
toNode.setExpanded(true);
|
||||||
|
|
||||||
|
node.moveTo(toNode);
|
||||||
|
|
||||||
toNode.folder = true;
|
toNode.folder = true;
|
||||||
toNode.renderTitle();
|
toNode.renderTitle();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const treeUtils = (function() {
|
|||||||
|
|
||||||
const title = (prefix ? (prefix + " - ") : "") + noteTitle;
|
const title = (prefix ? (prefix + " - ") : "") + noteTitle;
|
||||||
|
|
||||||
node.setTitle(title);
|
node.setTitle(escapeHtml(title));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -94,3 +94,7 @@ function isTopLevelNode(node) {
|
|||||||
function isRootNode(node) {
|
function isRootNode(node) {
|
||||||
return node.key === "root_1";
|
return node.key === "root_1";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function escapeHtml(str) {
|
||||||
|
return $('<div/>').text(str).html();
|
||||||
|
}
|
||||||
@@ -74,6 +74,12 @@ span.fancytree-node.fancytree-active-clone:not(.fancytree-active) .fancytree-tit
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* By default not focused active tree item is not easily visible, this makes it more visible */
|
||||||
|
span.fancytree-active:not(.fancytree-focused) .fancytree-title {
|
||||||
|
background-color: #ddd !important;
|
||||||
|
border-color: #555 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.ui-autocomplete {
|
.ui-autocomplete {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|||||||
@@ -3,12 +3,9 @@
|
|||||||
const migration = require('./migration');
|
const migration = require('./migration');
|
||||||
const sql = require('./sql');
|
const sql = require('./sql');
|
||||||
const utils = require('./utils');
|
const utils = require('./utils');
|
||||||
const options = require('./options');
|
|
||||||
|
|
||||||
async function checkAuth(req, res, next) {
|
async function checkAuth(req, res, next) {
|
||||||
const username = await options.getOption('username');
|
if (!await sql.isUserInitialized()) {
|
||||||
|
|
||||||
if (!username) {
|
|
||||||
res.redirect("setup");
|
res.redirect("setup");
|
||||||
}
|
}
|
||||||
else if (!req.session.loggedIn && !utils.isElectron()) {
|
else if (!req.session.loggedIn && !utils.isElectron()) {
|
||||||
@@ -53,9 +50,7 @@ async function checkApiAuthForMigrationPage(req, res, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function checkAppNotInitialized(req, res, next) {
|
async function checkAppNotInitialized(req, res, next) {
|
||||||
const username = await options.getOption('username');
|
if (await sql.isUserInitialized()) {
|
||||||
|
|
||||||
if (username) {
|
|
||||||
res.status(400).send("App already initialized.");
|
res.status(400).send("App already initialized.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
module.exports = { build_date:"2017-12-27T17:41:07-05:00", build_revision: "6405d6e06658188f14f29b0a2e1891e5287000f5" };
|
module.exports = { build_date:"2017-12-28T21:17:25-05:00", build_revision: "aebce8f12b87e7c3d5dbd23e75918f3d01a4cc64" };
|
||||||
|
|||||||
@@ -49,9 +49,7 @@ const dbReady = new Promise((resolve, reject) => {
|
|||||||
// the database
|
// the database
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'");
|
if (!await isUserInitialized()) {
|
||||||
|
|
||||||
if (!username) {
|
|
||||||
log.info("Login/password not initialized. DB not ready.");
|
log.info("Login/password not initialized. DB not ready.");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -235,8 +233,15 @@ async function isDbUpToDate() {
|
|||||||
return upToDate;
|
return upToDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function isUserInitialized() {
|
||||||
|
const username = await getFirstValue("SELECT opt_value FROM options WHERE opt_name = 'username'");
|
||||||
|
|
||||||
|
return !!username;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
dbReady,
|
dbReady,
|
||||||
|
isUserInitialized,
|
||||||
insert,
|
insert,
|
||||||
replace,
|
replace,
|
||||||
getFirstValue,
|
getFirstValue,
|
||||||
|
|||||||
Reference in New Issue
Block a user