diff --git a/app/(app)/calendar/[naddr]/layout.tsx b/app/(app)/calendar/[naddr]/layout.tsx index 2665690..8d26e11 100644 --- a/app/(app)/calendar/[naddr]/layout.tsx +++ b/app/(app)/calendar/[naddr]/layout.tsx @@ -1,18 +1,31 @@ import type { Metadata, ResolvingMetadata } from "next"; import { get } from "@/lib/server-actions/events/cache"; +import { getEvent } from "@/lib/server-actions/meta/event"; +import { nip19 } from "nostr-tools"; +import { getTagValues } from "@/lib/nostr/utils"; export async function generateMetadata( { params }: { params: { naddr: string } }, parent: ResolvingMetadata, ): Promise { + const previousImages = (await parent).openGraph?.images || []; + // read route params const identifier = params.naddr; + const { data, type } = nip19.decode(identifier); + if (type !== "naddr") { + return { + title: "Flockstr Calendar", + openGraph: { + images: previousImages, + }, + }; + } // fetch data - const event = await get(identifier); + const event = await getEvent(data.kind, data.pubkey, data.identifier); // optionally access and extend (rather than replace) parent metadata - const previousImages = (await parent).openGraph?.images || []; if (!event) { return { title: "Flockstr Calendar", @@ -21,21 +34,24 @@ export async function generateMetadata( }, }; } - const title = `${event.name} | Flockstr`; - const images = event.image - ? [event.image, ...previousImages] - : previousImages; + + const title = `${getTagValues("name", event.tags as string[][])} | Flockstr`; + const images = + getTagValues("image", event.tags as string[][]) ?? + getTagValues("banner", event.tags as string[][]) ?? + ""; + return { title: title, - description: event.description, + description: event.content, openGraph: { title: title, - description: event.description, + description: event.content, images: images, }, twitter: { title: title, - description: event.description, + description: event.content, images: images, card: "summary_large_image", }, diff --git a/app/(app)/event/[naddr]/layout.tsx b/app/(app)/event/[naddr]/layout.tsx index 9efc5e0..9692da6 100644 --- a/app/(app)/event/[naddr]/layout.tsx +++ b/app/(app)/event/[naddr]/layout.tsx @@ -1,18 +1,29 @@ import type { Metadata, ResolvingMetadata } from "next"; -import { get } from "@/lib/server-actions/events/cache"; +import { getEvent } from "@/lib/server-actions/meta/event"; +import { nip19 } from "nostr-tools"; +import { getTagValues } from "@/lib/nostr/utils"; export async function generateMetadata( { params }: { params: { naddr: string } }, parent: ResolvingMetadata, ): Promise { + const previousImages = (await parent).openGraph?.images || []; // read route params const identifier = params.naddr; + const { data, type } = nip19.decode(identifier); + if (type !== "naddr") { + return { + title: "Flockstr Event", + openGraph: { + images: previousImages, + }, + }; + } // fetch data - const event = await get(identifier); + const event = await getEvent(data.kind, data.pubkey, data.identifier); // optionally access and extend (rather than replace) parent metadata - const previousImages = (await parent).openGraph?.images || []; if (!event) { return { title: "Flockstr Event", @@ -21,22 +32,25 @@ export async function generateMetadata( }, }; } - const title = `${event.name} | Flockstr`; - const images = event.image - ? [event.image, ...previousImages] - : previousImages; + + const title = `${getTagValues("name", event.tags as string[][])} | Flockstr`; + const images = + getTagValues("image", event.tags as string[][]) ?? + getTagValues("banner", event.tags as string[][]) ?? + ""; + return { title: title, - description: event.description, + description: event.content, openGraph: { title: title, - description: event.description, - images: images, + description: event.content, + images: [images], }, twitter: { title: title, - description: event.description, - images: images, + description: event.content, + images: [images], card: "summary_large_image", }, }; diff --git a/bun.lockb b/bun.lockb index 02c1670..6051581 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components/Modals/CreateCalendar.tsx b/components/Modals/CreateCalendar.tsx index 2262c76..440023d 100644 --- a/components/Modals/CreateCalendar.tsx +++ b/components/Modals/CreateCalendar.tsx @@ -57,7 +57,7 @@ export default function CreateCalendarEventModal() { } if (!name) { - setError("Please add a title"); + setError("Please add a name"); return; } setIsLoading(true); diff --git a/db/client.ts b/db/client.ts new file mode 100644 index 0000000..10082dc --- /dev/null +++ b/db/client.ts @@ -0,0 +1,11 @@ +import { PrismaClient } from "@prisma/client"; + +declare global { + var prisma: PrismaClient | undefined; +} + +const prisma = global.prisma || new PrismaClient(); + +if (process.env.NODE_ENV === "development") global.prisma = prisma; + +export default prisma; diff --git a/lib/server-actions/meta/event.ts b/lib/server-actions/meta/event.ts new file mode 100644 index 0000000..f774393 --- /dev/null +++ b/lib/server-actions/meta/event.ts @@ -0,0 +1,12 @@ +"use server"; +import prisma from "@/db/client"; + +export async function getEvent(kind: number, pubkey: string, d: string) { + return await prisma.nostrEvent.findFirst({ + where: { + kind, + pubkey, + d, + }, + }); +} diff --git a/package.json b/package.json index f83c2f5..5de9f54 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@nostr-dev-kit/ndk": "^2.0.0", "@nostr-dev-kit/ndk-cache-dexie": "^2.0.3", "@nostr-dev-kit/ndk-react": "^0.1.1", + "@prisma/client": "^5.8.0", "@radix-ui/react-aspect-ratio": "^1.0.3", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", @@ -53,6 +54,7 @@ "next-themes": "^0.2.1", "node-html-parser": "^6.1.10", "nostr-tools": "^1.16.0", + "prisma": "^5.8.0", "ramda": "^0.29.1", "react": "^18", "react-aria": "^3.29.1", diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..115fd02 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,33 @@ +// This is your Prisma schema file, +// learn more about it in the docs: https://pris.ly/d/prisma-schema + +// datasource db { +// provider = "postgresql" +// url = env("POSTGRES_PRISMA_URL") // uses connection pooling +// directUrl = env("POSTGRES_URL_NON_POOLING") // uses a direct connection +// } + +// generator client { +// provider = "prisma-client-js" +// } +datasource db { + provider = "mysql" + url = env("DATABASE_URL") + relationMode = "prisma" +} + +generator client { + provider = "prisma-client-js" +} + +model NostrEvent { + key Int @id @default(autoincrement()) + id String + kind Int + content String @default("") @db.Text + created_at Int + pubkey String + tags Json @default("[]") + sig String + d String? +}