address
This commit is contained in:
parent
2fe390a52f
commit
31da3a0241
134
components/Address.tsx
Normal file
134
components/Address.tsx
Normal file
@ -0,0 +1,134 @@
|
||||
import Link from "next/link";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { useAtom } from "jotai";
|
||||
import { nip19 } from "nostr-tools";
|
||||
|
||||
import {
|
||||
Flex,
|
||||
Stack,
|
||||
Heading,
|
||||
Text,
|
||||
Card,
|
||||
CardHeader,
|
||||
CardBody,
|
||||
Tag,
|
||||
} from "@chakra-ui/react";
|
||||
import { useEvents } from "@emoji/nostr/hooks";
|
||||
import { relaysAtom } from "@emoji/user/state";
|
||||
import { findTag } from "@emoji/nostr/nip57";
|
||||
|
||||
function getEmoji(ev) {
|
||||
if ([1, 30_023, 30_024].includes(ev.kind)) {
|
||||
return "📝";
|
||||
}
|
||||
if (ev.kind === 30_311) {
|
||||
return "🎥";
|
||||
}
|
||||
|
||||
return "❔";
|
||||
}
|
||||
|
||||
function Preview({ naddr, ev }) {
|
||||
const title = useMemo(() => findTag(ev, "title"), [ev]);
|
||||
const description = useMemo(() => findTag(ev, "summary"), [ev]);
|
||||
const tags = useMemo(
|
||||
() => ev.tags.filter((t) => t.at(0) === "t").map((t) => t.at(1)),
|
||||
[ev]
|
||||
);
|
||||
return (
|
||||
<Link href={`https://habla.news/a/${naddr}`}>
|
||||
<Card variant="elevated">
|
||||
<CardHeader pb={0}>
|
||||
<Heading fontSize="md">
|
||||
{" "}
|
||||
{getEmoji(ev)} {title}
|
||||
</Heading>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Stack>
|
||||
{description && <Text>{description}</Text>}
|
||||
{tags.length > 0 && (
|
||||
<Flex gap={2} flexWrap="wrap" mt={4}>
|
||||
{tags.map((t) => (
|
||||
<Tag key={t}>{t}</Tag>
|
||||
))}
|
||||
</Flex>
|
||||
)}
|
||||
</Stack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
function Stream({ naddr, ev }) {
|
||||
const title = useMemo(() => findTag(ev, "title"), [ev]);
|
||||
const description = useMemo(() => findTag(ev, "summary"), [ev]);
|
||||
const tags = useMemo(
|
||||
() => ev.tags.filter((t) => t.at(0) === "t").map((t) => t.at(1)),
|
||||
[ev]
|
||||
);
|
||||
return (
|
||||
<Link href={`https://zap.stream/${naddr}`}>
|
||||
<Card variant="elevated">
|
||||
<CardHeader pb={0}>
|
||||
<Heading fontSize="md">
|
||||
{" "}
|
||||
{getEmoji(ev)} {title}
|
||||
</Heading>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Stack>
|
||||
{description && <Text>{description}</Text>}
|
||||
{tags.length > 0 && (
|
||||
<Flex gap={2} flexWrap="wrap" mt={4}>
|
||||
{tags.map((t) => (
|
||||
<Tag key={t}>{t}</Tag>
|
||||
))}
|
||||
</Flex>
|
||||
)}
|
||||
</Stack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
export function Address({ a }) {
|
||||
const [relays] = useAtom(relaysAtom);
|
||||
const [k, pubkey, d] = useMemo(() => a.split(":"), [a]);
|
||||
const naddr = useMemo(() => {
|
||||
return nip19.naddrEncode({
|
||||
kind: Number(k),
|
||||
pubkey: pubkey,
|
||||
identifier: d,
|
||||
relays,
|
||||
});
|
||||
}, [k, pubkey, d, relays]);
|
||||
const { events } = useEvents(
|
||||
[
|
||||
{
|
||||
kinds: [Number(k)],
|
||||
authors: [pubkey],
|
||||
"#d": [d],
|
||||
},
|
||||
],
|
||||
relays
|
||||
);
|
||||
const ev = events[0];
|
||||
if (!ev) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ev.kind === 30_311) {
|
||||
return <Stream naddr={naddr} ev={ev} />;
|
||||
}
|
||||
|
||||
if (ev.kind === 30_023) {
|
||||
return <Preview naddr={naddr} ev={ev} />;
|
||||
}
|
||||
|
||||
const alt = ev.tags.find((t) => t.at(0) === "alt");
|
||||
return alt ? <Text>{alt}</Text> : <Text>Unknown event kind: {ev.kind}</Text>;
|
||||
}
|
@ -63,7 +63,7 @@ export default function CreateGoal({ showPreview = true }) {
|
||||
event.tags.push(["closed_at", String(closedAt)]);
|
||||
}
|
||||
return event;
|
||||
}, [name, closedAt, amount, url]);
|
||||
}, [name, address, closedAt, amount, url]);
|
||||
|
||||
const handleNameChange = (event) => {
|
||||
setName(event.target.value);
|
||||
|
@ -26,6 +26,7 @@ import { ExternalLinkIcon } from "@chakra-ui/icons";
|
||||
|
||||
import EmojiGrid from "@emoji/components/EmojiGrid";
|
||||
import User from "@emoji/components/User";
|
||||
import { Address } from "@emoji/components/Address";
|
||||
import { GoalZaps } from "@emoji/components/GoalsZaps";
|
||||
import { useEvents } from "@emoji/nostr/hooks";
|
||||
import { pubkeyAtom, relaysAtom } from "@emoji/user/state";
|
||||
@ -161,19 +162,19 @@ export function Goal({ goal, isDetail = false, ...rest }) {
|
||||
return acc.concat([z.pubkey]);
|
||||
}, []);
|
||||
}, [zappers]);
|
||||
const link = nevent && (
|
||||
<Link href={`/e/${nevent}`}>
|
||||
<Icon as={ExternalLinkIcon} boxSize={5} color="gray.500" />
|
||||
</Link>
|
||||
);
|
||||
return (
|
||||
<Card p={0} minW="320px" sx={isExpired ? { opacity: 0.8 } : {}} {...rest}>
|
||||
<CardHeader>
|
||||
<Stack spacing={1}>
|
||||
<Flex justifyContent="space-between">
|
||||
{goal.content.length > 0 && (
|
||||
<Heading fontSize="lg">{goal.content}</Heading>
|
||||
)}
|
||||
{goal.content.length > 0 &&
|
||||
(nevent ? (
|
||||
<Link href={`/e/${nevent}`} shallow>
|
||||
<Heading fontSize="lg">{goal.content}</Heading>
|
||||
</Link>
|
||||
) : (
|
||||
<Heading fontSize="lg">{goal.content}</Heading>
|
||||
))}
|
||||
{closedAtTimestamp && !isExpired && (
|
||||
<Tag>expires {formatRemainingTime(closedAtTimestamp)}</Tag>
|
||||
)}
|
||||
@ -181,16 +182,9 @@ export function Goal({ goal, isDetail = false, ...rest }) {
|
||||
<User size="xs" fontSize="md" pubkey={goal.pubkey} />
|
||||
</Stack>
|
||||
</CardHeader>
|
||||
<CardBody
|
||||
pt={0}
|
||||
cursor={nevent ? "pointer" : "auto"}
|
||||
onClick={
|
||||
nevent
|
||||
? () => router.push(`/e/${nevent}`, undefined, { shallow: true })
|
||||
: null
|
||||
}
|
||||
>
|
||||
<CardBody pt={0} cursor={nevent ? "pointer" : "auto"}>
|
||||
<Stack gap={4} my={4}>
|
||||
{a && <Address a={a} />}
|
||||
{url && (
|
||||
<Flex align="center" gap={2}>
|
||||
<Icon as={ExternalLinkIcon} boxSize={3} color="gray.500" />
|
||||
@ -199,29 +193,31 @@ export function Goal({ goal, isDetail = false, ...rest }) {
|
||||
</a>
|
||||
</Flex>
|
||||
)}
|
||||
<Stack>
|
||||
<Flex justifyContent="space-between">
|
||||
<Text>{formatShortNumber(total)}</Text>
|
||||
<Text
|
||||
sx={
|
||||
isAchieved
|
||||
? { color: "green.500" }
|
||||
: {
|
||||
color: progress === 0 ? "gray.500" : "black",
|
||||
}
|
||||
}
|
||||
>
|
||||
{isAchieved
|
||||
? "100"
|
||||
: progress === 0
|
||||
? "0"
|
||||
: progress.toFixed(2)}
|
||||
%
|
||||
</Text>
|
||||
<Text>{formatShortNumber(amount)}</Text>
|
||||
</Flex>
|
||||
<Progress value={progress} colorScheme="green" />
|
||||
</Stack>
|
||||
<Link href={`/e/${nevent}`}>
|
||||
<Stack>
|
||||
<Flex justifyContent="space-between">
|
||||
<Text>{formatShortNumber(total)}</Text>
|
||||
<Text
|
||||
sx={
|
||||
isAchieved
|
||||
? { color: "green.500" }
|
||||
: {
|
||||
color: progress === 0 ? "gray.500" : "black",
|
||||
}
|
||||
}
|
||||
>
|
||||
{isAchieved
|
||||
? "100"
|
||||
: progress === 0
|
||||
? "0"
|
||||
: progress.toFixed(2)}
|
||||
%
|
||||
</Text>
|
||||
<Text>{formatShortNumber(amount)}</Text>
|
||||
</Flex>
|
||||
<Progress value={progress} colorScheme="green" />
|
||||
</Stack>
|
||||
</Link>
|
||||
</Stack>
|
||||
{isDetail && (
|
||||
<>
|
||||
|
@ -1,20 +1,39 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { Flex, Stack, Heading, Text } from "@chakra-ui/react";
|
||||
import { useAtom } from "jotai";
|
||||
|
||||
import { GOAL } from "@emoji/nostr/const";
|
||||
import { Goals } from "@emoji/components/Goals";
|
||||
import { Goal, Goals } from "@emoji/components/Goals";
|
||||
import { pool, useEvents } from "@emoji/nostr/hooks";
|
||||
import { relaysAtom } from "@emoji/user/state";
|
||||
|
||||
export default function HomeContent() {
|
||||
const [relays] = useAtom(relaysAtom);
|
||||
const { events, eose } = useEvents([{ kinds: [GOAL] }], relays);
|
||||
const { events: example } = useEvents(
|
||||
[
|
||||
{
|
||||
kinds: [GOAL],
|
||||
authors: [
|
||||
"55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185",
|
||||
],
|
||||
limit: 1,
|
||||
},
|
||||
],
|
||||
relays
|
||||
);
|
||||
const ev = example[0];
|
||||
const { events, eose } = useEvents([{ kinds: [GOAL], limit: 3 }], relays);
|
||||
return (
|
||||
<Flex alignItems="center" justifyContent="center">
|
||||
<Goals goals={events} />
|
||||
<Stack>
|
||||
<Heading>Zapgoals</Heading>
|
||||
<Text>asfdadsffads fsda</Text>
|
||||
{ev && <Goal goal={ev} />}
|
||||
<Text>asfdadsffads fsda</Text>
|
||||
{eose && <Goals goals={events} />}
|
||||
</Stack>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user