"use client"; import { callRPC } from "app/api/rpc/client"; import { ButtonPrimary } from "components/Buttons"; import { Input } from "components/Input"; import React, { useState, useRef, useEffect } from "react"; import { updatePublication, updatePublicationBasePath, } from "./updatePublication"; import { usePublicationData } from "../[did]/[publication]/dashboard/PublicationSWRProvider"; import { PubLeafletPublication } from "lexicons/api"; import useSWR, { mutate } from "swr"; import { AddTiny } from "components/Icons/AddTiny"; import { DotLoader } from "components/utils/DotLoader"; import { useSmoker, useToaster } from "components/Toast"; import { addPublicationDomain } from "actions/domains/addDomain"; import { LoadingTiny } from "components/Icons/LoadingTiny"; import { PinTiny } from "components/Icons/PinTiny"; import { Verification } from "@vercel/sdk/esm/models/getprojectdomainop"; import Link from "next/link"; import { Checkbox } from "components/Checkbox"; import type { GetDomainConfigResponseBody } from "@vercel/sdk/esm/models/getdomainconfigop"; import { PubSettingsHeader } from "../[did]/[publication]/dashboard/PublicationSettings"; export const EditPubForm = (props: { backToMenuAction: () => void; loading: boolean; setLoadingAction: (l: boolean) => void; }) => { let { data } = usePublicationData(); let { publication: pubData } = data || {}; let record = pubData?.record as PubLeafletPublication.Record; let [formState, setFormState] = useState<"normal" | "loading">("normal"); let [nameValue, setNameValue] = useState(record?.name || ""); let [showInDiscover, setShowInDiscover] = useState( record?.preferences?.showInDiscover === undefined ? true : record.preferences.showInDiscover, ); let [showComments, setShowComments] = useState( record?.preferences?.showComments === undefined ? true : record.preferences.showComments, ); let [descriptionValue, setDescriptionValue] = useState( record?.description || "", ); let [iconFile, setIconFile] = useState(null); let [iconPreview, setIconPreview] = useState(null); let fileInputRef = useRef(null); useEffect(() => { if (!pubData || !pubData.record) return; setNameValue(record.name); setDescriptionValue(record.description || ""); if (record.icon) setIconPreview( `/api/atproto_images?did=${pubData.identity_did}&cid=${(record.icon.ref as unknown as { $link: string })["$link"]}`, ); }, [pubData]); let toast = useToaster(); return (
{ if (!pubData) return; e.preventDefault(); props.setLoadingAction(true); let data = await updatePublication({ uri: pubData.uri, name: nameValue, description: descriptionValue, iconFile: iconFile, preferences: { showInDiscover: showInDiscover, showComments: showComments, }, }); toast({ type: "success", content: "Updated!" }); props.setLoadingAction(false); mutate("publication-data"); }} >

Logo (optional)

fileInputRef.current?.click()} > {iconPreview ? ( Logo preview ) : ( )}
{ const file = e.target.files?.[0]; if (file) { setIconFile(file); const reader = new FileReader(); reader.onload = (e) => { setIconPreview(e.target?.result as string); }; reader.readAsDataURL(file); } }} />

setShowInDiscover(e.target.checked)} >

Show In{" "} Discover

This publication will appear on our public Discover page

setShowComments(e.target.checked)} >

Show comments on posts

); }; export function CustomDomainForm() { let { data } = usePublicationData(); let { publication: pubData } = data || {}; if (!pubData) return null; let record = pubData?.record as PubLeafletPublication.Record; let [state, setState] = useState< | { type: "default" } | { type: "addDomain" } | { type: "domainSettings"; domain: string; verification?: Verification[]; config?: GetDomainConfigResponseBody; } >({ type: "default" }); let domains = pubData?.publication_domains || []; return (

Publication Domain{domains.length > 1 && "s"}

{state.type === "addDomain" ? ( setState({ type: "default" })} setDomain={(d) => setState({ type: "domainSettings", domain: d })} /> ) : state.type === "domainSettings" ? ( setState({ type: "default" })} /> ) : (
{domains.map((d) => ( { setState({ type: "domainSettings", domain: d.domain, verification: v?.verification, config: v?.config, }); }} />
))}
)}
); } function AddDomain(props: { publication_uri: string; goBack: () => void; setDomain: (d: string) => void; }) { let [domain, setDomain] = useState(""); let smoker = useSmoker(); return (
); } // OKay so... You hit this button, it gives you a form. You type in the form, and then hit add. We create a record, and a the record link it to your publiction. Then we show you the stuff to set. ) // We don't want to switch it, until it works. // There's a checkbox to say that this is hosted somewhere else function Domain(props: { domain: string; base_path: string; publication_uri: string; setDomain: (domain?: { verification?: Verification[]; config?: GetDomainConfigResponseBody; }) => void; }) { let { data } = useSWR(props.domain, async (domain) => { return await callRPC("get_domain_status", { domain }); }); let pending = data?.config?.misconfigured || data?.verification; return (
{props.domain}
{pending ? ( ) : props.base_path === props.domain ? (

current default domain

) : ( )}
); } const DomainSettings = (props: { domain: string; config?: GetDomainConfigResponseBody; goBack: () => void; verification?: Verification[]; }) => { let { data, mutate } = useSWR(props.domain, async (domain) => { return await callRPC("get_domain_status", { domain }); }); let isSubdomain = props.domain.split(".").length > 2; if (!data) return; let { config, verification } = data; if (!config?.misconfigured && !verification) return
This domain is verified!
; return (
To verify this domain, add the following record to your DNS provider for{" "} {props.domain}.
{verification && ( )} {config && (isSubdomain ? ( ) : ( ))} {config?.configuredBy === "CNAME" && config.recommendedCNAME[0] && ( )}
Type Name Value
{verification[0].type}
{verification[0].domain}
{verification?.[0].value}
CNAME
{props.domain.split(".").slice(0, -2).join(".")}
{ config?.recommendedCNAME.sort( (a, b) => a.rank - b.rank, )[0].value }
A
@
{ config?.recommendedIPv4.sort((a, b) => a.rank - b.rank)[0] .value[0] }
mutate()} />
); }; const VerifyButton = (props: { verify: () => Promise }) => { let [loading, setLoading] = useState(false); return ( ); };