From a3425eb9df304f2342cf87df12ebe65bdc58eb59 Mon Sep 17 00:00:00 2001 From: DIYgod Date: Mon, 31 Oct 2022 01:11:18 +0000 Subject: [PATCH] feat: dashboard notifications list --- showcase.json | 6 +- src/components/dashboard/DashboardLayout.tsx | 6 + src/components/dashboard/DashboardMain.tsx | 2 +- src/models/site.model.ts | 43 ++++++ .../dashboard/[subdomain]/notifications.tsx | 146 ++++++++++++++++++ src/queries/site.ts | 11 ++ 6 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 src/pages/dashboard/[subdomain]/notifications.tsx diff --git a/showcase.json b/showcase.json index 06063341..54ee371c 100644 --- a/showcase.json +++ b/showcase.json @@ -56,5 +56,9 @@ "jingfelix", "tongyi", "mayx", - "tcj" + "tcj", + "atlas", + "meow-7218", + "erection", + "vup" ] diff --git a/src/components/dashboard/DashboardLayout.tsx b/src/components/dashboard/DashboardLayout.tsx index 168f0422..c2c1044a 100644 --- a/src/components/dashboard/DashboardLayout.tsx +++ b/src/components/dashboard/DashboardLayout.tsx @@ -64,6 +64,12 @@ export function DashboardLayout({ icon: "i-bi-window-stack", text: "Pages", }, + { + href: `/dashboard/${subdomain}/notifications`, + isActive: ({ href, pathname }) => href === pathname, + icon: "i-bi:bell", + text: "Notifications", + }, { href: `/dashboard/${subdomain}/settings/general`, isActive: ({ pathname }) => diff --git a/src/components/dashboard/DashboardMain.tsx b/src/components/dashboard/DashboardMain.tsx index 4a14fc38..13c405a3 100644 --- a/src/components/dashboard/DashboardMain.tsx +++ b/src/components/dashboard/DashboardMain.tsx @@ -10,7 +10,7 @@ export const DashboardMain: React.FC<{ className={clsx( fullWidth ? "relative" - : "max-w-screen-xl relative px-5 py-5 md:px-10", + : "max-w-screen-2xl relative px-5 py-5 md:px-10", )} > {children} diff --git a/src/models/site.model.ts b/src/models/site.model.ts index 6d8bd595..fcdd0e0c 100644 --- a/src/models/site.model.ts +++ b/src/models/site.model.ts @@ -6,6 +6,8 @@ import { toGateway } from "~/lib/ipfs-parser" import type Unidata from "unidata.js" import { createClient } from "@urql/core" import axios from "axios" +import { indexer } from "~/queries/crossbell" +import type { LinkEntity, NoteEntity } from "crossbell.js" export const checkSubdomain = async ({ subdomain, @@ -341,3 +343,44 @@ export async function unsubscribeFromSite( }, ) } + +export async function getNotifications(input: { siteCId: string }) { + const [subscriptions, notes] = await Promise.all([ + indexer.getBacklinksOfCharacter(input.siteCId, { + limit: 100, + }), + indexer.getNotes({ + toCharacterId: input.siteCId, + limit: 100, + includeCharacter: true, + }), + ]) + + return [ + ...(subscriptions.list.map( + ( + item: LinkEntity & { + type?: "backlinks" + }, + ) => { + item.type = "backlinks" + return item + }, + ) as any), + ] + .concat( + notes.list.map( + ( + item: NoteEntity & { + type?: "notes" + }, + ) => { + item.type = "notes" + return item + }, + ), + ) + .sort((a, b) => { + return b.createdAt > a.createdAt ? 1 : -1 + }) +} diff --git a/src/pages/dashboard/[subdomain]/notifications.tsx b/src/pages/dashboard/[subdomain]/notifications.tsx new file mode 100644 index 00000000..30c9efa3 --- /dev/null +++ b/src/pages/dashboard/[subdomain]/notifications.tsx @@ -0,0 +1,146 @@ +import { useRouter } from "next/router" +import { DashboardLayout } from "~/components/dashboard/DashboardLayout" +import { DashboardMain } from "~/components/dashboard/DashboardMain" +import { UniLink } from "~/components/ui/UniLink" +import { getSiteLink } from "~/lib/helpers" +import { useGetNotifications, useGetSite } from "~/queries/site" +import { CharacterCard } from "~/components/common/CharacterCard" +import { Avatar } from "~/components/ui/Avatar" +import dayjs from "dayjs" +import duration from "dayjs/plugin/duration" +import relativeTime from "dayjs/plugin/relativeTime" +import { BlockchainIcon } from "~/components/icons/BlockchainIcon" +import { CSB_SCAN } from "~/lib/env" +import { PageContent } from "~/components/common/PageContent" + +dayjs.extend(duration) +dayjs.extend(relativeTime) + +export default function SubdomainIndex() { + const router = useRouter() + const subdomain = router.query.subdomain as string + + const site = useGetSite(subdomain) + + const notifications = useGetNotifications({ + siteCId: site.data?.metadata?.proof, + }) + + return ( + + +

Notifications

+
+
+ {notifications.data?.map((notification) => { + let key = "" + let character + let message = "" + + switch (notification.type) { + case "notes": + if ( + !notification.toNote.metadata?.content?.sources?.includes( + "xlog", + ) + ) { + return null + } + key = notification.characterId + notification.noteId + character = notification?.character + message = "commented on your post" + break + case "backlinks": + key = notification.fromCharacter.handle + character = notification.fromCharacter + message = "follows you" + break + } + + return ( +
+
+
+ +
+ + + +
+
+
+
+
+ + {character?.metadata?.content?.name || + character?.handle} + {" "} + {message}{" "} + + attribute.trait_type === "xlog_slug", + )?.value || + notification.toNote?.characterId + + "-" + + notification.toNote?.noteId + }`} + > + {notification.toNote?.metadata?.content?.title} + {" "} + ·{" "} + {dayjs + .duration( + dayjs(notification?.createdAt).diff( + dayjs(), + "minute", + ), + "minute", + ) + .humanize()}{" "} + ago ·{" "} + + + +
+ +
+
+
+ ) + })} +
+
+
+
+ ) +} diff --git a/src/queries/site.ts b/src/queries/site.ts index db7c4e00..34a13d1a 100644 --- a/src/queries/site.ts +++ b/src/queries/site.ts @@ -130,3 +130,14 @@ export function useUnsubscribeFromSite() { }, ) } + +export const useGetNotifications = (data: { siteCId?: string }) => { + return useQuery(["getNotifications", data], async () => { + if (!data.siteCId) { + return null + } + return siteModel.getNotifications({ + siteCId: data.siteCId, + }) + }) +}