mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-29 02:52:27 +08:00
port js to ts
This commit is contained in:
parent
34762236d1
commit
16b58a58a3
@ -1,56 +0,0 @@
|
||||
import FlexContainer from "./containers/flex_container.js";
|
||||
import OpenNoteButtonWidget from "./buttons/open_note_button_widget.js";
|
||||
import BookmarkFolderWidget from "./buttons/bookmark_folder.js";
|
||||
import froca from "../services/froca.js";
|
||||
import utils from "../services/utils.js";
|
||||
|
||||
export default class BookmarkButtons extends FlexContainer {
|
||||
constructor(isHorizontalLayout) {
|
||||
super(isHorizontalLayout ? "row" : "column");
|
||||
|
||||
this.contentSized();
|
||||
this.settings = {};
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
this.$widget.empty();
|
||||
this.children = [];
|
||||
this.noteIds = [];
|
||||
|
||||
const bookmarkParentNote = await froca.getNote("_lbBookmarks");
|
||||
|
||||
for (const note of await bookmarkParentNote.getChildNotes()) {
|
||||
this.noteIds.push(note.noteId);
|
||||
|
||||
const buttonWidget = note.isLabelTruthy("bookmarkFolder") ? new BookmarkFolderWidget(note) : new OpenNoteButtonWidget(note).class("launcher-button");
|
||||
if (this.settings.titlePlacement) {
|
||||
if (!buttonWidget.settings) {
|
||||
buttonWidget = {};
|
||||
}
|
||||
buttonWidget.settings.titlePlacement = this.settings.titlePlacement;
|
||||
}
|
||||
|
||||
this.child(buttonWidget);
|
||||
|
||||
this.$widget.append(buttonWidget.render());
|
||||
|
||||
buttonWidget.refreshIcon();
|
||||
}
|
||||
|
||||
utils.reloadTray();
|
||||
}
|
||||
|
||||
initialRenderCompleteEvent() {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({ loadResults }) {
|
||||
if (loadResults.getBranchRows().find((branch) => branch.parentNoteId === "_lbBookmarks")) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
if (loadResults.getAttributeRows().find((attr) => attr.type === "label" && ["iconClass", "workspaceIconClass", "bookmarkFolder"].includes(attr.name) && this.noteIds.includes(attr.noteId))) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
78
src/public/app/widgets/bookmark_buttons.ts
Normal file
78
src/public/app/widgets/bookmark_buttons.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import FlexContainer from "./containers/flex_container.js";
|
||||
import OpenNoteButtonWidget from "./buttons/open_note_button_widget.js";
|
||||
import BookmarkFolderWidget from "./buttons/bookmark_folder.js";
|
||||
import froca from "../services/froca.js";
|
||||
import utils from "../services/utils.js";
|
||||
import type { EventData } from "../components/app_context.js";
|
||||
import type Component from "../components/component.js";
|
||||
|
||||
interface BookmarkButtonsSettings {
|
||||
titlePlacement?: string;
|
||||
}
|
||||
|
||||
export default class BookmarkButtons extends FlexContainer<Component> {
|
||||
private settings: BookmarkButtonsSettings;
|
||||
private noteIds: string[];
|
||||
|
||||
constructor(isHorizontalLayout: boolean) {
|
||||
super(isHorizontalLayout ? "row" : "column");
|
||||
|
||||
this.contentSized();
|
||||
this.settings = {};
|
||||
this.noteIds = [];
|
||||
}
|
||||
|
||||
async refresh(): Promise<void> {
|
||||
this.$widget.empty();
|
||||
this.children = [];
|
||||
this.noteIds = [];
|
||||
|
||||
const bookmarkParentNote = await froca.getNote("_lbBookmarks");
|
||||
|
||||
if (!bookmarkParentNote) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const note of await bookmarkParentNote.getChildNotes()) {
|
||||
this.noteIds.push(note.noteId);
|
||||
|
||||
let buttonWidget: OpenNoteButtonWidget | BookmarkFolderWidget = note.isLabelTruthy("bookmarkFolder")
|
||||
? new BookmarkFolderWidget(note)
|
||||
: new OpenNoteButtonWidget(note).class("launcher-button");
|
||||
|
||||
if (this.settings.titlePlacement) {
|
||||
if (!('settings' in buttonWidget)) {
|
||||
(buttonWidget as any).settings = {};
|
||||
}
|
||||
|
||||
(buttonWidget as any).settings.titlePlacement = this.settings.titlePlacement;
|
||||
}
|
||||
|
||||
this.child(buttonWidget);
|
||||
|
||||
this.$widget.append(buttonWidget.render());
|
||||
|
||||
buttonWidget.refreshIcon();
|
||||
}
|
||||
|
||||
utils.reloadTray();
|
||||
}
|
||||
|
||||
initialRenderCompleteEvent(): void {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">): void {
|
||||
if (loadResults.getBranchRows().find((branch) => branch.parentNoteId === "_lbBookmarks")) {
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
if (loadResults.getAttributeRows().find((attr) =>
|
||||
attr.type === "label" &&
|
||||
attr.name && ["iconClass", "workspaceIconClass", "bookmarkFolder"].includes(attr.name) &&
|
||||
attr.noteId && this.noteIds.includes(attr.noteId)
|
||||
)) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import RightDropdownButtonWidget from "./right_dropdown_button.js";
|
||||
import linkService from "../../services/link.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
|
||||
const DROPDOWN_TPL = `
|
||||
<div class="bookmark-folder-widget">
|
||||
@ -43,25 +44,35 @@ const DROPDOWN_TPL = `
|
||||
<ul class="children-notes"></ul>
|
||||
</div>`;
|
||||
|
||||
interface LinkOptions {
|
||||
showTooltip: boolean;
|
||||
showNoteIcon: boolean;
|
||||
}
|
||||
|
||||
export default class BookmarkFolderWidget extends RightDropdownButtonWidget {
|
||||
constructor(note) {
|
||||
private note: FNote;
|
||||
private $parentNote!: JQuery<HTMLElement>;
|
||||
private $childrenNotes!: JQuery<HTMLElement>;
|
||||
declare $dropdownContent: JQuery<HTMLElement>;
|
||||
|
||||
constructor(note: FNote) {
|
||||
super(utils.escapeHtml(note.title), note.getIcon(), DROPDOWN_TPL);
|
||||
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
doRender() {
|
||||
doRender(): void {
|
||||
super.doRender();
|
||||
|
||||
this.$parentNote = this.$dropdownContent.find(".parent-note");
|
||||
this.$childrenNotes = this.$dropdownContent.find(".children-notes");
|
||||
}
|
||||
|
||||
async dropdownShown() {
|
||||
async dropdownShown(): Promise<void> {
|
||||
this.$parentNote.empty();
|
||||
this.$childrenNotes.empty();
|
||||
|
||||
const linkOptions = {
|
||||
const linkOptions: LinkOptions = {
|
||||
showTooltip: false,
|
||||
showNoteIcon: true
|
||||
};
|
||||
@ -73,5 +84,5 @@ export default class BookmarkFolderWidget extends RightDropdownButtonWidget {
|
||||
}
|
||||
}
|
||||
|
||||
refreshIcon() {}
|
||||
refreshIcon(): void {}
|
||||
}
|
76
src/public/app/widgets/buttons/edit_button.ts
Normal file
76
src/public/app/widgets/buttons/edit_button.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import attributeService from "../../services/attributes.js";
|
||||
import protectedSessionHolder from "../../services/protected_session_holder.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
import LoadResults from "../../services/load_results.js";
|
||||
import type { AttributeRow } from "../../services/load_results.js";
|
||||
import FNote from "../../entities/fnote.js";
|
||||
|
||||
export default class EditButton extends OnClickButtonWidget {
|
||||
isEnabled(): boolean {
|
||||
return Boolean(super.isEnabled() && this.note && this.noteContext?.viewScope?.viewMode === "default");
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.icon("bx-edit-alt")
|
||||
.title(t("edit_button.edit_this_note"))
|
||||
.titlePlacement("bottom")
|
||||
.onClick((widget) => {
|
||||
if (this.noteContext?.viewScope) {
|
||||
this.noteContext.viewScope.readOnlyTemporarilyDisabled = true;
|
||||
appContext.triggerEvent("readOnlyTemporarilyDisabled", { noteContext: this.noteContext });
|
||||
}
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
async refreshWithNote(note: FNote): Promise<void> {
|
||||
if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) {
|
||||
this.toggleInt(false);
|
||||
} else {
|
||||
// prevent flickering by assuming hidden before async operation
|
||||
this.toggleInt(false);
|
||||
|
||||
const wasVisible = this.isVisible();
|
||||
|
||||
// can't do this in isEnabled() since isReadOnly is async
|
||||
const isReadOnly = await this.noteContext?.isReadOnly();
|
||||
this.toggleInt(Boolean(isReadOnly));
|
||||
|
||||
// make the edit button stand out on the first display, otherwise
|
||||
// it's difficult to notice that the note is readonly
|
||||
if (this.isVisible() && !wasVisible && this.$widget) {
|
||||
this.$widget.addClass("bx-tada bx-lg");
|
||||
|
||||
setTimeout(() => {
|
||||
this.$widget?.removeClass("bx-tada bx-lg");
|
||||
}, 1700);
|
||||
}
|
||||
}
|
||||
|
||||
await super.refreshWithNote(note);
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({ loadResults }: { loadResults: LoadResults }): void {
|
||||
if (loadResults.getAttributeRows().find((attr: AttributeRow) =>
|
||||
attr.type === "label" &&
|
||||
attr.name?.toLowerCase().includes("readonly") &&
|
||||
this.note &&
|
||||
attributeService.isAffecting(attr, this.note)
|
||||
)) {
|
||||
if (this.noteContext?.viewScope) {
|
||||
this.noteContext.viewScope.readOnlyTemporarilyDisabled = false;
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async noteTypeMimeChangedEvent({ noteId }: { noteId: string }): Promise<void> {
|
||||
if (this.isNote(noteId)) {
|
||||
await this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
import BasicWidget from "../basic_widget.js";
|
||||
import { Tooltip, Dropdown } from "bootstrap";
|
||||
type PopoverPlacement = Tooltip.PopoverPlacement;
|
||||
|
||||
const TPL = `
|
||||
<div class="dropdown right-dropdown-widget dropend">
|
||||
<button type="button" data-bs-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false"
|
||||
aria-haspopup="true" aria-expanded="false"
|
||||
class="bx right-dropdown-button launcher-button"></button>
|
||||
|
||||
|
||||
<div class="tooltip-trigger"></div>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-right"></div>
|
||||
@ -14,7 +15,17 @@ const TPL = `
|
||||
`;
|
||||
|
||||
export default class RightDropdownButtonWidget extends BasicWidget {
|
||||
constructor(title, iconClass, dropdownTpl) {
|
||||
protected iconClass: string;
|
||||
protected title: string;
|
||||
protected dropdownTpl: string;
|
||||
protected settings: { titlePlacement: PopoverPlacement };
|
||||
protected $dropdownMenu!: JQuery<HTMLElement>;
|
||||
protected dropdown!: Dropdown;
|
||||
protected $tooltip!: JQuery<HTMLElement>;
|
||||
protected tooltip!: Tooltip;
|
||||
public $dropdownContent!: JQuery<HTMLElement>;
|
||||
|
||||
constructor(title: string, iconClass: string, dropdownTpl: string) {
|
||||
super();
|
||||
|
||||
this.iconClass = iconClass;
|
||||
@ -26,13 +37,13 @@ export default class RightDropdownButtonWidget extends BasicWidget {
|
||||
};
|
||||
}
|
||||
|
||||
doRender() {
|
||||
doRender(): void {
|
||||
this.$widget = $(TPL);
|
||||
this.$dropdownMenu = this.$widget.find(".dropdown-menu");
|
||||
this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']"));
|
||||
this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']")[0]);
|
||||
|
||||
this.$tooltip = this.$widget.find(".tooltip-trigger").attr("title", this.title);
|
||||
this.tooltip = new Tooltip(this.$tooltip, {
|
||||
this.tooltip = new Tooltip(this.$tooltip[0], {
|
||||
placement: this.settings.titlePlacement,
|
||||
fallbackPlacements: [this.settings.titlePlacement]
|
||||
});
|
||||
@ -48,7 +59,8 @@ export default class RightDropdownButtonWidget extends BasicWidget {
|
||||
await this.dropdownShown();
|
||||
|
||||
const rect = this.$dropdownMenu[0].getBoundingClientRect();
|
||||
const pixelsToBottom = $(window).height() - rect.bottom;
|
||||
const windowHeight = $(window).height() || 0;
|
||||
const pixelsToBottom = windowHeight - rect.bottom;
|
||||
|
||||
if (pixelsToBottom < 0) {
|
||||
this.$dropdownMenu.css("top", pixelsToBottom);
|
||||
@ -60,5 +72,5 @@ export default class RightDropdownButtonWidget extends BasicWidget {
|
||||
}
|
||||
|
||||
// to be overridden
|
||||
async dropdownShow() {}
|
||||
async dropdownShown(): Promise<void> {}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import attributeService from "../../services/attributes.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
|
||||
export default class ShowHighlightsListWidgetButton extends OnClickButtonWidget {
|
||||
isEnabled() {
|
||||
return super.isEnabled() && this.note && this.note.type === "text" && this.noteContext.viewScope.viewMode === "default";
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.icon("bx-highlight")
|
||||
.title(t("show_highlights_list_widget_button.show_highlights_list"))
|
||||
.titlePlacement("bottom")
|
||||
.onClick((widget) => {
|
||||
this.noteContext.viewScope.highlightsListTemporarilyHidden = false;
|
||||
appContext.triggerEvent("showHighlightsListWidget", { noteId: this.noteId });
|
||||
this.toggleInt(false);
|
||||
});
|
||||
}
|
||||
|
||||
async refreshWithNote(note) {
|
||||
this.toggleInt(this.noteContext.viewScope.highlightsListTemporarilyHidden);
|
||||
}
|
||||
async reEvaluateHighlightsListWidgetVisibilityEvent({ noteId }) {
|
||||
if (noteId === this.noteId) {
|
||||
await this.refresh();
|
||||
}
|
||||
}
|
||||
async entitiesReloadedEvent({ loadResults }) {
|
||||
if (loadResults.isNoteContentReloaded(this.noteId)) {
|
||||
await this.refresh();
|
||||
} else if (
|
||||
loadResults
|
||||
.getAttributeRows()
|
||||
.find((attr) => attr.type === "label" && (attr.name.toLowerCase().includes("readonly") || attr.name === "hideHighlightWidget") && attributeService.isAffecting(attr, this.note))
|
||||
) {
|
||||
await this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async noteTypeMimeChangedEvent({ noteId }) {
|
||||
if (this.isNote(noteId)) {
|
||||
await this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
import OnClickButtonWidget from "./onclick_button.js";
|
||||
import appContext from "../../components/app_context.js";
|
||||
import attributeService from "../../services/attributes.js";
|
||||
import { t } from "../../services/i18n.js";
|
||||
import LoadResults from "../../services/load_results.js";
|
||||
import type { AttributeRow } from "../../services/load_results.js";
|
||||
|
||||
export default class ShowHighlightsListWidgetButton extends OnClickButtonWidget {
|
||||
isEnabled(): boolean {
|
||||
return Boolean(super.isEnabled() && this.note && this.note.type === "text" && this.noteContext?.viewScope?.viewMode === "default");
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.icon("bx-highlight")
|
||||
.title(t("show_highlights_list_widget_button.show_highlights_list"))
|
||||
.titlePlacement("bottom")
|
||||
.onClick((widget) => {
|
||||
if (this.noteContext?.viewScope && this.noteId) {
|
||||
this.noteContext.viewScope.highlightsListTemporarilyHidden = false;
|
||||
appContext.triggerEvent("showHighlightsListWidget", { noteId: this.noteId });
|
||||
}
|
||||
this.toggleInt(false);
|
||||
});
|
||||
}
|
||||
|
||||
async refreshWithNote(): Promise<void> {
|
||||
if (this.noteContext?.viewScope) {
|
||||
this.toggleInt(this.noteContext.viewScope.highlightsListTemporarilyHidden);
|
||||
}
|
||||
}
|
||||
|
||||
async reEvaluateHighlightsListWidgetVisibilityEvent({ noteId }: { noteId: string }): Promise<void> {
|
||||
if (noteId === this.noteId) {
|
||||
await this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent({ loadResults }: { loadResults: LoadResults }): Promise<void> {
|
||||
if (this.noteId && loadResults.isNoteContentReloaded(this.noteId)) {
|
||||
await this.refresh();
|
||||
} else if (
|
||||
loadResults
|
||||
.getAttributeRows()
|
||||
.find((attr: AttributeRow) =>
|
||||
attr.type === "label" &&
|
||||
(attr.name?.toLowerCase().includes("readonly") || attr.name === "hideHighlightWidget") &&
|
||||
this.note &&
|
||||
attributeService.isAffecting(attr, this.note)
|
||||
)
|
||||
) {
|
||||
await this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async noteTypeMimeChangedEvent({ noteId }: { noteId: string }): Promise<void> {
|
||||
if (this.isNote(noteId)) {
|
||||
await this.refresh();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user