From 3bed9051e5396f8e3414f46af64fcb36e5d6b4d6 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Wed, 29 Jun 2022 22:43:26 +0100 Subject: [PATCH] feat: crossbell renovation - support navigation --- src/components/site/SitePage.tsx | 2 +- src/lib/types.ts | 11 +++- src/models/site.model.ts | 11 ++-- .../[subdomain]/settings/navigation.tsx | 54 ++++++++++--------- 4 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/components/site/SitePage.tsx b/src/components/site/SitePage.tsx index a1cfb087..34eb4c30 100644 --- a/src/components/site/SitePage.tsx +++ b/src/components/site/SitePage.tsx @@ -43,7 +43,7 @@ export const SitePage: React.FC<{ contentHTML={page.body?.content || ""} className="my-10" /> -
+

🔔 This post has been permanently stored on-chain and signed by its creator.

  • diff --git a/src/lib/types.ts b/src/lib/types.ts index 1714c958..4a608a35 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -1,4 +1,4 @@ -import type { Note as UniNote } from "unidata.js" +import type { Note as UniNote, Profile as UniProfile } from "unidata.js" export type Site = { id: string @@ -78,4 +78,13 @@ export type Note = UniNote & { export type Notes = { total: number, list: Note[], +} + +export type Profile = UniProfile & { + navigation?: SiteNavigationItem[] +} + +export type Profiles = { + total: number, + list: Note[], } \ No newline at end of file diff --git a/src/models/site.model.ts b/src/models/site.model.ts index b9ca979f..04dfb6c3 100644 --- a/src/models/site.model.ts +++ b/src/models/site.model.ts @@ -3,7 +3,7 @@ import { isUUID } from "~/lib/uuid" import { MembershipRole, PageType, type Site } from "~/lib/db.server" import { Gate } from "~/lib/gate.server" import { sendLoginEmail } from "~/lib/mailgun.server" -import { SiteNavigationItem } from "~/lib/types" +import { SiteNavigationItem, Profile } from "~/lib/types" import { nanoid } from "nanoid" import { getMembership } from "./membership" import { checkReservedWords } from "~/lib/reserved-words" @@ -60,7 +60,11 @@ export const getSite = async (input: string) => { platform: 'Crossbell', }); - const site = profiles.list?.sort((a, b) => +new Date(b.date_updated || 0) - +new Date(a.date_updated || 0))?.[0] + const site: Profile = profiles.list?.sort((a, b) => +new Date(b.date_updated || 0) - +new Date(a.date_updated || 0))?.[0] + const navigation = site.tags?.find(tag => tag.startsWith('navigation:'))?.replace('navigation:', "") + if (navigation) { + site.navigation = JSON.parse(navigation) + } if (!site) return null @@ -92,7 +96,7 @@ export async function updateSite( description?: string icon?: string | null subdomain?: string - navigation?: SiteNavigationItem[] // TODO + navigation?: SiteNavigationItem[] }, ) { return await unidata.profiles.set({ @@ -105,6 +109,7 @@ export async function updateSite( ...(payload.description && { bio: payload.description }), ...(payload.icon && { avatars: [payload.icon] }), ...(payload.subdomain && { username: payload.subdomain }), + ...(payload.navigation && { tags: ['navigation:' + JSON.stringify(payload.navigation)] }), }) } diff --git a/src/pages/dashboard/[subdomain]/settings/navigation.tsx b/src/pages/dashboard/[subdomain]/settings/navigation.tsx index f611dbd1..1e3b223d 100644 --- a/src/pages/dashboard/[subdomain]/settings/navigation.tsx +++ b/src/pages/dashboard/[subdomain]/settings/navigation.tsx @@ -6,10 +6,11 @@ import { SettingsLayout } from "~/components/dashboard/SettingsLayout" import { useRouter } from "next/router" import { DashboardLayout } from "~/components/dashboard/DashboardLayout" import { trpc } from "~/lib/trpc" -import { SiteNavigationItem } from "~/lib/types" +import { SiteNavigationItem, Profile } from "~/lib/types" import { nanoid } from "nanoid" import { ReactSortable } from "react-sortablejs" import equal from "fast-deep-equal" +import { getSite, updateSite } from "~/models/site.model" type UpdateItem = (id: string, newItem: Partial) => void @@ -69,20 +70,23 @@ export default function SiteSettingsNavigationPage() { const router = useRouter() const subdomain = router.query.subdomain as string - const trpcContext = trpc.useContext() - const siteResult = trpc.useQuery(["site", { site: subdomain }], { - enabled: !!subdomain, - refetchOnWindowFocus: false, - }) - const updateSite = trpc.useMutation("site.updateSite") + let [site, setSite] = useState(null) + + useEffect(() => { + if (subdomain) { + getSite(subdomain).then((site) => { + setSite(site) + }) + } + }, [subdomain]) const [items, setItems] = useState([]) const itemsModified = useMemo(() => { - if (!siteResult.data) return false - return !equal(items, siteResult.data.navigation) - }, [items, siteResult.data]) + if (!site) return false + return !equal(items, site.navigation) + }, [items, site]) const updateItem: UpdateItem = (id, newItem) => { setItems((items) => { @@ -99,11 +103,20 @@ export default function SiteSettingsNavigationPage() { setItems((items) => [...items, { id: nanoid(), label: "", url: "" }]) } + let [loading, setLoading] = useState(false) const handleSubmit = (e: FormEvent) => { e.preventDefault() - updateSite.mutate({ - site: siteResult.data!.id, + setLoading(true) + updateSite({ + site: site!.username!, navigation: items, + }).then((result) => { + if (result.code === 0) { + toast.success("Saved") + } else { + toast.error("Failed to save" + ": " + result.message) + } + setLoading(false) }) } @@ -112,18 +125,10 @@ export default function SiteSettingsNavigationPage() { } useEffect(() => { - if (siteResult.data?.navigation) { - setItems(siteResult.data.navigation) + if (site?.navigation) { + setItems(site.navigation) } - }, [siteResult.data?.navigation]) - - useEffect(() => { - if (updateSite.isSuccess) { - updateSite.reset() - toast.success("Saved") - trpcContext.invalidateQueries(["site", { site: subdomain }]) - } - }, [updateSite, trpcContext, subdomain]) + }, [site?.navigation]) return ( @@ -135,7 +140,6 @@ export default function SiteSettingsNavigationPage() { No navigation items yet
)} - {/** @ts-expect-error */}