From 8ec01c73cdac5770cc80fafb553a43da9d1e5f1c Mon Sep 17 00:00:00 2001 From: zadam Date: Tue, 1 Oct 2019 21:11:11 +0200 Subject: [PATCH] skeleton implementation of new "book" note type --- package-lock.json | 2 +- src/public/javascripts/services/link.js | 6 +- .../javascripts/services/note_detail_book.js | 63 +++++++++++++++++++ src/public/javascripts/services/note_type.js | 1 + .../javascripts/services/tab_context.js | 48 +++++++------- .../javascripts/services/tree_builder.js | 29 ++++----- src/public/stylesheets/style.css | 7 +++ src/services/consistency_checks.js | 2 +- src/views/details/book.ejs | 1 + src/views/tabs.ejs | 2 + 10 files changed, 116 insertions(+), 45 deletions(-) create mode 100644 src/public/javascripts/services/note_detail_book.js create mode 100644 src/views/details/book.ejs diff --git a/package-lock.json b/package-lock.json index 937052b71..ab5efb20b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "trilium", - "version": "0.35.0-beta", + "version": "0.35.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/public/javascripts/services/link.js b/src/public/javascripts/services/link.js index 1d66bd27e..27d54aa95 100644 --- a/src/public/javascripts/services/link.js +++ b/src/public/javascripts/services/link.js @@ -21,13 +21,15 @@ async function createNoteLink(notePath, noteTitle = null) { noteTitle = await treeUtils.getNoteTitle(noteId); } - const noteLink = $("", { + const $noteLink = $("", { href: 'javascript:', text: noteTitle }).attr('data-action', 'note') .attr('data-note-path', notePath); - return noteLink; + $noteLink.addClass("no-tooltip-preview"); + + return $noteLink; } async function createNoteLinkWithPath(notePath, noteTitle = null) { diff --git a/src/public/javascripts/services/note_detail_book.js b/src/public/javascripts/services/note_detail_book.js new file mode 100644 index 000000000..b4fd6a672 --- /dev/null +++ b/src/public/javascripts/services/note_detail_book.js @@ -0,0 +1,63 @@ +import bundleService from "./bundle.js"; +import server from "./server.js"; +import linkService from "./link.js"; + +class NoteDetailBook { + /** + * @param {TabContext} ctx + */ + constructor(ctx) { + this.ctx = ctx; + this.$component = ctx.$tabContent.find('.note-detail-book'); + } + + async render() { + this.$component.empty(); + + for (const childNote of await this.ctx.note.getChildNotes()) { + this.$component.append( + $('
') + .append($('
').append(await linkService.createNoteLink(childNote.noteId))) + .append($('
').append(await this.getNoteContent(childNote))) + ); + } + } + + async getNoteContent(note) { + if (note.type === 'text') { + const fullNote = await server.get('notes/' + note.noteId); + + const $content = $("
").html(fullNote.content); + + if (!fullNote.content.toLowerCase().includes("Content of this note cannot be displayed in the book format"; + } + } + + getContent() {} + + show() { + this.$component.show(); + } + + focus() {} + + onNoteChange() {} + + cleanup() { + this.$component.empty(); + } + + scrollToTop() { + this.$component.scrollTop(0); + } +} + +export default NoteDetailBook; \ No newline at end of file diff --git a/src/public/javascripts/services/note_type.js b/src/public/javascripts/services/note_type.js index da95a5a7b..5627938b9 100644 --- a/src/public/javascripts/services/note_type.js +++ b/src/public/javascripts/services/note_type.js @@ -11,6 +11,7 @@ const NOTE_TYPES = [ { type: "text", mime: "text/html", title: "Text", selectable: true }, { type: "relation-map", mime: "application/json", title: "Relation Map", selectable: true }, { type: "render", mime: '', title: "Render Note", selectable: true }, + { type: "book", mime: '', title: "Book", selectable: true }, { type: "code", mime: 'text/plain', title: "Code", selectable: true } ]; diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index eebf5f9a0..8f29c903c 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -23,7 +23,8 @@ const componentClasses = { 'search': "./note_detail_search.js", 'render': "./note_detail_render.js", 'relation-map': "./note_detail_relation_map.js", - 'protected-session': "./note_detail_protected_session.js" + 'protected-session': "./note_detail_protected_session.js", + 'book': "./note_detail_book.js" }; let showSidebarInNewTab = true; @@ -163,7 +164,7 @@ class TabContext { this.setTitleBar(); - this.closeAutocomplete(); // esp. on windows autocomplete is not getting closed automatically + this.cleanup(); // esp. on windows autocomplete is not getting closed automatically setTimeout(async () => { // we include the note into recent list only if the user stayed on the note at least 5 seconds @@ -289,24 +290,23 @@ class TabContext { } getComponentType() { - let type; - - if (this.note) { - type = this.note.type; - - if (this.note.isProtected) { - if (protectedSessionHolder.isProtectedSessionAvailable()) { - protectedSessionHolder.touchProtectedSession(); - } else { - type = 'protected-session'; - - // user shouldn't be able to edit note title - this.$noteTitle.prop("readonly", true); - } - } - } else { - type = 'empty'; + if (!this.note) { + return "empty"; } + + let type = this.note.type; + + if (this.note.isProtected) { + if (protectedSessionHolder.isProtectedSessionAvailable()) { + protectedSessionHolder.touchProtectedSession(); + } else { + type = 'protected-session'; + + // user shouldn't be able to edit note title + this.$noteTitle.prop("readonly", true); + } + } + return type; } @@ -368,9 +368,7 @@ class TabContext { async showChildrenOverview() { const attributes = await this.attributes.getAttributes(); const hideChildrenOverview = attributes.some(attr => attr.type === 'label' && attr.name === 'hideChildrenOverview') - || this.note.type === 'relation-map' - || this.note.type === 'image' - || this.note.type === 'file'; + || ['relation-map', 'image', 'file', 'book'].includes(this.note.type); if (hideChildrenOverview) { this.$childrenOverview.hide(); @@ -440,15 +438,17 @@ class TabContext { async remove() { // sometimes there are orphan autocompletes after closing the tab - this.closeAutocomplete(); + this.cleanup(); await this.saveNoteIfChanged(); this.$tabContent.remove(); } - closeAutocomplete() { + cleanup() { if (utils.isDesktop()) { this.$tabContent.find('.aa-input').autocomplete('close'); + + $('.note-tooltip').remove(); } } diff --git a/src/public/javascripts/services/tree_builder.js b/src/public/javascripts/services/tree_builder.js index 2f8c8ef24..94ef9a79e 100644 --- a/src/public/javascripts/services/tree_builder.js +++ b/src/public/javascripts/services/tree_builder.js @@ -31,6 +31,16 @@ async function prepareBranch(note) { } } +const NOTE_TYPE_ICONS = { + "file": "jam jam-attachment", + "image": "jam jam-picture", + "code": "jam jam-terminal", + "render": "jam jam-play", + "search": "jam jam-search-folder", + "relation-map": "jam jam-map", + "book": "jam jam-book" +}; + async function getIcon(note) { const hoistedNoteId = await hoistedNoteService.getHoistedNoteId(); @@ -48,23 +58,8 @@ async function getIcon(note) { return "jam jam-file"; } } - else if (note.type === 'file') { - return "jam jam-attachment" - } - else if (note.type === 'image') { - return "jam jam-picture" - } - else if (note.type === 'code') { - return "jam jam-terminal" - } - else if (note.type === 'render') { - return "jam jam-play" - } - else if (note.type === 'search') { - return "jam jam-search-folder" - } - else if (note.type === 'relation-map') { - return "jam jam-map" + else { + return NOTE_TYPE_ICONS[note.type]; } } diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index 21eae4818..ac437f25f 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -817,4 +817,11 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href .modal-header { padding: 0.7rem 1rem !important; /* make modal header padding slightly smaller */ +} + +.note-book { + border-radius: 5px; + background-color: var(--accented-background-color); + padding: 15px; + margin-top: 10px; } \ No newline at end of file diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index ed2e55815..e261ea88e 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -216,7 +216,7 @@ async function findLogicIssues() { FROM notes WHERE isDeleted = 0 - AND type NOT IN ('text', 'code', 'render', 'file', 'image', 'search', 'relation-map')`, + AND type NOT IN ('text', 'code', 'render', 'file', 'image', 'search', 'relation-map', 'book')`, ({noteId, type}) => `Note ${noteId} has invalid type=${type}`); await findIssues(` diff --git a/src/views/details/book.ejs b/src/views/details/book.ejs new file mode 100644 index 000000000..711b42625 --- /dev/null +++ b/src/views/details/book.ejs @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/src/views/tabs.ejs b/src/views/tabs.ejs index 5db78c230..2225c79fc 100644 --- a/src/views/tabs.ejs +++ b/src/views/tabs.ejs @@ -34,6 +34,8 @@ <% include details/protected_session_password.ejs %> + <% include details/book.ejs %> +