import { EventData } from "../../components/app_context"; import { closeActiveDialog, openDialog } from "../../services/dialog"; import { t } from "../../services/i18n"; import Modal from "../react/Modal"; import ReactBasicWidget from "../react/ReactBasicWidget"; import Button from "../react/Button"; import FormRadioGroup from "../react/FormRadioGroup"; import NoteAutocomplete from "../react/NoteAutocomplete"; import { useRef, useState } from "preact/hooks"; import tree from "../../services/tree"; import { useEffect } from "react"; import note_autocomplete, { Suggestion } from "../../services/note_autocomplete"; import type { default as TextTypeWidget } from "../type_widgets/editable_text.js"; import { logError } from "../../services/ws"; import FormGroup from "../react/FormGroup.js"; type LinkType = "reference-link" | "external-link" | "hyper-link"; interface AddLinkDialogProps { text?: string; textTypeWidget?: TextTypeWidget; } function AddLinkDialogComponent({ text: _text, textTypeWidget }: AddLinkDialogProps) { const [ text, setText ] = useState(_text ?? ""); const [ linkTitle, setLinkTitle ] = useState(""); const hasSelection = textTypeWidget?.hasSelection(); const [ linkType, setLinkType ] = useState(hasSelection ? "hyper-link" : "reference-link"); const [ suggestion, setSuggestion ] = useState(null); async function setDefaultLinkTitle(noteId: string) { const noteTitle = await tree.getNoteTitle(noteId); setLinkTitle(noteTitle); } function resetExternalLink() { if (linkType === "external-link") { setLinkType("reference-link"); } } useEffect(() => { if (!suggestion) { resetExternalLink(); return; } if (suggestion.notePath) { const noteId = tree.getNoteIdFromUrl(suggestion.notePath); if (noteId) { setDefaultLinkTitle(noteId); } resetExternalLink(); } if (suggestion.externalLink) { setLinkTitle(suggestion.externalLink); setLinkType("external-link"); } }, [suggestion]); function onShown() { const $autocompleteEl = $(autocompleteRef.current); if (!text) { note_autocomplete.showRecentNotes($autocompleteEl); } else { note_autocomplete.setText($autocompleteEl, text); } // to be able to quickly remove entered text $autocompleteEl .trigger("focus") .trigger("select"); } function onSubmit() { if (suggestion.notePath) { // Handle note link closeActiveDialog(); textTypeWidget?.addLink(suggestion.notePath, linkType === "reference-link" ? null : linkTitle); } else if (suggestion.externalLink) { // Handle external link closeActiveDialog(); textTypeWidget?.addLink(suggestion.externalLink, linkTitle, true); } else { logError("No link to add."); } } const autocompleteRef = useRef(null); return ( } onSubmit={onSubmit} onShown={onShown} onHidden={() => setSuggestion(null)} > {!hasSelection && (
{(linkType !== "external-link") && ( <> setLinkType(newValue as LinkType)} /> )} {(linkType !== "reference-link" && (

))}
)}
); } export default class AddLinkDialog extends ReactBasicWidget { private props: AddLinkDialogProps = {}; get component() { return ; } async showAddLinkDialogEvent({ textTypeWidget, text = "" }: EventData<"showAddLinkDialog">) { this.props.text = text; this.props.textTypeWidget = textTypeWidget; this.doRender(); await openDialog(this.$widget); } }