import { t } from "../../services/i18n.js";
import BasicWidget from "../basic_widget.js";
import server from "../../services/server.js";
import dialogService from "../../services/dialog.js";
import toastService from "../../services/toast.js";
import ws from "../../services/ws.js";
import appContext from "../../components/app_context.js";
import openService from "../../services/open.js";
import utils from "../../services/utils.js";
import { Dropdown } from "bootstrap";
import type attachmentsApiRoute from "../../../../routes/api/attachments.js"
import type FAttachment from "../../entities/fattachment.js";
const TPL = `
`;
export default class AttachmentActionsWidget extends BasicWidget {
$uploadNewRevisionInput!: JQuery;
attachment: FAttachment;
isFullDetail: boolean;
dropdown!: Dropdown;
constructor(attachment: FAttachment, isFullDetail: boolean) {
super();
this.attachment = attachment;
this.isFullDetail = isFullDetail;
}
get attachmentId() {
return this.attachment.attachmentId;
}
doRender() {
this.$widget = $(TPL);
this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find("[data-bs-toggle='dropdown']")[0]);
this.$widget.on("click", ".dropdown-item", () => this.dropdown.toggle());
this.$uploadNewRevisionInput = this.$widget.find(".attachment-upload-new-revision-input");
this.$uploadNewRevisionInput.on("change", async () => {
const fileToUpload = this.$uploadNewRevisionInput[0].files?.item(0); // copy to allow reset below
this.$uploadNewRevisionInput.val("");
if (fileToUpload) {
const result = await server.upload(`attachments/${this.attachmentId}/file`, fileToUpload);
if (result.uploaded) {
toastService.showMessage(t("attachments_actions.upload_success"));
} else {
toastService.showError(t("attachments_actions.upload_failed"));
}
}
});
const isElectron = utils.isElectron();
if (!this.isFullDetail) {
const $openAttachmentButton = this.$widget.find("[data-trigger-command='openAttachment']");
$openAttachmentButton.addClass("disabled").append($(' ').attr("title", t("attachments_actions.open_externally_detail_page")));
if (isElectron) {
const $openAttachmentCustomButton = this.$widget.find("[data-trigger-command='openAttachmentCustom']");
$openAttachmentCustomButton.addClass("disabled").append($(' ').attr("title", t("attachments_actions.open_externally_detail_page")));
}
}
if (!isElectron) {
const $openAttachmentCustomButton = this.$widget.find("[data-trigger-command='openAttachmentCustom']");
$openAttachmentCustomButton.addClass("disabled").append($(' ').attr("title", t("attachments_actions.open_custom_client_only")));
}
}
async openAttachmentCommand() {
await openService.openAttachmentExternally(this.attachmentId, this.attachment.mime);
}
async openAttachmentCustomCommand() {
await openService.openAttachmentCustom(this.attachmentId, this.attachment.mime);
}
async downloadAttachmentCommand() {
await openService.downloadAttachment(this.attachmentId);
}
async uploadNewAttachmentRevisionCommand() {
this.$uploadNewRevisionInput.trigger("click");
}
async copyAttachmentLinkToClipboardCommand() {
//TriliumNextTODO: the parent here is AttachmentDetailWidget
//how can we pass that to the generic TypedComponent?
//@ts-ignore - TypedComponent
this.parent?.copyAttachmentLinkToClipboard();
}
async deleteAttachmentCommand() {
if (!(await dialogService.confirm(t("attachments_actions.delete_confirm", { title: this.attachment.title })))) {
return;
}
await server.remove(`attachments/${this.attachmentId}`);
toastService.showMessage(t("attachments_actions.delete_success", { title: this.attachment.title }));
}
async convertAttachmentIntoNoteCommand() {
if (!(await dialogService.confirm(t("attachments_actions.convert_confirm", { title: this.attachment.title })))) {
return;
}
const { note: newNote } = await server.post>(`attachments/${this.attachmentId}/convert-to-note`);
toastService.showMessage(t("attachments_actions.convert_success", { title: this.attachment.title }));
await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.getActiveContext().setNote(newNote.noteId);
}
async renameAttachmentCommand() {
const attachmentTitle = await dialogService.prompt({
title: t("attachments_actions.rename_attachment"),
message: t("attachments_actions.enter_new_name"),
defaultValue: this.attachment.title
});
if (!attachmentTitle?.trim()) {
return;
}
await server.put(`attachments/${this.attachmentId}/rename`, { title: attachmentTitle });
}
}