better content fetching
This commit is contained in:
parent
3a91d248e9
commit
5868f19db3
@ -8,16 +8,19 @@ import {
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { RiArrowRightLine } from "react-icons/ri";
|
import { RiArrowRightLine } from "react-icons/ri";
|
||||||
import KindCard from "@/components/KindCard";
|
import KindCard from "@/components/KindCard";
|
||||||
import { DUMMY_30023 } from "@/constants";
|
import { NOTABLE_ACCOUNTS } from "@/constants";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import useEvents from "@/lib/hooks/useEvents";
|
import useEvents from "@/lib/hooks/useEvents";
|
||||||
import { Event } from "nostr-tools";
|
import { Event } from "nostr-tools";
|
||||||
import KindLoading from "@/components/KindCard/loading";
|
import KindLoading from "@/components/KindCard/loading";
|
||||||
|
import { nip19 } from "nostr-tools";
|
||||||
|
import { getTagValues } from "@/lib/nostr/utils";
|
||||||
|
|
||||||
export default function LongFormContentSection() {
|
export default function LongFormContentSection() {
|
||||||
const { events } = useEvents({
|
const { events } = useEvents({
|
||||||
filter: {
|
filter: {
|
||||||
kinds: [30023],
|
kinds: [30023],
|
||||||
|
authors: NOTABLE_ACCOUNTS.map((a) => nip19.decode(a).data.toString()),
|
||||||
limit: 10,
|
limit: 10,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -31,14 +34,19 @@ export default function LongFormContentSection() {
|
|||||||
</SectionHeader>
|
</SectionHeader>
|
||||||
<SectionContent className="sm:lg-feed-cols relative mx-auto flex flex-col gap-4">
|
<SectionContent className="sm:lg-feed-cols relative mx-auto flex flex-col gap-4">
|
||||||
{events?.length ? (
|
{events?.length ? (
|
||||||
events.map((e) => {
|
events
|
||||||
const event = e.rawEvent() as Event;
|
.filter((e) => !!getTagValues("summary", e.tags))
|
||||||
return (
|
.slice(0, 6)
|
||||||
<Link key={e.id} href={`/article/${e.tagId}`}>
|
.map((e, idx) => {
|
||||||
<KindCard {...event} />
|
if (idx > 6) return null;
|
||||||
</Link>
|
const event = e.rawEvent() as Event;
|
||||||
);
|
|
||||||
})
|
return (
|
||||||
|
<Link key={e.id} href={`/article/${e.encode()}`}>
|
||||||
|
<KindCard {...event} />
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<KindLoading />
|
<KindLoading />
|
||||||
|
@ -33,7 +33,6 @@ export default function ArticlePage({
|
|||||||
return (
|
return (
|
||||||
<div className="center pt-20 text-primary">
|
<div className="center pt-20 text-primary">
|
||||||
<Spinner />
|
<Spinner />
|
||||||
{events.length}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,14 @@ import { nip19 } from "nostr-tools";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export default function Kind1(props: Event) {
|
export default function Kind1(props: Event) {
|
||||||
const { content, pubkey, tags } = props;
|
const { content, pubkey, tags, created_at: createdAt } = props;
|
||||||
const r = getTagsValues("r", tags).filter(Boolean);
|
const r = getTagsValues("r", tags).filter(Boolean);
|
||||||
const npub = nip19.npubEncode(pubkey);
|
const npub = nip19.npubEncode(pubkey);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container
|
||||||
pubkey={pubkey}
|
pubkey={pubkey}
|
||||||
|
createdAt={createdAt}
|
||||||
actionOptions={[
|
actionOptions={[
|
||||||
{
|
{
|
||||||
label: "View profile",
|
label: "View profile",
|
||||||
|
@ -3,9 +3,14 @@ import Container from "./components/Container";
|
|||||||
import { CardTitle, CardDescription } from "@/components/ui/card";
|
import { CardTitle, CardDescription } from "@/components/ui/card";
|
||||||
import { getTagValues, getTagsValues } from "@/lib/nostr/utils";
|
import { getTagValues, getTagsValues } from "@/lib/nostr/utils";
|
||||||
import { type Event } from "nostr-tools";
|
import { type Event } from "nostr-tools";
|
||||||
|
import { nip19 } from "nostr-tools";
|
||||||
import { removeDuplicates } from "@/lib/utils";
|
import { removeDuplicates } from "@/lib/utils";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { copyText } from "@/lib/utils";
|
||||||
|
|
||||||
export default function Kind30023({ content, pubkey, tags }: Event) {
|
export default function Kind30023(props: Event) {
|
||||||
|
const { content, pubkey, tags, created_at: createdAt } = props;
|
||||||
|
const npub = nip19.npubEncode(pubkey);
|
||||||
const title = getTagValues("title", tags);
|
const title = getTagValues("title", tags);
|
||||||
const summary = getTagValues("summary", tags);
|
const summary = getTagValues("summary", tags);
|
||||||
const contentTags = removeDuplicates(getTagsValues("t", tags)).filter(
|
const contentTags = removeDuplicates(getTagsValues("t", tags)).filter(
|
||||||
@ -13,7 +18,26 @@ export default function Kind30023({ content, pubkey, tags }: Event) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container pubkey={pubkey} contentTags={contentTags}>
|
<Container
|
||||||
|
pubkey={pubkey}
|
||||||
|
contentTags={contentTags}
|
||||||
|
createdAt={createdAt}
|
||||||
|
actionOptions={[
|
||||||
|
{
|
||||||
|
label: "View profile",
|
||||||
|
href: `/${npub}`,
|
||||||
|
type: "link",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Copy raw data",
|
||||||
|
type: "button",
|
||||||
|
onClick: () => {
|
||||||
|
void copyText(JSON.stringify(props));
|
||||||
|
toast.success("Copied Text!");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
<CardTitle className="mb-1.5 line-clamp-2 text-lg font-semibold leading-6">
|
<CardTitle className="mb-1.5 line-clamp-2 text-lg font-semibold leading-6">
|
||||||
{title}
|
{title}
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
@ -6,7 +6,7 @@ import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
|||||||
import { formatDate } from "@/lib/utils/dates";
|
import { formatDate } from "@/lib/utils/dates";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
import ProfileHeader from "./ProfileHeader";
|
import ProfileHeader, { LoadingProfileHeader } from "./ProfileHeader";
|
||||||
import Actions from "./Actions";
|
import Actions from "./Actions";
|
||||||
import Tags from "./Tags";
|
import Tags from "./Tags";
|
||||||
import DropDownMenu from "@/components/DropDownMenu";
|
import DropDownMenu from "@/components/DropDownMenu";
|
||||||
@ -24,14 +24,16 @@ type Option = {
|
|||||||
} & (OptionLink | OptionButton);
|
} & (OptionLink | OptionButton);
|
||||||
|
|
||||||
type CreatorCardProps = {
|
type CreatorCardProps = {
|
||||||
pubkey: string;
|
pubkey?: string;
|
||||||
contentTags?: string[];
|
contentTags?: string[];
|
||||||
|
createdAt?: number;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
actionOptions?: Option[];
|
actionOptions?: Option[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Container({
|
export default function Container({
|
||||||
children,
|
children,
|
||||||
|
createdAt,
|
||||||
contentTags,
|
contentTags,
|
||||||
pubkey,
|
pubkey,
|
||||||
actionOptions = [],
|
actionOptions = [],
|
||||||
@ -39,9 +41,10 @@ export default function Container({
|
|||||||
return (
|
return (
|
||||||
<Card className="relative flex h-full flex-col overflow-hidden">
|
<Card className="relative flex h-full flex-col overflow-hidden">
|
||||||
<CardHeader className="flex flex-row items-center justify-between space-y-0 p-4 pb-4">
|
<CardHeader className="flex flex-row items-center justify-between space-y-0 p-4 pb-4">
|
||||||
<ProfileHeader pubkey={pubkey} />
|
{pubkey ? <ProfileHeader pubkey={pubkey} /> : <LoadingProfileHeader />}
|
||||||
|
|
||||||
<div className="-mr-1 flex items-center gap-x-1.5 text-xs text-muted-foreground">
|
<div className="-mr-1 flex items-center gap-x-1.5 text-xs text-muted-foreground">
|
||||||
{formatDate(new Date("10-5-23"), "MMM Do")}
|
{!!createdAt && formatDate(new Date(createdAt * 1000), "MMM Do")}
|
||||||
<DropDownMenu options={actionOptions}>
|
<DropDownMenu options={actionOptions}>
|
||||||
<Button
|
<Button
|
||||||
size={"sm"}
|
size={"sm"}
|
||||||
|
@ -4,6 +4,7 @@ import Link from "next/link";
|
|||||||
import useProfile from "@/lib/hooks/useProfile";
|
import useProfile from "@/lib/hooks/useProfile";
|
||||||
import { nip19 } from "nostr-tools";
|
import { nip19 } from "nostr-tools";
|
||||||
import { getTwoLetters, getNameToShow } from "@/lib/utils";
|
import { getTwoLetters, getNameToShow } from "@/lib/utils";
|
||||||
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
|
|
||||||
type ProfileHeaderProps = {
|
type ProfileHeaderProps = {
|
||||||
pubkey: string;
|
pubkey: string;
|
||||||
@ -50,3 +51,15 @@ export default function ProfileHeader({ pubkey }: ProfileHeaderProps) {
|
|||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function LoadingProfileHeader() {
|
||||||
|
return (
|
||||||
|
<div className="center group gap-x-3">
|
||||||
|
<Avatar className="center h-8 w-8 overflow-hidden rounded-sm bg-muted"></Avatar>
|
||||||
|
<div className="space-y-1">
|
||||||
|
<Skeleton className="h-2.5 w-[70px] bg-muted" />
|
||||||
|
<Skeleton className="h-2.5 w-[100px] bg-muted" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -1,10 +1,34 @@
|
|||||||
import Container from "./components/Container";
|
import Container from "./components/Container";
|
||||||
import { CardTitle, CardDescription } from "@/components/ui/card";
|
import { CardTitle, CardDescription } from "@/components/ui/card";
|
||||||
import { type Event } from "nostr-tools";
|
import { type Event } from "nostr-tools";
|
||||||
|
import { nip19 } from "nostr-tools";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { copyText } from "@/lib/utils";
|
||||||
|
|
||||||
|
export default function KindDefault(props: Event) {
|
||||||
|
const { pubkey, created_at: createdAt } = props;
|
||||||
|
const npub = nip19.npubEncode(pubkey);
|
||||||
|
|
||||||
export default function KindDefault({ pubkey }: Event) {
|
|
||||||
return (
|
return (
|
||||||
<Container pubkey={pubkey}>
|
<Container
|
||||||
|
pubkey={pubkey}
|
||||||
|
createdAt={createdAt}
|
||||||
|
actionOptions={[
|
||||||
|
{
|
||||||
|
label: "View profile",
|
||||||
|
href: `/${npub}`,
|
||||||
|
type: "link",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Copy raw data",
|
||||||
|
type: "button",
|
||||||
|
onClick: () => {
|
||||||
|
void copyText(JSON.stringify(props));
|
||||||
|
toast.success("Copied Text!");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
<CardTitle className="mb-1.5 line-clamp-2 text-lg font-semibold">
|
<CardTitle className="mb-1.5 line-clamp-2 text-lg font-semibold">
|
||||||
The start of the Nostr revolution
|
The start of the Nostr revolution
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
@ -5,11 +5,7 @@ import { Skeleton } from "@/components/ui/skeleton";
|
|||||||
|
|
||||||
export default function KindLoading() {
|
export default function KindLoading() {
|
||||||
return (
|
return (
|
||||||
<Container
|
<Container>
|
||||||
pubkey={
|
|
||||||
"f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca"
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<div className="space-y-2 text-muted-foreground">
|
<div className="space-y-2 text-muted-foreground">
|
||||||
<Skeleton className="mb-2 h-4 w-1/3 bg-muted" />
|
<Skeleton className="mb-2 h-4 w-1/3 bg-muted" />
|
||||||
<Skeleton className="h-4 w-1/2 bg-muted" />
|
<Skeleton className="h-4 w-1/2 bg-muted" />
|
||||||
|
@ -44,8 +44,8 @@ export default function VideoCard({ className, card }: VideoCardProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="-mt-1 flex gap-2 overflow-x-scroll">
|
<div className="-mt-1 flex flex-wrap gap-2 overflow-x-hidden">
|
||||||
{card.tags.map((tag) => (
|
{card.tags.slice(0, 4).map((tag) => (
|
||||||
<Badge key={tag}>{tag}</Badge>
|
<Badge key={tag}>{tag}</Badge>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,6 +7,33 @@ export const EXPLORE_CREATORS = [
|
|||||||
"npub1dc9p7jzjhj86g2uqgltq4qvnpkyfqn9r72kdlddcgyat3j05gnjsgjc8rz",
|
"npub1dc9p7jzjhj86g2uqgltq4qvnpkyfqn9r72kdlddcgyat3j05gnjsgjc8rz",
|
||||||
"npub1qny3tkh0acurzla8x3zy4nhrjz5zd8l9sy9jys09umwng00manysew95gx",
|
"npub1qny3tkh0acurzla8x3zy4nhrjz5zd8l9sy9jys09umwng00manysew95gx",
|
||||||
];
|
];
|
||||||
|
export const NOTABLE_ACCOUNTS = [
|
||||||
|
"npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s",
|
||||||
|
"npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft",
|
||||||
|
"npub1u6qhg5ucu3xza4nlz94q90y720tr6l09avnq8y3yfp5qrv9v8sus3tnd7t",
|
||||||
|
"npub1sg6plzptd64u62a878hep2kev88swjh3tw00gjsfl8f237lmu63q0uf63m",
|
||||||
|
"npub19mduaf5569jx9xz555jcx3v06mvktvtpu0zgk47n4lcpjsz43zzqhj6vzk",
|
||||||
|
"npub1dc9p7jzjhj86g2uqgltq4qvnpkyfqn9r72kdlddcgyat3j05gnjsgjc8rz",
|
||||||
|
"npub1qny3tkh0acurzla8x3zy4nhrjz5zd8l9sy9jys09umwng00manysew95gx",
|
||||||
|
"npub1hs55msz0awmpqt6e6t0zfn0sncp4quf5q0lxlkgrw6lw9479fmlsj2thdl",
|
||||||
|
"npub1dergggklka99wwrs92yz8wdjs952h2ux2ha2ed598ngwu9w7a6fsh9xzpc",
|
||||||
|
"npub1a2cww4kn9wqte4ry70vyfwqyqvpswksna27rtxd8vty6c74era8sdcw83a",
|
||||||
|
"npub1r0rs5q2gk0e3dk3nlc7gnu378ec6cnlenqp8a3cjhyzu6f8k5sgs4sq9ac",
|
||||||
|
"npub12rzunrxvx89f78h4df284lzvkjqetljkq0200p62ygwmjevx0j8qhehrv9",
|
||||||
|
"npub1s05p3ha7en49dv8429tkk07nnfa9pcwczkf5x5qrdraqshxdje9sq6eyhe",
|
||||||
|
"npub1a3hrd4wfawr578d5y5l0qgmh7lx8q6tumfq0h7eymmttt52veexqkcfg37",
|
||||||
|
"npub1rzg96zjavgatsx5ch2vvtq4atatly5rvdwqgjp0utxw45zeznvyqfdkxve",
|
||||||
|
"npub14j7wc366rf8efqvnnm8m68pazy04kkj8fgu6uqumh3eqlhfst0kqrngtpf",
|
||||||
|
"npub17plqkxhsv66g8quxxc9p5t9mxazzn20m426exqnl8lxnh5a4cdns7jezx0",
|
||||||
|
"npub1zuuajd7u3sx8xu92yav9jwxpr839cs0kc3q6t56vd5u9q033xmhsk6c2uc",
|
||||||
|
"npub1cj8znuztfqkvq89pl8hceph0svvvqk0qay6nydgk9uyq7fhpfsgsqwrz4u",
|
||||||
|
"npub1h50pnxqw9jg7dhr906fvy4mze2yzawf895jhnc3p7qmljdugm6gsrurqev",
|
||||||
|
"npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6",
|
||||||
|
"npub1jt0x3vsnqtazzda3ewa8ykdch2t8k566qhrd9vyy0k0ntleu744q8h6q3n",
|
||||||
|
"npub1csamkk8zu67zl9z4wkp90a462v53q775aqn5q6xzjdkxnkvcpd7srtz4x9",
|
||||||
|
"npub1ejxswthae3nkljavznmv66p9ahp4wmj4adux525htmsrff4qym9sz2t3tv",
|
||||||
|
"npub107jk7htfv243u0x5ynn43scq9wrxtaasmrwwa8lfu2ydwag6cx2quqncxg",
|
||||||
|
];
|
||||||
|
|
||||||
export const BANNER =
|
export const BANNER =
|
||||||
"https://o-0-o-image-storage.s3.amazonaws.com/poker-min_1_2_20.png";
|
"https://o-0-o-image-storage.s3.amazonaws.com/poker-min_1_2_20.png";
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
export * from "./relays";
|
export * from "./relays";
|
||||||
export * from "./dummy";
|
export * from "./dummy";
|
||||||
|
export * from "./app";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user