2025-12-13 10:54:19 +02:00
|
|
|
import "./NoteBadges.css";
|
2025-12-09 21:06:28 +02:00
|
|
|
|
2025-12-10 11:21:06 +02:00
|
|
|
import clsx from "clsx";
|
2025-12-10 09:27:44 +02:00
|
|
|
import { ComponentChildren, MouseEventHandler } from "preact";
|
2025-12-10 11:21:06 +02:00
|
|
|
import { useRef } from "preact/hooks";
|
|
|
|
|
|
2025-12-13 10:47:46 +02:00
|
|
|
import { t } from "../../services/i18n";
|
|
|
|
|
import Dropdown, { DropdownProps } from "../react/Dropdown";
|
|
|
|
|
import { useIsNoteReadOnly, useNoteContext, useNoteLabel, useNoteLabelBoolean, useStaticTooltip } from "../react/hooks";
|
|
|
|
|
import Icon from "../react/Icon";
|
|
|
|
|
import { useShareInfo } from "../shared_info";
|
2025-12-13 12:25:01 +02:00
|
|
|
import { Badge } from "../react/Badge";
|
2025-12-09 21:06:28 +02:00
|
|
|
|
2025-12-13 10:54:19 +02:00
|
|
|
export default function NoteBadges() {
|
2025-12-09 21:06:28 +02:00
|
|
|
return (
|
2025-12-13 10:54:19 +02:00
|
|
|
<div className="note-badges">
|
2025-12-09 21:06:28 +02:00
|
|
|
<ReadOnlyBadge />
|
2025-12-09 21:44:39 +02:00
|
|
|
<ShareBadge />
|
2025-12-11 17:34:04 +02:00
|
|
|
<ClippedNoteBadge />
|
2025-12-11 17:43:00 +02:00
|
|
|
<ExecuteBadge />
|
2025-12-09 21:06:28 +02:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ReadOnlyBadge() {
|
|
|
|
|
const { note, noteContext } = useNoteContext();
|
|
|
|
|
const { isReadOnly, enableEditing } = useIsNoteReadOnly(note, noteContext);
|
|
|
|
|
const isExplicitReadOnly = note?.isLabelTruthy("readOnly");
|
2025-12-11 17:20:28 +02:00
|
|
|
const isTemporarilyEditable = noteContext?.ntxId !== "_popup-editor" && noteContext?.viewScope?.readOnlyTemporarilyDisabled;
|
2025-12-09 21:06:28 +02:00
|
|
|
|
2025-12-10 09:11:28 +02:00
|
|
|
if (isTemporarilyEditable) {
|
|
|
|
|
return <Badge
|
|
|
|
|
icon="bx bx-lock-open-alt"
|
2025-12-10 11:41:14 +02:00
|
|
|
text={t("breadcrumb_badges.read_only_temporarily_disabled")}
|
2025-12-10 09:27:44 +02:00
|
|
|
tooltip={t("breadcrumb_badges.read_only_temporarily_disabled_description")}
|
2025-12-10 09:38:55 +02:00
|
|
|
className="temporarily-editable-badge"
|
2025-12-10 09:11:28 +02:00
|
|
|
onClick={() => enableEditing(false)}
|
2025-12-10 11:41:14 +02:00
|
|
|
/>;
|
2025-12-10 09:11:28 +02:00
|
|
|
} else if (isReadOnly) {
|
|
|
|
|
return <Badge
|
|
|
|
|
icon="bx bx-lock-alt"
|
2025-12-10 11:41:14 +02:00
|
|
|
text={isExplicitReadOnly ? t("breadcrumb_badges.read_only_explicit") : t("breadcrumb_badges.read_only_auto")}
|
2025-12-10 09:27:44 +02:00
|
|
|
tooltip={isExplicitReadOnly ? t("breadcrumb_badges.read_only_explicit_description") : t("breadcrumb_badges.read_only_auto_description")}
|
2025-12-10 09:38:55 +02:00
|
|
|
className="read-only-badge"
|
2025-12-10 09:27:44 +02:00
|
|
|
onClick={() => enableEditing()}
|
2025-12-10 11:41:14 +02:00
|
|
|
/>;
|
2025-12-10 09:11:28 +02:00
|
|
|
}
|
2025-12-09 21:06:28 +02:00
|
|
|
}
|
|
|
|
|
|
2025-12-09 21:44:39 +02:00
|
|
|
function ShareBadge() {
|
|
|
|
|
const { note } = useNoteContext();
|
2025-12-10 09:27:44 +02:00
|
|
|
const { isSharedExternally, link, linkHref } = useShareInfo(note);
|
2025-12-09 21:44:39 +02:00
|
|
|
|
|
|
|
|
return (link &&
|
|
|
|
|
<Badge
|
2025-12-10 18:35:29 +02:00
|
|
|
icon={isSharedExternally ? "bx bx-world" : "bx bx-share-alt"}
|
2025-12-10 11:41:14 +02:00
|
|
|
text={isSharedExternally ? t("breadcrumb_badges.shared_publicly") : t("breadcrumb_badges.shared_locally")}
|
2025-12-10 09:27:44 +02:00
|
|
|
tooltip={isSharedExternally ?
|
|
|
|
|
t("breadcrumb_badges.shared_publicly_description", { link }) :
|
|
|
|
|
t("breadcrumb_badges.shared_locally_description", { link })
|
|
|
|
|
}
|
2025-12-10 09:38:55 +02:00
|
|
|
className="share-badge"
|
2025-12-10 09:47:05 +02:00
|
|
|
href={linkHref}
|
2025-12-10 11:41:14 +02:00
|
|
|
/>
|
2025-12-09 21:44:39 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-11 17:34:04 +02:00
|
|
|
function ClippedNoteBadge() {
|
|
|
|
|
const { note } = useNoteContext();
|
|
|
|
|
const [ pageUrl ] = useNoteLabel(note, "pageUrl");
|
|
|
|
|
|
|
|
|
|
return (pageUrl &&
|
|
|
|
|
<Badge
|
|
|
|
|
className="clipped-note-badge"
|
|
|
|
|
icon="bx bx-globe"
|
|
|
|
|
text={t("breadcrumb_badges.clipped_note")}
|
|
|
|
|
tooltip={t("breadcrumb_badges.clipped_note_description", { url: pageUrl })}
|
|
|
|
|
href={pageUrl}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-11 17:43:00 +02:00
|
|
|
function ExecuteBadge() {
|
|
|
|
|
const { note, parentComponent } = useNoteContext();
|
|
|
|
|
const isScript = note?.isTriliumScript();
|
|
|
|
|
const isSql = note?.isTriliumSqlite();
|
|
|
|
|
const isExecutable = isScript || isSql;
|
|
|
|
|
const [ executeDescription ] = useNoteLabel(note, "executeDescription");
|
|
|
|
|
const [ executeButton ] = useNoteLabelBoolean(note, "executeButton");
|
|
|
|
|
|
|
|
|
|
return (note && isExecutable && (executeDescription || executeButton) &&
|
|
|
|
|
<Badge
|
|
|
|
|
className="execute-badge"
|
|
|
|
|
icon="bx bx-play"
|
|
|
|
|
text={isScript ? t("breadcrumb_badges.execute_script") : t("breadcrumb_badges.execute_sql")}
|
|
|
|
|
tooltip={executeDescription || (isScript ? t("breadcrumb_badges.execute_script_description") : t("breadcrumb_badges.execute_sql_description"))}
|
|
|
|
|
onClick={() => parentComponent.triggerCommand("runActiveNote")}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|