conversion of note list renderer to class

This commit is contained in:
zadam 2020-10-23 22:11:39 +02:00
parent 29c1d05540
commit c7d8bddf24
2 changed files with 153 additions and 172 deletions

View File

@ -3,35 +3,6 @@ import noteContentRenderer from "./note_content_renderer.js";
import treeCache from "./tree_cache.js"; import treeCache from "./tree_cache.js";
import attributeService from "./attributes.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 = ` const TPL = `
<div class="note-list"> <div class="note-list">
<style> <style>
@ -41,6 +12,18 @@ const TPL = `
height: 100%; 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 { .note-book-card {
border-radius: 10px; border-radius: 10px;
background-color: var(--accented-background-color); background-color: var(--accented-background-color);
@ -85,7 +68,7 @@ const TPL = `
flex-grow: 0; flex-grow: 0;
} }
.note-list-container { .note-list-wrapper {
height: 100%; height: 100%;
overflow: auto; overflow: auto;
} }
@ -127,26 +110,64 @@ const TPL = `
title="Grid view"></button> title="Grid view"></button>
</div> </div>
<div class="note-list-wrapper">
<div class="note-list-pager"></div>
<div class="note-list-container"></div> <div class="note-list-container"></div>
<div class="note-list-pager"></div>
</div>
</div>`; </div>`;
async function toggleCards(cards, expand) { class NoteListRenderer {
for (const card of cards) { constructor(parentNote, notes) {
const $card = $(card); this.$noteList = $(TPL);
const noteId = $card.attr('data-note-id'); this.parentNote = parentNote;
const note = await treeCache.getNote(noteId); 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;
} }
}
async function renderPage(parentNote, notes, $container, page, pageSize) { await this.toggleCards($unexpandedCards, true);
const imageLinks = parentNote ? parentNote.getRelations('imageLink') : [];
const startIdx = (page - 1) * pageSize; if (!this.parentNote.hasLabel('expanded')) {
const endIdx = startIdx + pageSize; await attributeService.addLabel(this.parentNote.noteId, 'expanded');
}
}
});
const pageNotes = notes.slice(startIdx, Math.min(endIdx, notes.length)); 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 renderList() {
const $container = this.$noteList.find('.note-list-container').empty();
const imageLinks = this.parentNote ? this.parentNote.getRelations('imageLink') : [];
const startIdx = (this.page - 1) * this.pageSize;
const endIdx = startIdx + this.pageSize;
const pageNotes = this.notes.slice(startIdx, Math.min(endIdx, this.notes.length));
for (const note of pageNotes) { for (const note of pageNotes) {
// image is already visible in the parent note so no need to display it separately in the book // image is already visible in the parent note so no need to display it separately in the book
@ -154,71 +175,45 @@ async function renderPage(parentNote, notes, $container, page, pageSize) {
continue; continue;
} }
const $card = await renderNote(note); const $card = await this.renderNote(note);
$container.append($card); $container.append($card);
} }
}
async function renderNoteListContent($noteList, parentNote, notes, page = 1, pageSize = 2) { this.renderPager();
const $container = $noteList.find('.note-list-container').empty();
$container.append('<div class="note-list-pager"></div>'); return this.$noteList;
}
await renderPage(parentNote, notes, $container, page, pageSize); renderPager() {
const $pager = this.$noteList.find('.note-list-pager');
$container.append('<div class="note-list-pager"></div>'); for (let i = 1; i <= Math.ceil(this.notes.length / this.pageSize); i++) {
const $pager = $noteList.find('.note-list-pager');
for (let i = 1; i <= Math.ceil(notes.length / pageSize); i++) {
$pager.append( $pager.append(
i === page i === this.page
? $('<span>').text(i).css('text-decoration', 'underline').css('font-weight', "bold") ? $('<span>').text(i).css('text-decoration', 'underline').css('font-weight', "bold")
: $('<a href="javascript:">') : $('<a href="javascript:">')
.text(i) .text(i)
.on('click', () => renderNoteListContent($noteList, parentNote, notes, i, pageSize)), .on('click', () => {
this.page = i;
this.renderList();
}),
" &nbsp; " " &nbsp; "
); );
} }
}
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;
} }
await toggleCards($unexpandedCards, true); 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);
if (!parentNote.hasLabel('expanded')) { await this.toggleContent($card, note, expand);
await attributeService.addLabel(parentNote.noteId, 'expanded');
} }
} }
});
$noteList.find('.collapse-all-button').on('click', async () => { async renderNoteContent(note) {
const $expandedCards = $noteList.find('.note-book-card.expanded');
await toggleCards($expandedCards, false);
// owned is important - we shouldn't remove inherited expanded labels
for (const expandedAttr of parentNote.getOwnedLabels('expanded')) {
await attributeService.removeAttributeById(parentNote.noteId, expandedAttr.attributeId);
}
});
await renderNoteListContent($noteList, parentNote, notes);
return $noteList;
}
async function renderNoteContent(note) {
const $content = $('<div class="note-book-content">'); const $content = $('<div class="note-book-content">');
try { try {
@ -238,21 +233,20 @@ async function renderNoteContent(note) {
.filter(childNote => !imageLinks.find(rel => rel.value === childNote.noteId)); .filter(childNote => !imageLinks.find(rel => rel.value === childNote.noteId));
for (const childNote of childNotes) { for (const childNote of childNotes) {
$content.append(await renderNote(childNote, false)); $content.append(await this.renderNote(childNote, false));
} }
return $content; return $content;
} }
// TODO: we should also render (promoted) attributes // TODO: we should also render (promoted) attributes
async function renderNote(note, expand) { async renderNote(note, expand) {
const notePath = /*this.notePath + '/' + */ note.noteId; const notePath = /*this.notePath + '/' + */ note.noteId;
const $expander = $('<span class="note-expander bx bx-chevron-right"></span>'); const $expander = $('<span class="note-expander bx bx-chevron-right"></span>');
const $card = $('<div class="note-book-card">') const $card = $('<div class="note-book-card">')
.attr('data-note-id', note.noteId) .attr('data-note-id', note.noteId)
.css("flex-basis", ZOOMS[zoomLevel].width)
.append( .append(
$('<h5 class="note-book-title">') $('<h5 class="note-book-title">')
.append($expander) .append($expander)
@ -261,12 +255,12 @@ async function renderNote(note, expand) {
$expander.on('click', () => toggleContent($card, note, !$card.hasClass("expanded"))); $expander.on('click', () => toggleContent($card, note, !$card.hasClass("expanded")));
await toggleContent($card, note, expand); await this.toggleContent($card, note, expand);
return $card; return $card;
} }
async function toggleContent($card, note, expand) { async toggleContent($card, note, expand) {
if ((expand && $card.hasClass("expanded")) || (!expand && !$card.hasClass("expanded"))) { if ((expand && $card.hasClass("expanded")) || (!expand && !$card.hasClass("expanded"))) {
return; return;
} }
@ -283,24 +277,9 @@ async function toggleContent($card, note, expand) {
} }
if (expand && $card.find('.note-book-content').length === 0) { if (expand && $card.find('.note-book-content').length === 0) {
$card.append(await renderNoteContent(note)); $card.append(await this.renderNoteContent(note));
}
} }
} }
function setZoom(zoomLevel) { export default NoteListRenderer;
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
};

View File

@ -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"; import TypeWidget from "./type_widget.js";
const TPL = ` const TPL = `
@ -63,7 +63,9 @@ export default class BookTypeWidget extends TypeWidget {
// const zoomLevel = parseInt(note.getLabelValue('bookZoomLevel')) || this.getDefaultZoomLevel(); // const zoomLevel = parseInt(note.getLabelValue('bookZoomLevel')) || this.getDefaultZoomLevel();
// this.setZoom(zoomLevel); // 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 */ /** @return {boolean} true if this is "auto book" activated (empty text note) and not explicit book note */