diff --git a/bun.lockb b/bun.lockb index dce45b0b..7a133c97 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/web/components/routes/link/form/manage.tsx b/web/components/routes/link/form/manage.tsx index 1dc01fb9..f25ed934 100644 --- a/web/components/routes/link/form/manage.tsx +++ b/web/components/routes/link/form/manage.tsx @@ -130,8 +130,10 @@ const LinkForm = React.forwardRef(({ onSuccess, }) const title = form.watch("title") + const [inputValue, setInputValue] = useState("") const [originalLink, setOriginalLink] = useState("") - const [linkEntered, setLinkEntered] = useState(false) + const [invalidLink, setInvalidLink] = useState(false) + const [showLinkStatus, setShowLinkStatus] = useState(false) const [debouncedText, setDebouncedText] = useState("") useDebounce(() => setDebouncedText(title), 300, [title]) @@ -166,11 +168,33 @@ const LinkForm = React.forwardRef(({ onSuccess, } }, [selectedLink, form]) + const changeInput = (e: React.ChangeEvent) => { + const value = e.target.value + setInputValue(value) + setShowLinkStatus(false) + setInvalidLink(false) + } + + const pressEnter = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + e.preventDefault() + const trimmedValue = inputValue.trim().toLowerCase() + if (LibIsUrl(trimmedValue)) { + form.setValue("title", trimmedValue) + setShowLinkStatus(true) + setInvalidLink(false) + } else { + setInvalidLink(true) + setShowLinkStatus(true) + } + } + } + useEffect(() => { const fetchMetadata = async (url: string) => { setIsFetching(true) try { - const res = await fetch(`/api/metadata?url=${encodeURIComponent(url)}`, { cache: "no-store" }) + const res = await fetch(`/api/metadata?url=${encodeURIComponent(url)}`, { cache: "force-cache" }) if (!res.ok) throw new Error("Failed to fetch metadata") const data = await res.json() form.setValue("isLink", true) @@ -188,19 +212,10 @@ const LinkForm = React.forwardRef(({ onSuccess, setIsFetching(false) } } - - const lowerText = debouncedText.toLowerCase() - if (linkEntered && LibIsUrl(lowerText)) { - fetchMetadata(ensureUrlProtocol(lowerText)) + if (showLinkStatus && !invalidLink && LibIsUrl(form.getValues("title").toLowerCase())) { + fetchMetadata(ensureUrlProtocol(form.getValues("title").toLowerCase())) } - }, [debouncedText, form, linkEntered]) - - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === "Enter" && LibIsUrl(e.currentTarget.value.toLowerCase())) { - e.preventDefault() - setLinkEntered(true) - } - } + }, [showLinkStatus, invalidLink, form]) const onSubmit = (values: LinkFormValues) => { if (isFetching) return @@ -221,11 +236,9 @@ const LinkForm = React.forwardRef(({ onSuccess, selectedLink.description = values.description ?? "" selectedLink.isLink = values.isLink - if (selectedLink.meta) { - Object.assign(selectedLink.meta, values.meta) + if (values.isLink && values.meta) { + linkMetadata = LinkMetadata.create(values.meta, { owner: me._owner }) } - - // toast.success("Todo updated") } else { const newPersonalLink = PersonalLink.create( { @@ -252,14 +265,14 @@ const LinkForm = React.forwardRef(({ onSuccess, } } - const handleCancel: () => void = () => { + const undoEditing: () => void = () => { form.reset(DEFAULT_FORM_VALUES) onCancel?.() } return (
-
+
@@ -271,7 +284,7 @@ const LinkForm = React.forwardRef(({ onSuccess, variant="secondary" size="icon" aria-label="Choose icon" - className="text-primary/60 size-7" + className="size-7 text-primary/60" > {form.watch("isLink") ? ( (({ onSuccess, )} /> - - {linkEntered - ? originalLink - : LibIsUrl(form.watch("title").toLowerCase()) - ? 'Press "Enter" to confirm URL' - : ""} - + {showLinkStatus && ( + + {invalidLink ? "Allowing links only" : originalLink || ""} + + )}
- - {/* */} - + Actions - + Delete @@ -393,7 +397,7 @@ const LinkForm = React.forwardRef(({ onSuccess, {...field} autoComplete="off" placeholder="Description (optional)" - className="placeholder:text-primary/40 min-h-[24px] resize-none overflow-y-auto border-none p-1.5 text-xs font-medium shadow-none focus-visible:outline-none focus-visible:ring-0" + className="min-h-[24px] resize-none overflow-y-auto border-none p-1.5 text-xs font-medium shadow-none placeholder:text-primary/40 focus-visible:outline-none focus-visible:ring-0" onInput={e => { const target = e.target as HTMLTextAreaElement target.style.height = "auto" @@ -416,7 +420,7 @@ const LinkForm = React.forwardRef(({ onSuccess,
-