diff --git a/db/demo.tar b/db/demo.tar index 2748822c9..1f2691b2e 100644 Binary files a/db/demo.tar and b/db/demo.tar differ diff --git a/src/public/javascripts/dialogs/recent_changes.js b/src/public/javascripts/dialogs/recent_changes.js index af2a94bd4..703cb145f 100644 --- a/src/public/javascripts/dialogs/recent_changes.js +++ b/src/public/javascripts/dialogs/recent_changes.js @@ -44,7 +44,10 @@ export async function showDialog() { const note = await treeCache.getNote(change.noteId); const notePath = await treeService.getSomeNotePath(note); - noteLink = await linkService.createNoteLinkWithPath(notePath, change.title); + noteLink = await linkService.createNoteLink(notePath, { + title: change.title, + showNotePath: true + }); } changesListEl.append($('
  • ') diff --git a/src/public/javascripts/services/entrypoints.js b/src/public/javascripts/services/entrypoints.js index 3c934b170..5a2298de7 100644 --- a/src/public/javascripts/services/entrypoints.js +++ b/src/public/javascripts/services/entrypoints.js @@ -255,6 +255,8 @@ function registerEntrypoints() { await treeService.expandToNote(note.noteId); await noteDetailService.openInTab(note.noteId, true); + + noteDetailService.focusAndSelectTitle(); }); keyboardActionService.setGlobalActionHandler("EditBranchPrefix", async () => { diff --git a/src/public/javascripts/services/frontend_script_api.js b/src/public/javascripts/services/frontend_script_api.js index d17ad38d3..06bc5e839 100644 --- a/src/public/javascripts/services/frontend_script_api.js +++ b/src/public/javascripts/services/frontend_script_api.js @@ -125,14 +125,14 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte } /** - * Executes given anonymous function on the server. + * Executes given anonymous function on the backend. * Internally this serializes the anonymous function into string and sends it to backend via AJAX. * * @param {string} script - script to be executed on the backend * @param {Array.} params - list of parameters to the anonymous function to be send to backend * @return {Promise<*>} return value of the executed function on the backend */ - this.runOnServer = async (script, params = []) => { + this.runOnBackend = async (script, params = []) => { if (typeof script === "function") { script = script.toString(); } @@ -159,6 +159,12 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte } }; + /** + * @deprecated new name of this API call is runOnBackend so use that + * @method + */ + this.runOnServer = this.runOnBackend; + /** * This is a powerful search method - you can search by attributes and their values, e.g.: * "@dateModified =* MONTH AND @log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search diff --git a/src/public/javascripts/services/link.js b/src/public/javascripts/services/link.js index dcf210d5d..c1f74bf9a 100644 --- a/src/public/javascripts/services/link.js +++ b/src/public/javascripts/services/link.js @@ -9,7 +9,11 @@ function getNotePathFromUrl(url) { return notePathMatch === null ? null : notePathMatch[1]; } -async function createNoteLink(notePath, noteTitle = null, tooltip = true) { +async function createNoteLink(notePath, options = {}) { + let noteTitle = options.title; + const showTooltip = options.showTooltip === undefined ? true : options.showTooltip; + const showNotePath = options.showNotePath === undefined ? false : options.showNotePath; + if (!noteTitle) { const {noteId, parentNoteId} = treeUtils.getNoteIdAndParentIdFromNotePath(notePath); @@ -22,30 +26,26 @@ async function createNoteLink(notePath, noteTitle = null, tooltip = true) { }).attr('data-action', 'note') .attr('data-note-path', notePath); - if (!tooltip) { + if (!showTooltip) { $noteLink.addClass("no-tooltip-preview"); } - return $noteLink; -} + const $container = $("").append($noteLink); -async function createNoteLinkWithPath(notePath, noteTitle = null) { - const $link = await createNoteLink(notePath, noteTitle); + if (showNotePath) { + notePath = await treeService.resolveNotePath(notePath); - const $res = $("").append($link); - - if (notePath.includes("/")) { const noteIds = notePath.split("/"); noteIds.pop(); // remove last element const parentNotePath = noteIds.join("/").trim(); if (parentNotePath) { - $res.append($("").text(" (" + await treeUtils.getNotePathTitle(parentNotePath) + ")")); + $container.append($("").text(" (" + await treeUtils.getNotePathTitle(parentNotePath) + ")")); } } - return $res; + return $container; } function getNotePathFromLink($link) { @@ -180,7 +180,6 @@ $(document).on('contextmenu', ".note-detail-render a", newTabContextMenu); export default { getNotePathFromUrl, createNoteLink, - createNoteLinkWithPath, addLinkToEditor, addTextToEditor, goToLink diff --git a/src/public/javascripts/services/link_map.js b/src/public/javascripts/services/link_map.js index 967415a97..37bc0c77f 100644 --- a/src/public/javascripts/services/link_map.js +++ b/src/public/javascripts/services/link_map.js @@ -88,7 +88,7 @@ export default class LinkMap { .addClass("note-box") .prop("id", noteBoxId); - linkService.createNoteLink(noteId, note.title).then($link => { + linkService.createNoteLink(noteId, {title: note.title}).then($link => { $link.on('click', e => { try { $link.tooltip('dispose'); diff --git a/src/public/javascripts/services/note_detail_book.js b/src/public/javascripts/services/note_detail_book.js index 09ed86bf5..f2bbd8e5e 100644 --- a/src/public/javascripts/services/note_detail_book.js +++ b/src/public/javascripts/services/note_detail_book.js @@ -137,7 +137,7 @@ class NoteDetailBook { .attr('data-note-id', childNote.noteId) .css("flex-basis", ZOOMS[this.zoomLevel].width) .addClass("type-" + type) - .append($('
    ').append(await linkService.createNoteLink(childNotePath, null, false))) + .append($('
    ').append(await linkService.createNoteLink(childNotePath, {showTooltip: false}))) .append($('
    ') .css("max-height", ZOOMS[this.zoomLevel].height) .append(await this.getNoteContent(type, childNote))); diff --git a/src/public/javascripts/services/note_detail_file.js b/src/public/javascripts/services/note_detail_file.js index 0a3dea656..4f91dceb1 100644 --- a/src/public/javascripts/services/note_detail_file.js +++ b/src/public/javascripts/services/note_detail_file.js @@ -39,8 +39,11 @@ class NoteDetailFile { }); this.$uploadNewRevisionInput.on('change', async () => { + const fileToUpload = this.$uploadNewRevisionInput[0].files[0]; // copy to allow reset below + this.$uploadNewRevisionInput.val(''); + const formData = new FormData(); - formData.append('upload', this.$uploadNewRevisionInput[0].files[0]); + formData.append('upload', fileToUpload); const result = await $.ajax({ url: baseApiUrl + 'notes/' + this.ctx.note.noteId + '/file', diff --git a/src/public/javascripts/services/note_detail_image.js b/src/public/javascripts/services/note_detail_image.js index f877dce48..c0216a40e 100644 --- a/src/public/javascripts/services/note_detail_image.js +++ b/src/public/javascripts/services/note_detail_image.js @@ -48,8 +48,11 @@ class NoteDetailImage { }); this.$uploadNewRevisionInput.on('change', async () => { + const fileToUpload = this.$uploadNewRevisionInput[0].files[0]; // copy to allow reset below + this.$uploadNewRevisionInput.val(''); + const formData = new FormData(); - formData.append('upload', this.$uploadNewRevisionInput[0].files[0]); + formData.append('upload', fileToUpload); const result = await $.ajax({ url: baseApiUrl + 'images/' + this.ctx.note.noteId, diff --git a/src/public/javascripts/services/note_detail_relation_map.js b/src/public/javascripts/services/note_detail_relation_map.js index 45feb0d92..c46ffde32 100644 --- a/src/public/javascripts/services/note_detail_relation_map.js +++ b/src/public/javascripts/services/note_detail_relation_map.js @@ -494,7 +494,7 @@ class NoteDetailRelationMap { } async createNoteBox(noteId, title, x, y) { - const $link = await linkService.createNoteLink(noteId, title); + const $link = await linkService.createNoteLink(noteId, {title}); $link.mousedown(e => { console.log(e); diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index 22461f36a..86aa65fa9 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -11,8 +11,6 @@ import protectedSessionService from "./protected_session.js"; import optionsService from "./options.js"; import linkService from "./link.js"; import Sidebar from "./sidebar.js"; -import libraryLoader from "./library_loader.js"; -import noteAutocompleteService from "./note_autocomplete.js"; const $tabContentsContainer = $("#note-tab-container"); @@ -291,6 +289,10 @@ class TabContext { } getComponent() { + if (!this.components[this.type]) { + throw new Error("Could not find component for type: " + this.type); + } + return this.components[this.type]; } @@ -377,7 +379,7 @@ class TabContext { async addPath(notePath, isCurrent) { const title = await treeUtils.getNotePathTitle(notePath); - const noteLink = await linkService.createNoteLink(notePath, title); + const noteLink = await linkService.createNoteLink(notePath, {title}); noteLink .addClass("no-tooltip-preview") diff --git a/src/public/javascripts/services/tree.js b/src/public/javascripts/services/tree.js index 28920c6d2..ba8cf9f22 100644 --- a/src/public/javascripts/services/tree.js +++ b/src/public/javascripts/services/tree.js @@ -127,16 +127,16 @@ async function getNodeFromPath(notePath, expand = false, expandOpts = {}) { // we expand only after hoisted note since before then nodes are not actually present in the tree if (parentNode) { - checkFolderStatus(parentNode); - if (!parentNode.isLoaded()) { await parentNode.load(); } if (expand) { - parentNode.setExpanded(true, expandOpts); + await parentNode.setExpanded(true, expandOpts); } + await checkFolderStatus(parentNode); + let foundChildNode = findChildNode(parentNode, childNoteId); if (!foundChildNode) { // note might be recently created so we'll force reload and try again diff --git a/src/public/javascripts/setup.js b/src/public/javascripts/setup.js index 4511679b1..65542cc47 100644 --- a/src/public/javascripts/setup.js +++ b/src/public/javascripts/setup.js @@ -131,12 +131,15 @@ async function checkOutstandingSyncs() { const { stats, initialized } = await $.get('api/sync/stats'); if (initialized) { - window.location.replace("./"); + const remote = require('electron').remote; + remote.app.relaunch(); + remote.app.exit(0); } + else { + const totalOutstandingSyncs = stats.outstandingPushes + stats.outstandingPulls; - const totalOutstandingSyncs = stats.outstandingPushes + stats.outstandingPulls; - - $("#outstanding-syncs").html(totalOutstandingSyncs); + $("#outstanding-syncs").html(totalOutstandingSyncs); + } } function showAlert(message) { diff --git a/src/public/javascripts/widgets/edited_notes.js b/src/public/javascripts/widgets/edited_notes.js index ee7dbe793..01ebf07b1 100644 --- a/src/public/javascripts/widgets/edited_notes.js +++ b/src/public/javascripts/widgets/edited_notes.js @@ -45,7 +45,7 @@ class EditedNotesWidget extends StandardWidget { $item.append($("").text(editedNote.title + " (deleted)")); } else { - $item.append(editedNote.notePath ? await linkService.createNoteLinkWithPath(editedNote.notePath.join("/")) : editedNote.title); + $item.append(editedNote.notePath ? await linkService.createNoteLink(editedNote.notePath.join("/"), {showNotePath: true}) : editedNote.title); } $list.append($item); diff --git a/src/public/javascripts/widgets/similar_notes.js b/src/public/javascripts/widgets/similar_notes.js index e4e338032..21e6d2b41 100644 --- a/src/public/javascripts/widgets/similar_notes.js +++ b/src/public/javascripts/widgets/similar_notes.js @@ -39,7 +39,7 @@ class SimilarNotesWidget extends StandardWidget { } const $item = $("
  • ") - .append(await linkService.createNoteLinkWithPath(similarNote.notePath.join("/"))); + .append(await linkService.createNoteLink(similarNote.notePath.join("/"), {showNotePath: true})); $list.append($item); } diff --git a/src/public/stylesheets/desktop.css b/src/public/stylesheets/desktop.css index 02dbbbebe..ec787b29b 100644 --- a/src/public/stylesheets/desktop.css +++ b/src/public/stylesheets/desktop.css @@ -57,6 +57,7 @@ body { } #left-pane { + height: 100%; display: flex; flex-direction: column; } diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index d3544296c..7d81adb82 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -105,6 +105,7 @@ span.fancytree-node.muted { opacity: 0.6; } flex-direction: column; flex-grow: 100; height: 100%; + width: 100%; } .note-detail-component-wrapper { diff --git a/src/services/auth.js b/src/services/auth.js index bb19b9ca1..f1192fa5f 100644 --- a/src/services/auth.js +++ b/src/services/auth.js @@ -83,7 +83,7 @@ async function checkBasicAuth(req, res, next) { const dbUsername = await optionService.getOption('username'); if (dbUsername !== username || !await passwordEncryptionService.verifyPassword(password)) { - res.status(401).send("Not authorized"); + res.status(401).send('Incorrect username and/or password'); } else { next();