import "./InlineTitle.css"; import { NoteType } from "@triliumnext/commons"; import clsx from "clsx"; import { ComponentChild } from "preact"; import { useEffect, useMemo, useRef, useState } from "preact/hooks"; import { Trans } from "react-i18next"; import FNote from "../../entities/fnote"; import { ViewScope } from "../../services/link"; import { formatDateTime } from "../../utils/formatters"; import NoteIcon from "../note_icon"; import NoteTitleWidget from "../note_title"; import { useNoteContext, useNoteProperty, useStaticTooltip } from "../react/hooks"; import { joinElements } from "../react/react_utils"; import { useNoteMetadata } from "../ribbon/NoteInfoTab"; import { NOTE_TYPES } from "../../services/note_types"; import { Badge } from "../react/Badge"; import server from "../../services/server"; const supportedNoteTypes = new Set([ "text", "code" ]); export default function InlineTitle() { const { note, parentComponent, viewScope } = useNoteContext(); const [ shown, setShown ] = useState(shouldShow(note, viewScope)); const containerRef= useRef(null); useEffect(() => { setShown(shouldShow(note, viewScope)); }, [ note, viewScope ]); useEffect(() => { if (!shown) return; const titleRow = parentComponent.$widget[0] .closest(".note-split") ?.querySelector("&> .title-row"); if (!titleRow) return; const observer = new IntersectionObserver((entries) => { titleRow.classList.toggle("collapse", entries[0].isIntersecting); }); if (containerRef.current) { observer.observe(containerRef.current); } return () => { titleRow.classList.remove("collapse"); observer.disconnect(); }; }, [ shown, parentComponent ]); return (
); } function shouldShow(note: FNote | null | undefined, viewScope: ViewScope | undefined) { if (!note) return false; if (viewScope?.viewMode !== "default") return false; if (note.noteId.startsWith("_options")) return true; return supportedNoteTypes.has(note.type); } //#region Title details export function NoteTitleDetails() { const { note } = useNoteContext(); const { metadata } = useNoteMetadata(note); const isHiddenNote = note?.noteId.startsWith("_"); const items: ComponentChild[] = [ (!isHiddenNote && metadata?.dateCreated && ), (!isHiddenNote && metadata?.dateModified && ) ].filter(item => !!item); return items.length > 0 && (
{joinElements(items, " • ")}
); } function TextWithValue({ i18nKey, value, valueTooltip }: { i18nKey: string; value: string; valueTooltip: string; }) { const listItemRef = useRef(null); useStaticTooltip(listItemRef, { selector: "span.value", title: valueTooltip, popperConfig: { placement: "bottom" } }); return (
  • {value} as React.ReactElement }} />
  • ); } //#endregion //#region Note type switcher function NoteTypeSwitcher() { const { note } = useNoteContext(); const currentNoteType = useNoteProperty(note, "type"); const noteTypes = useMemo(() => NOTE_TYPES.filter((nt) => !nt.reserved && !nt.static), []); return (note &&
    {noteTypes.map(noteType => noteType.type !== currentNoteType && ( server.put(`notes/${note.noteId}/type`, { type: noteType.type, mime: noteType.mime })} /> ))}
    ); } //#endregion