This commit is contained in:
zmeyer44 2023-10-16 00:28:09 -04:00
parent 5a3003abe5
commit 3a91d248e9
15 changed files with 173 additions and 101 deletions

View File

@ -42,9 +42,7 @@ export default function ProfilePage({
{!!profile?.banner && (
<Image
className="absolute inset-0 h-full w-full object-cover align-middle"
src={
"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,quality=75,width=1250,height=357.14285714285717/calendar-cover-images/4m/c50dff9c-12e1-4b8a-ae95-68a36364b760"
}
src={profile.banner}
width={400}
height={100}
alt="banner"
@ -58,9 +56,7 @@ export default function ProfilePage({
<div className="z-1 ml-[calc(-1_*_3px)] overflow-hidden rounded-[0.5rem] bg-background p-[3px] sm:ml-[calc(-1_*_4px)] sm:p-[4px] lg:ml-[calc(-1_*_6px)] lg:rounded-[1rem] lg:p-[6px]">
{profile?.image ? (
<Image
src={
"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=96,height=96/calendars/hw/70772773-6d97-4fbb-a076-fc4dee603080"
}
src={profile.image}
className="aspect-square w-[4rem] overflow-hidden rounded-[calc(0.5rem_-_3px)] object-cover object-center sm:w-[4.5rem] sm:rounded-[calc(0.5rem_-_4px)] md:w-[5rem] lg:w-[6rem] lg:rounded-[calc(1rem_-_6px)]"
unoptimized
alt="profile picture"

View File

@ -102,6 +102,7 @@ function Creator({ npub }: { npub: string }) {
"",
summary:
getTagValues("summary", e.tags) ?? getTagValues("r", e.tags) ?? e.content,
href: `/article/${e.encode()}`,
}));
return (

View File

@ -12,6 +12,8 @@ import { DUMMY_30023 } from "@/constants";
import Link from "next/link";
import useEvents from "@/lib/hooks/useEvents";
import { Event } from "nostr-tools";
import KindLoading from "@/components/KindCard/loading";
export default function LongFormContentSection() {
const { events } = useEvents({
filter: {
@ -28,14 +30,23 @@ export default function LongFormContentSection() {
</Button>
</SectionHeader>
<SectionContent className="sm:lg-feed-cols relative mx-auto flex flex-col gap-4">
{events.map((e) => {
const event = e.rawEvent() as Event;
return (
<Link key={e.id} href={`/article/${e.tagId}`}>
<KindCard {...event} />
</Link>
);
})}
{events?.length ? (
events.map((e) => {
const event = e.rawEvent() as Event;
return (
<Link key={e.id} href={`/article/${e.tagId}`}>
<KindCard {...event} />
</Link>
);
})
) : (
<>
<KindLoading />
<KindLoading />
<KindLoading />
<KindLoading />
</>
)}
</SectionContent>
</Section>
);

View File

@ -1,12 +0,0 @@
"use client";
import Article from "@/containers/Article";
export default function ArticlePage({
params: { eventId },
}: {
params: {
eventId: string;
};
}) {
return <Article />;
}

View File

@ -0,0 +1,39 @@
"use client";
import { useEffect } from "react";
import Article from "@/containers/Article";
import { useNDK } from "@nostr-dev-kit/ndk-react";
import { nip19 } from "nostr-tools";
import Spinner from "@/components/spinner";
import useEvents from "@/lib/hooks/useEvents";
export default function ArticlePage({
params: { naddr },
}: {
params: {
naddr: string;
};
}) {
const { ndk } = useNDK();
const { data, type } = nip19.decode(naddr);
const { events } = useEvents({
filter:
type === "naddr"
? {
kinds: [data.kind],
authors: [data.pubkey],
["#d"]: [data.identifier],
limit: 1,
}
: {},
});
if (events?.[0]) {
return <Article event={events[0]} />;
}
return (
<div className="center pt-20 text-primary">
<Spinner />
{events.length}
</div>
);
}

View File

@ -19,6 +19,7 @@ type CreatorCardProps = {
id: string;
title: string;
summary: string;
href: string;
}[];
};
@ -39,7 +40,11 @@ export default function CreatorCard({
<div className="absolute inset-0 bg-background/60 backdrop-blur-md transition-all">
<div className="group relative flex h-full w-full flex-col items-center justify-end transition-all">
<CardHeader className="absolute inset-x-0 top-[59%] transform pt-4 text-center transition-all duration-300 group-hover:top-[8px] group-hover:ml-[75px] group-hover:text-left">
<CardTitle>{getNameToShow({ profile, npub })}</CardTitle>
<Link href={`/${npub}`}>
<CardTitle className="hover:underline">
{getNameToShow({ profile, npub })}
</CardTitle>
</Link>
<CardDescription className="line-clamp-3 group-hover:text-xs">
{profile?.about}
</CardDescription>
@ -65,7 +70,7 @@ export default function CreatorCard({
{recentWork.map((item) => (
<li key={item.id} className="w-full overflow-hidden">
<Link
href={`/${item.id}`}
href={item.href}
className="flex max-w-full items-center justify-between overflow-hidden py-1.5 pl-4 pr-2 transition-colors hover:bg-muted hover:text-primary"
>
<div className="shrink overflow-x-hidden">

View File

@ -14,7 +14,7 @@ export default function Kind30023({ content, pubkey, tags }: Event) {
return (
<Container pubkey={pubkey} contentTags={contentTags}>
<CardTitle className="mb-1.5 line-clamp-2 text-lg font-semibold">
<CardTitle className="mb-1.5 line-clamp-2 text-lg font-semibold leading-6">
{title}
</CardTitle>
<CardDescription className="line-clamp-4 text-sm">

View File

@ -37,7 +37,7 @@ export default function Container({
actionOptions = [],
}: CreatorCardProps) {
return (
<Card className="relative 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">
<ProfileHeader pubkey={pubkey} />
<div className="-mr-1 flex items-center gap-x-1.5 text-xs text-muted-foreground">
@ -53,14 +53,16 @@ export default function Container({
</DropDownMenu>
</div>
</CardHeader>
<CardContent className="px-4 pb-3">
<CardContent className="flex grow flex-col px-4 pb-3">
{children}
{!!contentTags?.length && (
<div className="-mb-2 mt-1 max-h-[52px] overflow-hidden">
<Tags tags={contentTags} />
</div>
)}
<Actions />
<div className="mt-auto">
{!!contentTags?.length && (
<div className="-mb-1 mt-1 max-h-[52px] overflow-hidden">
<Tags tags={contentTags} />
</div>
)}
<Actions />
</div>
</CardContent>
</Card>
);

View File

@ -19,12 +19,34 @@ export default function ProfileHeader({ pubkey }: ProfileHeaderProps) {
{getTwoLetters({ npub, profile })}
</AvatarFallback>
</Avatar>
<div className="center 5 gap-1">
<span className="text-xs uppercase text-muted-foreground group-hover:underline">
{getNameToShow({ npub, profile })}
</span>
{!!profile?.nip05 && <HiCheckBadge className="h-4 w-4 text-primary" />}
</div>
{profile?.displayName || profile?.name ? (
<div className="flex flex-col gap-0">
<div className="flex items-center gap-1">
<span className="text-sm font-medium text-foreground group-hover:underline">
{getNameToShow({ npub, profile })}
</span>
{!!profile?.nip05 && (
<HiCheckBadge className="h-4 w-4 text-primary" />
)}
</div>
<div className="flex items-center gap-1">
{!!profile.nip05 && (
<span className="text-[11px] text-muted-foreground">
{profile.nip05}
</span>
)}
</div>
</div>
) : (
<div className="flex items-center gap-1">
<span className="text-sm uppercase text-foreground group-hover:underline">
{getNameToShow({ npub, profile })}
</span>
{!!profile?.nip05 && (
<HiCheckBadge className="h-4 w-4 text-primary" />
)}
</div>
)}
</Link>
);
}

View File

@ -0,0 +1,21 @@
import Container from "./components/Container";
import { CardTitle, CardDescription } from "@/components/ui/card";
import { type Event } from "nostr-tools";
import { Skeleton } from "@/components/ui/skeleton";
export default function KindLoading() {
return (
<Container
pubkey={
"f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca"
}
>
<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" />
<Skeleton className="h-4 w-2/5 bg-muted" />
<Skeleton className="h-4 w-4/5 bg-muted" />
</div>
</Container>
);
}

View File

@ -12,7 +12,6 @@ type MarkdoneProps = {
};
export default function Markdown({ content }: MarkdoneProps) {
const { resolvedTheme } = useTheme();
// const [blocks, setBlocks] = useState<Block[]>();
const [loading, setLoading] = useState(true);
const editor: BlockNoteEditor = useBlockNote({
@ -22,12 +21,10 @@ export default function Markdown({ content }: MarkdoneProps) {
useEffect(() => {
if (editor) {
if (content) {
console.log("initial md", content);
// Whenever the current Markdown content changes, converts it to an array
// of Block objects and replaces the editor's content with them.
const getBlocks = async () => {
const blocks: Block[] = await editor.markdownToBlocks(content);
console.log("Blocks", blocks);
editor.replaceBlocks(editor.topLevelBlocks, blocks);
setLoading(false);
};
@ -41,7 +38,7 @@ export default function Markdown({ content }: MarkdoneProps) {
if (loading) {
return (
<div className="">
<div className="center py-20 text-primary">
<Spinner />
</div>
);

View File

@ -1,11 +1,11 @@
export const EXPLORE_CREATORS = [
"npub1xtscya34g58tk0z605fvr788k263gsu6cy9x0mhnm87echrgufzsevkk5s",
"npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft",
"npub1u6qhg5ucu3xza4nlz94q90y720tr6l09avnq8y3yfp5qrv9v8sus3tnd7t",
"npub1sg6plzptd64u62a878hep2kev88swjh3tw00gjsfl8f237lmu63q0uf63m",
"npub19mduaf5569jx9xz555jcx3v06mvktvtpu0zgk47n4lcpjsz43zzqhj6vzk",
"npub1dc9p7jzjhj86g2uqgltq4qvnpkyfqn9r72kdlddcgyat3j05gnjsgjc8rz",
"npub1qny3tkh0acurzla8x3zy4nhrjz5zd8l9sy9jys09umwng00manysew95gx",
"npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn66ukqp3afqutajft",
];
export const BANNER =

View File

@ -1,7 +1,7 @@
export const RELAYS = [
"wss://nostr.pub.wellorder.net",
"wss://nostr.drss.io",
"wss://nostr.swiss-enigma.ch",
"wss://relay.damus.io",
"wss://nostr.mom",
"wss://nos.lol",
"wss://nostr.wine",
"wss://relay.damus.io",
"wss://nostr.swiss-enigma.ch",
];

View File

@ -7,56 +7,46 @@ import { Avatar, AvatarImage, AvatarFallback } from "@radix-ui/react-avatar";
import { useRouter } from "next/navigation";
import { formatDate } from "@/lib/utils/dates";
import Actions from "./Actions";
import Logo from "@/assets/Logo";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { getTagAllValues, getTagValues } from "@/lib/nostr/utils";
import useProfile from "@/lib/hooks/useProfile";
import { nip19 } from "nostr-tools";
import { getNameToShow, getTwoLetters } from "@/lib/utils";
export default function ArticlePage() {
type ArticleProps = {
event: NDKEvent;
};
export default function ArticlePage({ event }: ArticleProps) {
const Viewer = useMemo(
() => dynamic(() => import("@/components/LongForm"), { ssr: false }),
[],
);
console.log(event);
const router = useRouter();
const markdown = `Do you have any thoughts of YakiHonne? Share it and earn SATs!
Comment2Earn | Earn SATs by sharing your comments on YakiHonne
Earn SATs by sharing your comments on YakiHonne.
2nd - 15th Oct
### Follow Us
- Nostr: npub1yzvxlwp7wawed5vgefwfmugvumtp8c8t0etk3g8sky4n0ndvyxesnxrf8q
- Twitter: https://twitter.com/YakiHonne
- Facebook Profile: https://www.facebook.com/profi…1715056704
- Facebook Page: https://www.facebook.com/profi…2076811240
- Facebook Group: https://www.facebook.com/group…4539860115
- Youtube: https://www.youtube.com/channe…f4EyFJ7BlA
### How to Get SATs:
1. Post your thoughts about YakiHonne on at least one of the above social media, and be sure to @ YakiHonne.
2. Follow YakiHonne on at least one of the social media above.
3. Back to this article, leave your social account which followed YakiHonne in the Comments.
4. Be zapped with SATs.
### What You Will Get:
1. 500 SATs, if you finished all steps.
2. 1000 SATs, if you finished all steps and`;
const markdown = event.content;
const pubkey = event.pubkey;
const createdAt = getTagValues("published_at", event.tags)
? parseInt(getTagValues("published_at", event.tags) as string)
: event.created_at;
const { profile } = useProfile(pubkey);
const npub = nip19.npubEncode(pubkey);
const title = getTagValues("title", event.tags);
const summary = getTagValues("summary", event.tags);
const tags = getTagAllValues("t", event.tags);
return (
<div className="relative @container">
<div className="sticky inset-x-0 top-0 z-10 flex items-center justify-between border-b bg-background pb-4 pt-4">
<div className="center gap-x-3">
<Avatar className="center h-8 w-8 overflow-hidden rounded-sm bg-muted">
<AvatarImage
src={
"https://images.unsplash.com/photo-1566492031773-4f4e44671857?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=4&w=256&h=256&q=60"
}
alt="user"
/>
<AvatarFallback className="text-xs">SC</AvatarFallback>
<AvatarImage src={profile?.image} alt="user" />
<AvatarFallback className="text-xs">
{getTwoLetters({ profile, npub })}
</AvatarFallback>
</Avatar>
<span className="text-xs uppercase text-muted-foreground">
Derek Seivers
{getNameToShow({ profile, npub })}
</span>
</div>
<Button
@ -79,27 +69,27 @@ export default function ArticlePage() {
<article className="prose dark:prose-invert prose-zinc relative mx-auto max-w-3xl pt-7">
<div className="">
<div className="flex items-center justify-between gap-1 lg:mb-2">
<Button variant={"link"} className="px-0">
Balaji's News Letter
</Button>
{tags.map((t) => (
<Button variant={"link"} className="px-0">
{t}
</Button>
))}
<div className="center text-xs text-muted-foreground/50">
<span className="mr-2.5">
{formatDate(new Date("10-2-22"), "MMMM Do, YYYY")}
</span>
{!!createdAt && (
<span className="mr-2.5">
{formatDate(new Date(createdAt * 1000), "MMMM Do, YYYY")}
</span>
)}
<span className="h-3 w-[1px] rounded-full bg-muted-foreground/50"></span>
</div>
</div>
<h1 className="">
This is the large title for the article. It's time to take over.
</h1>
<h1 className="">{title}</h1>
<div className="mb-3 flex items-center justify-end">
<Actions />
</div>
<div className="rounded-r-lg border-l-[4px] border-primary bg-muted p-4">
<p className="m-0">
Here is a short summary for the article that you are about to
start reading. Get ready to really enojy your self.
</p>
<p className="m-0">{summary} </p>
</div>
</div>
<Viewer content={markdown} />