Compare commits
No commits in common. "b2dfaa18d1cd9e87e477c1cacd068d52cc6a695c" and "3fa54dea990bed64ffb7183b6da154f9304e2e66" have entirely different histories.
b2dfaa18d1
...
3fa54dea99
@ -1,31 +1,18 @@
|
|||||||
import type { Metadata, ResolvingMetadata } from "next";
|
import type { Metadata, ResolvingMetadata } from "next";
|
||||||
import { get } from "@/lib/server-actions/events/cache";
|
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(
|
export async function generateMetadata(
|
||||||
{ params }: { params: { naddr: string } },
|
{ params }: { params: { naddr: string } },
|
||||||
parent: ResolvingMetadata,
|
parent: ResolvingMetadata,
|
||||||
): Promise<Metadata> {
|
): Promise<Metadata> {
|
||||||
const previousImages = (await parent).openGraph?.images || [];
|
|
||||||
|
|
||||||
// read route params
|
// read route params
|
||||||
const identifier = params.naddr;
|
const identifier = params.naddr;
|
||||||
const { data, type } = nip19.decode(identifier);
|
|
||||||
if (type !== "naddr") {
|
|
||||||
return {
|
|
||||||
title: "Flockstr Calendar",
|
|
||||||
openGraph: {
|
|
||||||
images: previousImages,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch data
|
// fetch data
|
||||||
const event = await getEvent(data.kind, data.pubkey, data.identifier);
|
const event = await get(identifier);
|
||||||
|
|
||||||
// optionally access and extend (rather than replace) parent metadata
|
// optionally access and extend (rather than replace) parent metadata
|
||||||
|
const previousImages = (await parent).openGraph?.images || [];
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return {
|
return {
|
||||||
title: "Flockstr Calendar",
|
title: "Flockstr Calendar",
|
||||||
@ -34,24 +21,21 @@ export async function generateMetadata(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
const title = `${event.name} | Flockstr`;
|
||||||
const title = `${getTagValues("name", event.tags as string[][])} | Flockstr`;
|
const images = event.image
|
||||||
const images =
|
? [event.image, ...previousImages]
|
||||||
getTagValues("image", event.tags as string[][]) ??
|
: previousImages;
|
||||||
getTagValues("banner", event.tags as string[][]) ??
|
|
||||||
"";
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: title,
|
title: title,
|
||||||
description: event.content,
|
description: event.description,
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: title,
|
title: title,
|
||||||
description: event.content,
|
description: event.description,
|
||||||
images: images,
|
images: images,
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
title: title,
|
title: title,
|
||||||
description: event.content,
|
description: event.description,
|
||||||
images: images,
|
images: images,
|
||||||
card: "summary_large_image",
|
card: "summary_large_image",
|
||||||
},
|
},
|
||||||
|
@ -45,7 +45,7 @@ export default function Header({ event }: { event: NDKEvent }) {
|
|||||||
const { pubkey, tags } = event;
|
const { pubkey, tags } = event;
|
||||||
const { profile } = useProfile(pubkey);
|
const { profile } = useProfile(pubkey);
|
||||||
const eventReference = event.tagId();
|
const eventReference = event.tagId();
|
||||||
const title = getTagValues("title", tags) ?? "Untitled";
|
const title = getTagValues("name", tags) ?? "Untitled";
|
||||||
const image =
|
const image =
|
||||||
getTagValues("image", tags) ??
|
getTagValues("image", tags) ??
|
||||||
getTagValues("picture", tags) ??
|
getTagValues("picture", tags) ??
|
||||||
|
@ -29,7 +29,7 @@ export default function RSVPButton({ event }: RSVPButtonProps) {
|
|||||||
const { currentUser } = useCurrentUser();
|
const { currentUser } = useCurrentUser();
|
||||||
const { ndk } = useNDK();
|
const { ndk } = useNDK();
|
||||||
const eventReference = event.tagId();
|
const eventReference = event.tagId();
|
||||||
const name = getTagValues("title", event.tags);
|
const name = getTagValues("name", event.tags);
|
||||||
const tickets = getTagValues("tickets", event.tags);
|
const tickets = getTagValues("tickets", event.tags);
|
||||||
const price = getTagAllValues("price", event.tags);
|
const price = getTagAllValues("price", event.tags);
|
||||||
const priceInBTC = parseFloat(getTagValues("price", event.tags) ?? "0");
|
const priceInBTC = parseFloat(getTagValues("price", event.tags) ?? "0");
|
||||||
@ -88,14 +88,13 @@ export default function RSVPButton({ event }: RSVPButtonProps) {
|
|||||||
|
|
||||||
if (!tickets) {
|
if (!tickets) {
|
||||||
if (rsvpEvent) {
|
if (rsvpEvent) {
|
||||||
const rsvpResponse = getTagValues("status", rsvpEvent.tags);
|
const rsvpResponse = getTagValues("l", rsvpEvent.tags);
|
||||||
const rsvpResponseDeprecated = getTagValues("l", rsvpEvent.tags);
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Button disabled>
|
<Button disabled>
|
||||||
{rsvpResponse === "accepted" || rsvpResponseDeprecated === "accepted"
|
{rsvpResponse === "accepted"
|
||||||
? "Going"
|
? "Going"
|
||||||
: rsvpResponse === "tentative" || rsvpResponseDeprecated === "tentative"
|
: rsvpResponse === "tentative"
|
||||||
? "Tentative"
|
? "Tentative"
|
||||||
: "Not Going"}
|
: "Not Going"}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -1,29 +1,18 @@
|
|||||||
import type { Metadata, ResolvingMetadata } from "next";
|
import type { Metadata, ResolvingMetadata } from "next";
|
||||||
import { getEvent } from "@/lib/server-actions/meta/event";
|
import { get } from "@/lib/server-actions/events/cache";
|
||||||
import { nip19 } from "nostr-tools";
|
|
||||||
import { getTagValues } from "@/lib/nostr/utils";
|
|
||||||
|
|
||||||
export async function generateMetadata(
|
export async function generateMetadata(
|
||||||
{ params }: { params: { naddr: string } },
|
{ params }: { params: { naddr: string } },
|
||||||
parent: ResolvingMetadata,
|
parent: ResolvingMetadata,
|
||||||
): Promise<Metadata> {
|
): Promise<Metadata> {
|
||||||
const previousImages = (await parent).openGraph?.images || [];
|
|
||||||
// read route params
|
// read route params
|
||||||
const identifier = params.naddr;
|
const identifier = params.naddr;
|
||||||
const { data, type } = nip19.decode(identifier);
|
|
||||||
if (type !== "naddr") {
|
|
||||||
return {
|
|
||||||
title: "Flockstr Event",
|
|
||||||
openGraph: {
|
|
||||||
images: previousImages,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch data
|
// fetch data
|
||||||
const event = await getEvent(data.kind, data.pubkey, data.identifier);
|
const event = await get(identifier);
|
||||||
|
|
||||||
// optionally access and extend (rather than replace) parent metadata
|
// optionally access and extend (rather than replace) parent metadata
|
||||||
|
const previousImages = (await parent).openGraph?.images || [];
|
||||||
if (!event) {
|
if (!event) {
|
||||||
return {
|
return {
|
||||||
title: "Flockstr Event",
|
title: "Flockstr Event",
|
||||||
@ -32,25 +21,22 @@ export async function generateMetadata(
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
const title = `${event.name} | Flockstr`;
|
||||||
const title = `${getTagValues("title", event.tags as string[][])} | Flockstr`;
|
const images = event.image
|
||||||
const images =
|
? [event.image, ...previousImages]
|
||||||
getTagValues("image", event.tags as string[][]) ??
|
: previousImages;
|
||||||
getTagValues("banner", event.tags as string[][]) ??
|
|
||||||
"";
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: title,
|
title: title,
|
||||||
description: event.content,
|
description: event.description,
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: title,
|
title: title,
|
||||||
description: event.content,
|
description: event.description,
|
||||||
images: [images],
|
images: images,
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
title: title,
|
title: title,
|
||||||
description: event.content,
|
description: event.description,
|
||||||
images: [images],
|
images: images,
|
||||||
card: "summary_large_image",
|
card: "summary_large_image",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -44,7 +44,7 @@ export default function EventPage({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (event) {
|
if (event) {
|
||||||
const { tags, content } = event;
|
const { tags, content } = event;
|
||||||
const name = getTagValues("title", tags) ?? "Untitled";
|
const name = getTagValues("name", tags) ?? "Untitled";
|
||||||
const image =
|
const image =
|
||||||
getTagValues("image", tags) ??
|
getTagValues("image", tags) ??
|
||||||
getTagValues("picture", tags) ??
|
getTagValues("picture", tags) ??
|
||||||
|
@ -57,7 +57,7 @@ export default function CreateCalendarEventModal() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
setError("Please add a name");
|
setError("Please add a title");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
@ -120,7 +120,7 @@ export default function CreateCalendarEventModal({
|
|||||||
const random = randomId();
|
const random = randomId();
|
||||||
const tags: string[][] = [
|
const tags: string[][] = [
|
||||||
["d", random],
|
["d", random],
|
||||||
["title", title],
|
["name", title],
|
||||||
["description", description],
|
["description", description],
|
||||||
["start", toUnix(convertToTimezone(startDate, timezone)).toString()],
|
["start", toUnix(convertToTimezone(startDate, timezone)).toString()],
|
||||||
["end", toUnix(convertToTimezone(endDate, timezone)).toString()],
|
["end", toUnix(convertToTimezone(endDate, timezone)).toString()],
|
||||||
|
@ -41,7 +41,8 @@ export default function RSVPModal({ eventReference }: RSVPModalProps) {
|
|||||||
const tags: string[][] = [
|
const tags: string[][] = [
|
||||||
["d", random],
|
["d", random],
|
||||||
["a", eventReference],
|
["a", eventReference],
|
||||||
["status", statusMap[type]],
|
["L", "status"],
|
||||||
|
["l", statusMap[type], "status"],
|
||||||
];
|
];
|
||||||
const event = await createEvent(ndk, {
|
const event = await createEvent(ndk, {
|
||||||
content: "",
|
content: "",
|
||||||
|
@ -44,8 +44,8 @@ export default function AvatarStack({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function User({ pubkey, className }: { pubkey: string; className: string }) {
|
function User({ pubkey, className }: { pubkey: string; className: string }) {
|
||||||
const { profile, npub } = useProfile(pubkey);
|
const { profile } = useProfile(pubkey);
|
||||||
// const npub = profilenip19.npubEncode(pubkey);
|
const npub = nip19.npubEncode(pubkey);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Avatar
|
<Avatar
|
||||||
|
11
db/client.ts
11
db/client.ts
@ -1,11 +0,0 @@
|
|||||||
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;
|
|
@ -7,7 +7,7 @@ import { type NDKUserProfile } from "@nostr-dev-kit/ndk";
|
|||||||
|
|
||||||
export default function useProfile(key: string) {
|
export default function useProfile(key: string) {
|
||||||
const { ndk, getProfile } = useNDK();
|
const { ndk, getProfile } = useNDK();
|
||||||
const npub = key.length === 64 ? nip19.npubEncode(key) : key;
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ndk) return;
|
if (!ndk) return;
|
||||||
if (NOSTR_BECH32_REGEXP.test(key)) {
|
if (NOSTR_BECH32_REGEXP.test(key)) {
|
||||||
@ -20,5 +20,5 @@ export default function useProfile(key: string) {
|
|||||||
};
|
};
|
||||||
}, [key, ndk]);
|
}, [key, ndk]);
|
||||||
|
|
||||||
return { profile: getProfile(key), npub: npub };
|
return { profile: getProfile(key) };
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
"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,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "prisma generate && next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
@ -17,7 +17,6 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.0.0",
|
"@nostr-dev-kit/ndk": "^2.0.0",
|
||||||
"@nostr-dev-kit/ndk-cache-dexie": "^2.0.3",
|
"@nostr-dev-kit/ndk-cache-dexie": "^2.0.3",
|
||||||
"@nostr-dev-kit/ndk-react": "^0.1.1",
|
"@nostr-dev-kit/ndk-react": "^0.1.1",
|
||||||
"@prisma/client": "^5.7.1",
|
|
||||||
"@radix-ui/react-aspect-ratio": "^1.0.3",
|
"@radix-ui/react-aspect-ratio": "^1.0.3",
|
||||||
"@radix-ui/react-avatar": "^1.0.4",
|
"@radix-ui/react-avatar": "^1.0.4",
|
||||||
"@radix-ui/react-dialog": "^1.0.5",
|
"@radix-ui/react-dialog": "^1.0.5",
|
||||||
@ -89,7 +88,6 @@
|
|||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.0.3",
|
||||||
"prettier-plugin-tailwindcss": "^0.5.6",
|
"prettier-plugin-tailwindcss": "^0.5.6",
|
||||||
"prisma": "^5.7.1",
|
|
||||||
"tailwindcss": "^3",
|
"tailwindcss": "^3",
|
||||||
"typescript": "^5",
|
"typescript": "^5",
|
||||||
"webln": "^0.3.2"
|
"webln": "^0.3.2"
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
// 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 @db.Text
|
|
||||||
created_at Int
|
|
||||||
pubkey String
|
|
||||||
tags Json @default("[]")
|
|
||||||
sig String
|
|
||||||
d String?
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user