skeleton implementation of new "book" note type

This commit is contained in:
zadam 2019-10-01 21:11:11 +02:00
parent 0ef6634d41
commit 8ec01c73cd
10 changed files with 116 additions and 45 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "trilium",
"version": "0.35.0-beta",
"version": "0.35.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -21,13 +21,15 @@ async function createNoteLink(notePath, noteTitle = null) {
noteTitle = await treeUtils.getNoteTitle(noteId);
}
const noteLink = $("<a>", {
const $noteLink = $("<a>", {
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) {

View File

@ -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(
$('<div class="note-book">')
.append($('<h5 class="note-book-title">').append(await linkService.createNoteLink(childNote.noteId)))
.append($('<div class="note-book-content">').append(await this.getNoteContent(childNote)))
);
}
}
async getNoteContent(note) {
if (note.type === 'text') {
const fullNote = await server.get('notes/' + note.noteId);
const $content = $("<div>").html(fullNote.content);
if (!fullNote.content.toLowerCase().includes("<img") && $content.text().trim() === "") {
return "";
}
else {
return $content;
}
}
else {
return "<em>Content of this note cannot be displayed in the book format</em>";
}
}
getContent() {}
show() {
this.$component.show();
}
focus() {}
onNoteChange() {}
cleanup() {
this.$component.empty();
}
scrollToTop() {
this.$component.scrollTop(0);
}
}
export default NoteDetailBook;

View File

@ -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 }
];

View File

@ -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();
}
}

View File

@ -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];
}
}

View File

@ -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;
}

View File

@ -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(`

View File

@ -0,0 +1 @@
<div class="note-detail-book note-detail-component"></div>

View File

@ -34,6 +34,8 @@
<% include details/protected_session_password.ejs %>
<% include details/book.ejs %>
<div class="children-overview hide-toggle"></div>
</div>
</div>