121 lines
3.2 KiB
TypeScript
Raw Normal View History

import { t } from "../../services/i18n.js";
2021-05-29 13:24:14 +02:00
import linkService from "../../services/link.js";
import server from "../../services/server.js";
import froca from "../../services/froca.js";
import NoteContextAwareWidget from "../note_context_aware_widget.js";
2025-01-19 21:08:57 +02:00
import type FNote from "../../entities/fnote.js";
import type { EventData } from "../../components/app_context.js";
2021-05-29 13:24:14 +02:00
const TPL = `
<div class="similar-notes-widget">
2025-01-19 21:08:57 +02:00
<style>
2021-05-29 13:24:14 +02:00
.similar-notes-wrapper {
max-height: 200px;
overflow: auto;
padding: 12px;
}
.similar-notes-wrapper a {
display: inline-block;
border: 1px dotted var(--main-border-color);
border-radius: 20px;
background-color: var(--accented-background-color);
padding: 0 10px 0 10px;
margin: 0 3px 0 3px;
max-width: 10em;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
</style>
<div class="similar-notes-wrapper"></div>
</div>
`;
2025-01-19 21:08:57 +02:00
// TODO: Deduplicate with server
interface SimilarNote {
score: number;
notePath: string[];
noteId: string;
}
2021-05-29 13:24:14 +02:00
export default class SimilarNotesWidget extends NoteContextAwareWidget {
2025-01-19 21:08:57 +02:00
private $similarNotesWrapper!: JQuery<HTMLElement>;
private title?: string;
private rendered?: boolean;
2021-06-27 12:53:05 +02:00
get name() {
return "similarNotes";
}
get toggleCommand() {
return "toggleRibbonTabSimilarNotes";
}
2021-05-29 13:24:14 +02:00
isEnabled() {
2025-01-19 21:08:57 +02:00
return super.isEnabled() && this.note?.type !== "search" && !this.note?.isLabelTruthy("similarNotesWidgetDisabled");
2021-05-29 13:24:14 +02:00
}
getTitle() {
return {
show: this.isEnabled(),
2025-01-09 18:07:02 +02:00
title: t("similar_notes.title"),
icon: "bx bx-bar-chart"
2021-05-29 13:24:14 +02:00
};
}
doRender() {
this.$widget = $(TPL);
2021-06-13 22:55:31 +02:00
this.contentSized();
2021-05-29 13:24:14 +02:00
this.$similarNotesWrapper = this.$widget.find(".similar-notes-wrapper");
}
2025-01-19 21:08:57 +02:00
async refreshWithNote(note: FNote) {
if (!this.note) {
return;
}
2021-05-29 13:24:14 +02:00
// remember which title was when we found the similar notes
this.title = this.note.title;
2025-01-19 21:08:57 +02:00
const similarNotes = await server.get<SimilarNote[]>(`similar-notes/${this.noteId}`);
2021-05-29 13:24:14 +02:00
if (similarNotes.length === 0) {
2025-01-09 18:07:02 +02:00
this.$similarNotesWrapper.empty().append(t("similar_notes.no_similar_notes_found"));
2021-05-29 13:24:14 +02:00
return;
}
2025-01-09 18:07:02 +02:00
const noteIds = similarNotes.flatMap((note) => note.notePath);
2021-05-29 13:24:14 +02:00
await froca.getNotes(noteIds, true); // preload all at once
2025-01-09 18:07:02 +02:00
const $list = $("<div>");
2021-05-29 13:24:14 +02:00
for (const similarNote of similarNotes) {
const note = await froca.getNote(similarNote.noteId, true);
if (!note) {
continue;
}
2025-01-09 18:07:02 +02:00
const $item = (await linkService.createLink(similarNote.notePath.join("/"))).css("font-size", 24 * (1 - 1 / (1 + similarNote.score)));
2021-05-29 13:24:14 +02:00
$list.append($item);
}
this.$similarNotesWrapper.empty().append($list);
}
2025-01-19 21:08:57 +02:00
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
2021-05-29 13:24:14 +02:00
if (this.note && this.title !== this.note.title) {
this.rendered = false;
this.refresh();
}
}
}