Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

port js to ts #1270

Merged
merged 3 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 0 additions & 56 deletions src/public/app/widgets/bookmark_buttons.js

This file was deleted.

78 changes: 78 additions & 0 deletions src/public/app/widgets/bookmark_buttons.ts
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
Original file line number Diff line number Diff line change
@@ -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">
Expand Down Expand Up @@ -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
};
Expand All @@ -73,5 +84,5 @@ export default class BookmarkFolderWidget extends RightDropdownButtonWidget {
}
}

refreshIcon() {}
refreshIcon(): void {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ 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() {
return super.isEnabled() && this.note && this.noteContext.viewScope.viewMode === "default";
isEnabled(): boolean {
return Boolean(super.isEnabled() && this.note && this.noteContext?.viewScope?.viewMode === "default");
}

constructor() {
Expand All @@ -16,15 +19,15 @@ export default class EditButton extends OnClickButtonWidget {
.title(t("edit_button.edit_this_note"))
.titlePlacement("bottom")
.onClick((widget) => {
this.noteContext.viewScope.readOnlyTemporarilyDisabled = true;

appContext.triggerEvent("readOnlyTemporarilyDisabled", { noteContext: this.noteContext });

if (this.noteContext?.viewScope) {
this.noteContext.viewScope.readOnlyTemporarilyDisabled = true;
appContext.triggerEvent("readOnlyTemporarilyDisabled", { noteContext: this.noteContext });
}
this.refresh();
});
}

async refreshWithNote(note) {
async refreshWithNote(note: FNote): Promise<void> {
if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) {
this.toggleInt(false);
} else {
Expand All @@ -34,31 +37,38 @@ export default class EditButton extends OnClickButtonWidget {
const wasVisible = this.isVisible();

// can't do this in isEnabled() since isReadOnly is async
this.toggleInt(await this.noteContext.isReadOnly());
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) {
if (this.isVisible() && !wasVisible && this.$widget) {
this.$widget.addClass("bx-tada bx-lg");

setTimeout(() => {
this.$widget.removeClass("bx-tada bx-lg");
this.$widget?.removeClass("bx-tada bx-lg");
}, 1700);
}
}

await super.refreshWithNote(note);
}

entitiesReloadedEvent({ loadResults }) {
if (loadResults.getAttributeRows().find((attr) => attr.type === "label" && attr.name.toLowerCase().includes("readonly") && attributeService.isAffecting(attr, this.note))) {
this.noteContext.viewScope.readOnlyTemporarilyDisabled = false;

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 }) {
async noteTypeMimeChangedEvent({ noteId }: { noteId: string }): Promise<void> {
if (this.isNote(noteId)) {
await this.refresh();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
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>
</div>
`;

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;
Expand All @@ -29,10 +40,10 @@ export default class RightDropdownButtonWidget extends BasicWidget {
doRender() {
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]
});
Expand All @@ -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);
Expand All @@ -60,5 +72,5 @@ export default class RightDropdownButtonWidget extends BasicWidget {
}

// to be overridden
async dropdownShow() {}
async dropdownShown(): Promise<void> {}
}

This file was deleted.

Loading