better content fetching

This commit is contained in:
zmeyer44 2023-10-16 00:57:59 -04:00
parent 3a91d248e9
commit 5868f19db3
11 changed files with 122 additions and 26 deletions

View File

@ -8,16 +8,19 @@ import {
import { Button } from "@/components/ui/button";
import { RiArrowRightLine } from "react-icons/ri";
import KindCard from "@/components/KindCard";
import { DUMMY_30023 } from "@/constants";
import { NOTABLE_ACCOUNTS } from "@/constants";
import Link from "next/link";
import useEvents from "@/lib/hooks/useEvents";
import { Event } from "nostr-tools";
import KindLoading from "@/components/KindCard/loading";
import { nip19 } from "nostr-tools";
import { getTagValues } from "@/lib/nostr/utils";
export default function LongFormContentSection() {
const { events } = useEvents({
filter: {
kinds: [30023],
authors: NOTABLE_ACCOUNTS.map((a) => nip19.decode(a).data.toString()),
limit: 10,
},
});
@ -31,10 +34,15 @@ export default function LongFormContentSection() {
</SectionHeader>
<SectionContent className="sm:lg-feed-cols relative mx-auto flex flex-col gap-4">
{events?.length ? (
events.map((e) => {
events
.filter((e) => !!getTagValues("summary", e.tags))
.slice(0, 6)
.map((e, idx) => {
if (idx > 6) return null;
const event = e.rawEvent() as Event;
return (
<Link key={e.id} href={`/article/${e.tagId}`}>
<Link key={e.id} href={`/article/${e.encode()}`}>
<KindCard {...event} />
</Link>
);

View File

@ -33,7 +33,6 @@ export default function ArticlePage({
return (
<div className="center pt-20 text-primary">
<Spinner />
{events.length}
</div>
);
}

View File

@ -9,13 +9,14 @@ import { nip19 } from "nostr-tools";
import { toast } from "sonner";
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 npub = nip19.npubEncode(pubkey);
return (
<Container
pubkey={pubkey}
createdAt={createdAt}
actionOptions={[
{
label: "View profile",

View File

@ -3,9 +3,14 @@ import Container from "./components/Container";
import { CardTitle, CardDescription } from "@/components/ui/card";
import { getTagValues, getTagsValues } from "@/lib/nostr/utils";
import { type Event } from "nostr-tools";
import { nip19 } from "nostr-tools";
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 summary = getTagValues("summary", tags);
const contentTags = removeDuplicates(getTagsValues("t", tags)).filter(
@ -13,7 +18,26 @@ export default function Kind30023({ content, pubkey, tags }: Event) {
);
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">
{title}
</CardTitle>

View File

@ -6,7 +6,7 @@ import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { formatDate } from "@/lib/utils/dates";
import { Button } from "@/components/ui/button";
import { ReactNode } from "react";
import ProfileHeader from "./ProfileHeader";
import ProfileHeader, { LoadingProfileHeader } from "./ProfileHeader";
import Actions from "./Actions";
import Tags from "./Tags";
import DropDownMenu from "@/components/DropDownMenu";
@ -24,14 +24,16 @@ type Option = {
} & (OptionLink | OptionButton);
type CreatorCardProps = {
pubkey: string;
pubkey?: string;
contentTags?: string[];
createdAt?: number;
children: ReactNode;
actionOptions?: Option[];
};
export default function Container({
children,
createdAt,
contentTags,
pubkey,
actionOptions = [],
@ -39,9 +41,10 @@ export default function Container({
return (
<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">
<ProfileHeader pubkey={pubkey} />
{pubkey ? <ProfileHeader pubkey={pubkey} /> : <LoadingProfileHeader />}
<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}>
<Button
size={"sm"}

View File

@ -4,6 +4,7 @@ import Link from "next/link";
import useProfile from "@/lib/hooks/useProfile";
import { nip19 } from "nostr-tools";
import { getTwoLetters, getNameToShow } from "@/lib/utils";
import { Skeleton } from "@/components/ui/skeleton";
type ProfileHeaderProps = {
pubkey: string;
@ -50,3 +51,15 @@ export default function ProfileHeader({ pubkey }: ProfileHeaderProps) {
</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>
);
}

View File

@ -1,10 +1,34 @@
import Container from "./components/Container";
import { CardTitle, CardDescription } from "@/components/ui/card";
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 (
<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">
The start of the Nostr revolution
</CardTitle>

View File

@ -5,11 +5,7 @@ import { Skeleton } from "@/components/ui/skeleton";
export default function KindLoading() {
return (
<Container
pubkey={
"f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca"
}
>
<Container>
<div className="space-y-2 text-muted-foreground">
<Skeleton className="mb-2 h-4 w-1/3 bg-muted" />
<Skeleton className="h-4 w-1/2 bg-muted" />

View File

@ -44,8 +44,8 @@ export default function VideoCard({ className, card }: VideoCardProps) {
</div>
</div>
</div>
<div className="-mt-1 flex gap-2 overflow-x-scroll">
{card.tags.map((tag) => (
<div className="-mt-1 flex flex-wrap gap-2 overflow-x-hidden">
{card.tags.slice(0, 4).map((tag) => (
<Badge key={tag}>{tag}</Badge>
))}
</div>

View File

@ -7,6 +7,33 @@ export const EXPLORE_CREATORS = [
"npub1dc9p7jzjhj86g2uqgltq4qvnpkyfqn9r72kdlddcgyat3j05gnjsgjc8rz",
"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 =
"https://o-0-o-image-storage.s3.amazonaws.com/poker-min_1_2_20.png";

View File

@ -1,2 +1,3 @@
export * from "./relays";
export * from "./dummy";
export * from "./app";