import linkService from "../services/link.js"; import server from "../services/server.js"; import treeCache from "../services/tree_cache.js"; import TabAwareWidget from "./tab_aware_widget.js"; import options from "../services/options.js"; const TPL = `


`; export default class SimilarNotesWidget extends TabAwareWidget { isEnabled() { return super.isEnabled() && !this.note.hasLabel('similarNotesWidgetDisabled'); } doRender() { this.$widget = $(TPL); this.overflowing(); this.$similarNotesWrapper = this.$widget.find(".similar-notes-wrapper"); this.$similarNotesExpanderText = this.$widget.find(".similar-notes-expander-text"); this.$expander = this.$widget.find('.similar-notes-expander'); this.$expander.on('click', async () => { const collapse = this.$similarNotesWrapper.is(":visible"); await options.save('similarNotesExpanded', !collapse); this.triggerEvent(`similarNotesCollapsedStateChanged`, {collapse}); }); return this.$widget; } noteSwitched() { const noteId = this.noteId; this.toggleInt(false); this.$similarNotesWrapper.hide(); // we'll open it in refresh() if needed // avoid executing this expensive operation multiple times when just going through notes (with keyboard especially) // until the users settles on a note setTimeout(() => { if (this.noteId === noteId) { this.refresh(); } }, 1000); } async refresh() { if (!this.isEnabled()) { return; } // remember which title was when we found the similar notes this.title = this.note.title; const similarNotes = await server.get('similar-notes/' + this.noteId); this.toggleInt(similarNotes.length > 0); if (similarNotes.length === 0) { return; } if (options.is('similarNotesExpanded')) { this.$similarNotesWrapper.show(); } this.$similarNotesExpanderText.text(`${similarNotes.length} similar note${similarNotes.length === 1 ? '': "s"}`); const noteIds = similarNotes.flatMap(note => note.notePath); await treeCache.getNotes(noteIds, true); // preload all at once const $list = $('
'); for (const similarNote of similarNotes) { const note = await treeCache.getNote(similarNote.noteId, true); if (!note) { continue; } const $item = (await linkService.createNoteLink(similarNote.notePath.join("/"))) .css("font-size", 24 * (1 - 1 / (1 + similarNote.score))); $list.append($item); } this.$similarNotesWrapper.empty().append($list); } entitiesReloadedEvent({loadResults}) { if (this.note && this.title !== this.note.title) { this.rendered = false; this.refresh(); } } /** * This event is used to synchronize collapsed state of all the tab-cached widgets since they are all rendered * separately but should behave uniformly for the user. */ similarNotesCollapsedStateChangedEvent({collapse}) { if (collapse) { this.$similarNotesWrapper.slideUp(200); } else { this.$similarNotesWrapper.slideDown(200); } } }