import { ConvertToAttachmentResponse } from "@triliumnext/commons";
import { useContext } from "preact/hooks";
import appContext, { CommandNames } from "../../components/app_context";
import NoteContext from "../../components/note_context";
import FNote from "../../entities/fnote";
import branches from "../../services/branches";
import dialog from "../../services/dialog";
import { t } from "../../services/i18n";
import server from "../../services/server";
import toast from "../../services/toast";
import { isElectron as getIsElectron, isMac as getIsMac } from "../../services/utils";
import ws from "../../services/ws";
import ActionButton from "../react/ActionButton";
import Dropdown from "../react/Dropdown";
import { FormDropdownDivider, FormDropdownSubmenu, FormListItem, FormListToggleableItem } from "../react/FormList";
import { useIsNoteReadOnly, useNoteContext, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useTriliumOption } from "../react/hooks";
import { ParentComponent } from "../react/react_utils";
import { isExperimentalFeatureEnabled } from "../../services/experimental_features";
import { useNoteBookmarkState, useShareState } from "./BasicPropertiesTab";
const isNewLayout = isExperimentalFeatureEnabled("new-layout");
export default function NoteActions() {
const { note, noteContext } = useNoteContext();
return (
{note && !isNewLayout && }
{note && note.type !== "launcher" && }
);
}
function RevisionsButton({ note }: { note: FNote }) {
const isEnabled = !["launcher", "doc"].includes(note?.type ?? "");
return (isEnabled &&
);
}
function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: NoteContext }) {
const parentComponent = useContext(ParentComponent);
const noteType = useNoteProperty(note, "type") ?? "";
const [viewType] = useNoteLabel(note, "viewType");
const canBeConvertedToAttachment = note?.isEligibleForConversionToAttachment();
const isSearchable = ["text", "code", "book", "mindMap", "doc"].includes(noteType);
const isInOptionsOrHelp = note?.noteId.startsWith("_options") || note?.noteId.startsWith("_help");
const isPrintable = ["text", "code"].includes(noteType) || (noteType === "book" && ["presentation", "list", "table"].includes(viewType ?? ""));
const isElectron = getIsElectron();
const isMac = getIsMac();
const hasSource = ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "aiChat"].includes(noteType);
const isSearchOrBook = ["search", "book"].includes(noteType);
const [syncServerHost] = useTriliumOption("syncServerHost");
const { isReadOnly, enableEditing } = useIsNoteReadOnly(note, noteContext);
return (
{isReadOnly && <>
enableEditing()} />
>}
{canBeConvertedToAttachment && }
{note.type === "render" && }
{isElectron && }
{isNewLayout && }
parentComponent?.triggerCommand("showImportDialog", { noteId: note.noteId })} />
noteContext?.notePath && parentComponent?.triggerCommand("showExportDialog", {
notePath: noteContext.notePath,
defaultType: "single"
})} />
{(syncServerHost && isElectron) &&
}
branches.deleteNotes([note.getParentBranches()[0].branchId])}
/>
{glob.isDev && }
);
}
function NoteBasicProperties({ note }: { note: FNote }) {
const [ isBookmarked, setIsBookmarked ] = useNoteBookmarkState(note);
const [ isShared, switchShareState ] = useShareState(note);
const [ isTemplate, setIsTemplate ] = useNoteLabelBoolean(note, "template");
return <>
>;
}
function EditabilityDropdown({ note }: { note: FNote }) {
const [ readOnly, setReadOnly ] = useNoteLabelBoolean(note, "readOnly");
const [ autoReadOnlyDisabled, setAutoReadOnlyDisabled ] = useNoteLabelBoolean(note, "autoReadOnlyDisabled");
function setState(readOnly: boolean, autoReadOnlyDisabled: boolean) {
setReadOnly(readOnly);
setAutoReadOnlyDisabled(autoReadOnlyDisabled);
}
return (
setState(false, false)} description={t("editability_select.note_is_editable")}>{t("editability_select.auto")}
setState(true, false)} description={t("editability_select.note_is_read_only")}>{t("editability_select.read_only")}
setState(false, true)} description={t("editability_select.note_is_always_editable")}>{t("editability_select.always_editable")}
);
}
function DevelopmentActions({ note, noteContext }: { note: FNote, noteContext?: NoteContext }) {
return (
window.open(`/?print=#root/${note.noteId}`, "_blank")}
>Open print page
{
noteContext?.getTextEditor(editor => {
editor.editing.view.change(() => {
throw new Error("Editor crashed.");
});
});
}}>Crash editor
);
}
function CommandItem({ icon, text, title, command, disabled }: { icon: string, text: string, title?: string, command: CommandNames | (() => void), disabled?: boolean, destructive?: boolean }) {
return {text};
}
function ConvertToAttachment({ note }: { note: FNote }) {
return (
{
if (!note || !(await dialog.confirm(t("note_actions.convert_into_attachment_prompt", { title: note.title })))) {
return;
}
const { attachment: newAttachment } = await server.post(`notes/${note.noteId}/convert-to-attachment`);
if (!newAttachment) {
toast.showMessage(t("note_actions.convert_into_attachment_failed", { title: note.title }));
return;
}
toast.showMessage(t("note_actions.convert_into_attachment_successful", { title: newAttachment.title }));
await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.getActiveContext()?.setNote(newAttachment.ownerId, {
viewScope: {
viewMode: "attachments",
attachmentId: newAttachment.attachmentId
}
});
}}
>{t("note_actions.convert_into_attachment")}
);
}