mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	conversion of note list renderer to class
This commit is contained in:
		| @@ -3,35 +3,6 @@ import noteContentRenderer from "./note_content_renderer.js"; | ||||
| import treeCache from "./tree_cache.js"; | ||||
| import attributeService from "./attributes.js"; | ||||
|  | ||||
| const ZOOMS = { | ||||
|     1: { | ||||
|         width: "100%", | ||||
|         height: "100%" | ||||
|     }, | ||||
|     2: { | ||||
|         width: "49%", | ||||
|         height: "350px" | ||||
|     }, | ||||
|     3: { | ||||
|         width: "32%", | ||||
|         height: "250px" | ||||
|     }, | ||||
|     4: { | ||||
|         width: "24%", | ||||
|         height: "200px" | ||||
|     }, | ||||
|     5: { | ||||
|         width: "19%", | ||||
|         height: "175px" | ||||
|     }, | ||||
|     6: { | ||||
|         width: "16%", | ||||
|         height: "150px" | ||||
|     } | ||||
| }; | ||||
|  | ||||
| const zoomLevel = 2; | ||||
|  | ||||
| const TPL = ` | ||||
| <div class="note-list"> | ||||
|     <style> | ||||
| @@ -41,6 +12,18 @@ const TPL = ` | ||||
|         height: 100%; | ||||
|     } | ||||
|      | ||||
|     .note-list.card-view .note-list-container { | ||||
|         display: flex; | ||||
|     } | ||||
|      | ||||
|     .note-list.card-view .note-book-card { | ||||
|         width: 300px; | ||||
|     } | ||||
|      | ||||
|     .note-list.card-view .note-expander { | ||||
|         display: none; | ||||
|     } | ||||
|      | ||||
|     .note-book-card { | ||||
|         border-radius: 10px; | ||||
|         background-color: var(--accented-background-color); | ||||
| @@ -85,7 +68,7 @@ const TPL = ` | ||||
|         flex-grow: 0; | ||||
|     } | ||||
|      | ||||
|     .note-list-container { | ||||
|     .note-list-wrapper { | ||||
|         height: 100%; | ||||
|         overflow: auto; | ||||
|     } | ||||
| @@ -127,180 +110,176 @@ const TPL = ` | ||||
|                 title="Grid view"></button> | ||||
|     </div> | ||||
|  | ||||
|     <div class="note-list-container"></div> | ||||
|     <div class="note-list-wrapper"> | ||||
|         <div class="note-list-pager"></div> | ||||
|      | ||||
|         <div class="note-list-container"></div> | ||||
|          | ||||
|         <div class="note-list-pager"></div> | ||||
|     </div> | ||||
| </div>`; | ||||
|  | ||||
| async function toggleCards(cards, expand) { | ||||
|     for (const card of cards) { | ||||
|         const $card = $(card); | ||||
|         const noteId = $card.attr('data-note-id'); | ||||
|         const note = await treeCache.getNote(noteId); | ||||
| class NoteListRenderer { | ||||
|     constructor(parentNote, notes) { | ||||
|         this.$noteList = $(TPL); | ||||
|         this.parentNote = parentNote; | ||||
|         this.notes = notes; | ||||
|         this.page = 1; | ||||
|         this.pageSize = 2; | ||||
|  | ||||
|         await toggleContent($card, note, expand); | ||||
|         this.$noteList.find('.grid-view-button').on('click', async () => { | ||||
|  | ||||
|         }); | ||||
|  | ||||
|         this.$noteList.find('.expand-children-button').on('click', async () => { | ||||
|             for (let i = 1; i < 30; i++) { // protection against infinite cycle | ||||
|                 const $unexpandedCards = this.$noteList.find('.note-book-card:not(.expanded)'); | ||||
|  | ||||
|                 if ($unexpandedCards.length === 0) { | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 await this.toggleCards($unexpandedCards, true); | ||||
|  | ||||
|                 if (!this.parentNote.hasLabel('expanded')) { | ||||
|                     await attributeService.addLabel(this.parentNote.noteId, 'expanded'); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         this.$noteList.find('.collapse-all-button').on('click', async () => { | ||||
|             const $expandedCards = this.$noteList.find('.note-book-card.expanded'); | ||||
|  | ||||
|             await this.toggleCards($expandedCards, false); | ||||
|  | ||||
|             // owned is important - we shouldn't remove inherited expanded labels | ||||
|             for (const expandedAttr of this.parentNote.getOwnedLabels('expanded')) { | ||||
|                 await attributeService.removeAttributeById(this.parentNote.noteId, expandedAttr.attributeId); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function renderPage(parentNote, notes, $container, page, pageSize) { | ||||
|     const imageLinks = parentNote ? parentNote.getRelations('imageLink') : []; | ||||
|     async renderList() { | ||||
|         const $container = this.$noteList.find('.note-list-container').empty(); | ||||
|  | ||||
|     const startIdx = (page - 1) * pageSize; | ||||
|     const endIdx = startIdx + pageSize; | ||||
|         const imageLinks = this.parentNote ? this.parentNote.getRelations('imageLink') : []; | ||||
|  | ||||
|     const pageNotes = notes.slice(startIdx, Math.min(endIdx, notes.length)); | ||||
|         const startIdx = (this.page - 1) * this.pageSize; | ||||
|         const endIdx = startIdx + this.pageSize; | ||||
|  | ||||
|     for (const note of pageNotes) { | ||||
|         // image is already visible in the parent note so no need to display it separately in the book | ||||
|         if (imageLinks.find(rel => rel.value === note.noteId)) { | ||||
|             continue; | ||||
|         } | ||||
|         const pageNotes = this.notes.slice(startIdx, Math.min(endIdx, this.notes.length)); | ||||
|  | ||||
|         const $card = await renderNote(note); | ||||
|  | ||||
|         $container.append($card); | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function renderNoteListContent($noteList, parentNote, notes, page = 1, pageSize = 2) { | ||||
|     const $container = $noteList.find('.note-list-container').empty(); | ||||
|  | ||||
|     $container.append('<div class="note-list-pager"></div>'); | ||||
|  | ||||
|     await renderPage(parentNote, notes, $container, page, pageSize); | ||||
|  | ||||
|     $container.append('<div class="note-list-pager"></div>'); | ||||
|  | ||||
|     const $pager = $noteList.find('.note-list-pager'); | ||||
|  | ||||
|     for (let i = 1; i <= Math.ceil(notes.length / pageSize); i++) { | ||||
|         $pager.append( | ||||
|             i === page | ||||
|                 ? $('<span>').text(i).css('text-decoration', 'underline').css('font-weight', "bold") | ||||
|                 : $('<a href="javascript:">') | ||||
|                     .text(i) | ||||
|                     .on('click', () => renderNoteListContent($noteList, parentNote, notes, i, pageSize)), | ||||
|             "   " | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| async function renderList(notes, parentNote) { | ||||
|     const $noteList = $(TPL); | ||||
|  | ||||
|     $noteList.find('.expand-children-button').on('click', async () => { | ||||
|         for (let i = 1; i < 30; i++) { // protection against infinite cycle | ||||
|             const $unexpandedCards = $noteList.find('.note-book-card:not(.expanded)'); | ||||
|  | ||||
|             if ($unexpandedCards.length === 0) { | ||||
|                 break; | ||||
|         for (const note of pageNotes) { | ||||
|             // image is already visible in the parent note so no need to display it separately in the book | ||||
|             if (imageLinks.find(rel => rel.value === note.noteId)) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             await toggleCards($unexpandedCards, true); | ||||
|             const $card = await this.renderNote(note); | ||||
|  | ||||
|             if (!parentNote.hasLabel('expanded')) { | ||||
|                 await attributeService.addLabel(parentNote.noteId, 'expanded'); | ||||
|             } | ||||
|             $container.append($card); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     $noteList.find('.collapse-all-button').on('click', async () => { | ||||
|         const $expandedCards = $noteList.find('.note-book-card.expanded'); | ||||
|         this.renderPager(); | ||||
|  | ||||
|         await toggleCards($expandedCards, false); | ||||
|         return this.$noteList; | ||||
|     } | ||||
|  | ||||
|         // owned is important - we shouldn't remove inherited expanded labels | ||||
|         for (const expandedAttr of parentNote.getOwnedLabels('expanded')) { | ||||
|             await attributeService.removeAttributeById(parentNote.noteId, expandedAttr.attributeId); | ||||
|     renderPager() { | ||||
|         const $pager = this.$noteList.find('.note-list-pager'); | ||||
|  | ||||
|         for (let i = 1; i <= Math.ceil(this.notes.length / this.pageSize); i++) { | ||||
|             $pager.append( | ||||
|                 i === this.page | ||||
|                     ? $('<span>').text(i).css('text-decoration', 'underline').css('font-weight', "bold") | ||||
|                     : $('<a href="javascript:">') | ||||
|                         .text(i) | ||||
|                         .on('click', () => { | ||||
|                             this.page = i; | ||||
|                             this.renderList(); | ||||
|                         }), | ||||
|                 "   " | ||||
|             ); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     await renderNoteListContent($noteList, parentNote, notes); | ||||
|  | ||||
|     return $noteList; | ||||
| } | ||||
|  | ||||
| async function renderNoteContent(note) { | ||||
|     const $content = $('<div class="note-book-content">'); | ||||
|  | ||||
|     try { | ||||
|         const {renderedContent, type} = await noteContentRenderer.getRenderedContent(note); | ||||
|  | ||||
|         $content.append(renderedContent); | ||||
|         $content.addClass("type-" + type); | ||||
|     } catch (e) { | ||||
|         console.log(`Caught error while rendering note ${note.noteId} of type ${note.type}: ${e.message}, stack: ${e.stack}`); | ||||
|  | ||||
|         $content.append("rendering error"); | ||||
|     } | ||||
|  | ||||
|     const imageLinks = note.getRelations('imageLink'); | ||||
|     async toggleCards(cards, expand) { | ||||
|         for (const card of cards) { | ||||
|             const $card = $(card); | ||||
|             const noteId = $card.attr('data-note-id'); | ||||
|             const note = await treeCache.getNote(noteId); | ||||
|  | ||||
|     const childNotes = (await note.getChildNotes()) | ||||
|         .filter(childNote => !imageLinks.find(rel => rel.value === childNote.noteId)); | ||||
|  | ||||
|     for (const childNote of childNotes) { | ||||
|         $content.append(await renderNote(childNote, false)); | ||||
|             await this.toggleContent($card, note, expand); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return $content; | ||||
| } | ||||
|     async renderNoteContent(note) { | ||||
|         const $content = $('<div class="note-book-content">'); | ||||
|  | ||||
| // TODO: we should also render (promoted) attributes | ||||
| async function renderNote(note, expand) { | ||||
|     const notePath = /*this.notePath + '/' + */ note.noteId; | ||||
|         try { | ||||
|             const {renderedContent, type} = await noteContentRenderer.getRenderedContent(note); | ||||
|  | ||||
|     const $expander = $('<span class="note-expander bx bx-chevron-right"></span>'); | ||||
|             $content.append(renderedContent); | ||||
|             $content.addClass("type-" + type); | ||||
|         } catch (e) { | ||||
|             console.log(`Caught error while rendering note ${note.noteId} of type ${note.type}: ${e.message}, stack: ${e.stack}`); | ||||
|  | ||||
|     const $card = $('<div class="note-book-card">') | ||||
|         .attr('data-note-id', note.noteId) | ||||
|         .css("flex-basis", ZOOMS[zoomLevel].width) | ||||
|         .append( | ||||
|             $('<h5 class="note-book-title">') | ||||
|                 .append($expander) | ||||
|                 .append(await linkService.createNoteLink(notePath, {showTooltip: false})) | ||||
|         ); | ||||
|             $content.append("rendering error"); | ||||
|         } | ||||
|  | ||||
|     $expander.on('click', () => toggleContent($card, note, !$card.hasClass("expanded"))); | ||||
|         const imageLinks = note.getRelations('imageLink'); | ||||
|  | ||||
|     await toggleContent($card, note, expand); | ||||
|         const childNotes = (await note.getChildNotes()) | ||||
|             .filter(childNote => !imageLinks.find(rel => rel.value === childNote.noteId)); | ||||
|  | ||||
|     return $card; | ||||
| } | ||||
|         for (const childNote of childNotes) { | ||||
|             $content.append(await this.renderNote(childNote, false)); | ||||
|         } | ||||
|  | ||||
| async function toggleContent($card, note, expand) { | ||||
|     if ((expand && $card.hasClass("expanded")) || (!expand && !$card.hasClass("expanded"))) { | ||||
|         return; | ||||
|         return $content; | ||||
|     } | ||||
|  | ||||
|     const $expander = $card.find('> .note-book-title .note-expander'); | ||||
|     // TODO: we should also render (promoted) attributes | ||||
|     async renderNote(note, expand) { | ||||
|         const notePath = /*this.notePath + '/' + */ note.noteId; | ||||
|  | ||||
|     if (expand) { | ||||
|         $card.addClass("expanded"); | ||||
|         $expander.addClass("bx-chevron-down").removeClass("bx-chevron-right"); | ||||
|     } | ||||
|     else { | ||||
|         $card.removeClass("expanded"); | ||||
|         $expander.addClass("bx-chevron-right").removeClass("bx-chevron-down"); | ||||
|         const $expander = $('<span class="note-expander bx bx-chevron-right"></span>'); | ||||
|  | ||||
|         const $card = $('<div class="note-book-card">') | ||||
|             .attr('data-note-id', note.noteId) | ||||
|             .append( | ||||
|                 $('<h5 class="note-book-title">') | ||||
|                     .append($expander) | ||||
|                     .append(await linkService.createNoteLink(notePath, {showTooltip: false})) | ||||
|             ); | ||||
|  | ||||
|         $expander.on('click', () => toggleContent($card, note, !$card.hasClass("expanded"))); | ||||
|  | ||||
|         await this.toggleContent($card, note, expand); | ||||
|  | ||||
|         return $card; | ||||
|     } | ||||
|  | ||||
|     if (expand && $card.find('.note-book-content').length === 0) { | ||||
|         $card.append(await renderNoteContent(note)); | ||||
|     async toggleContent($card, note, expand) { | ||||
|         if ((expand && $card.hasClass("expanded")) || (!expand && !$card.hasClass("expanded"))) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         const $expander = $card.find('> .note-book-title .note-expander'); | ||||
|  | ||||
|         if (expand) { | ||||
|             $card.addClass("expanded"); | ||||
|             $expander.addClass("bx-chevron-down").removeClass("bx-chevron-right"); | ||||
|         } | ||||
|         else { | ||||
|             $card.removeClass("expanded"); | ||||
|             $expander.addClass("bx-chevron-right").removeClass("bx-chevron-down"); | ||||
|         } | ||||
|  | ||||
|         if (expand && $card.find('.note-book-content').length === 0) { | ||||
|             $card.append(await this.renderNoteContent(note)); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| function setZoom(zoomLevel) { | ||||
|     if (!(zoomLevel in ZOOMS)) { | ||||
|         zoomLevel = this.getDefaultZoomLevel(); | ||||
|     } | ||||
|  | ||||
|     this.zoomLevel = zoomLevel; | ||||
|  | ||||
|     this.$zoomInButton.prop("disabled", zoomLevel === MIN_ZOOM_LEVEL); | ||||
|     this.$zoomOutButton.prop("disabled", zoomLevel === MAX_ZOOM_LEVEL); | ||||
|  | ||||
|     this.$content.find('.note-book-card').css("flex-basis", ZOOMS[zoomLevel].width); | ||||
|     this.$content.find('.note-book-content').css("max-height", ZOOMS[zoomLevel].height); | ||||
| } | ||||
|  | ||||
| export default { | ||||
|     renderList | ||||
| }; | ||||
| export default NoteListRenderer; | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import noteListRenderer from "../../services/note_list_renderer.js"; | ||||
| import NoteListRenderer from "../../services/note_list_renderer.js"; | ||||
| import TypeWidget from "./type_widget.js"; | ||||
|  | ||||
| const TPL = ` | ||||
| @@ -63,7 +63,9 @@ export default class BookTypeWidget extends TypeWidget { | ||||
|         // const zoomLevel = parseInt(note.getLabelValue('bookZoomLevel')) || this.getDefaultZoomLevel(); | ||||
|         // this.setZoom(zoomLevel); | ||||
|  | ||||
|         this.$content.append(await noteListRenderer.renderList(await note.getChildNotes(), note)); | ||||
|         const noteListRenderer = new NoteListRenderer(note, await note.getChildNotes()); | ||||
|  | ||||
|         this.$content.append(await noteListRenderer.renderList()); | ||||
|     } | ||||
|  | ||||
|     /** @return {boolean} true if this is "auto book" activated (empty text note) and not explicit book note */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user