mirror of
https://github.com/linsa-io/linsa.git
synced 2026-04-25 01:38:35 +02:00
fix: authed
This commit is contained in:
@@ -5,7 +5,7 @@ import { useForm } from "react-hook-form"
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { toast } from "sonner"
|
||||
import { createLinkSchema, LinkFormValues } from "./-schema"
|
||||
import { cn, generateUniqueSlug } from "@/lib/utils"
|
||||
import { cn, ensureUrlProtocol, generateUniqueSlug } from "@/lib/utils"
|
||||
import { Form } from "@/components/ui/form"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { atom, useAtom } from "jotai"
|
||||
@@ -22,12 +22,91 @@ import { useOnClickOutside } from "~/hooks/use-on-click-outside"
|
||||
import TopicSelector, {
|
||||
topicSelectorAtom,
|
||||
} from "~/components/custom/topic-selector"
|
||||
import { getMetadata } from "~/actions"
|
||||
import { createServerFn } from "@tanstack/start"
|
||||
import { urlSchema } from "~/lib/utils/schema"
|
||||
import * as cheerio from "cheerio"
|
||||
|
||||
interface Metadata {
|
||||
title: string
|
||||
description: string
|
||||
icon: string | null
|
||||
url: string
|
||||
}
|
||||
|
||||
const DEFAULT_VALUES = {
|
||||
TITLE: "",
|
||||
DESCRIPTION: "",
|
||||
FAVICON: null,
|
||||
}
|
||||
|
||||
export const globalLinkFormExceptionRefsAtom = atom<
|
||||
React.RefObject<HTMLElement>[]
|
||||
>([])
|
||||
|
||||
export const getMetadata = createServerFn("GET", async (url: string) => {
|
||||
if (!url) {
|
||||
return new Response('Missing "url" query parameter', {
|
||||
status: 400,
|
||||
})
|
||||
}
|
||||
|
||||
const result = urlSchema.safeParse(url)
|
||||
if (!result.success) {
|
||||
throw new Error(
|
||||
result.error.issues.map((issue) => issue.message).join(", "),
|
||||
)
|
||||
}
|
||||
|
||||
url = ensureUrlProtocol(url)
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.text()
|
||||
const $ = cheerio.load(data)
|
||||
|
||||
const metadata: Metadata = {
|
||||
title:
|
||||
$("title").text() ||
|
||||
$('meta[property="og:title"]').attr("content") ||
|
||||
DEFAULT_VALUES.TITLE,
|
||||
description:
|
||||
$('meta[name="description"]').attr("content") ||
|
||||
$('meta[property="og:description"]').attr("content") ||
|
||||
DEFAULT_VALUES.DESCRIPTION,
|
||||
icon:
|
||||
$('link[rel="icon"]').attr("href") ||
|
||||
$('link[rel="shortcut icon"]').attr("href") ||
|
||||
DEFAULT_VALUES.FAVICON,
|
||||
url: url,
|
||||
}
|
||||
|
||||
if (metadata.icon && !metadata.icon.startsWith("http")) {
|
||||
metadata.icon = new URL(metadata.icon, url).toString()
|
||||
}
|
||||
|
||||
return metadata
|
||||
} catch (error) {
|
||||
console.error("Error fetching metadata:", error)
|
||||
const defaultMetadata: Metadata = {
|
||||
title: DEFAULT_VALUES.TITLE,
|
||||
description: DEFAULT_VALUES.DESCRIPTION,
|
||||
icon: DEFAULT_VALUES.FAVICON,
|
||||
url: url,
|
||||
}
|
||||
return defaultMetadata
|
||||
}
|
||||
})
|
||||
|
||||
interface LinkFormProps extends React.ComponentPropsWithoutRef<"form"> {
|
||||
onClose?: () => void
|
||||
onSuccess?: () => void
|
||||
|
||||
Reference in New Issue
Block a user