+
+ Long form content
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/(app)/app/page.tsx b/app/(app)/app/page.tsx
index 3aa1ac6..22849ba 100644
--- a/app/(app)/app/page.tsx
+++ b/app/(app)/app/page.tsx
@@ -1,16 +1,10 @@
import { Button } from "@/components/ui/button";
import HorizontalCarousel from "./_sections/HorizontalCarousel";
import { RiArrowRightLine } from "react-icons/ri";
-import LongFormContentCard from "@/components/LongFormContentCard";
import BecomeACreator from "./_sections/BecomeACreator";
-import {
- Section,
- SectionHeader,
- SectionTitle,
- SectionContent,
-} from "@/containers/PageSection";
import LiveStreamingSection from "./_sections/LiveStreaming";
import FeaturedListsSection from "./_sections/FeaturedLists";
+import LongFormContentSection from "./_sections/LongFormContent";
export default function Page() {
return (
@@ -26,20 +20,7 @@ export default function Page() {
-
-
- Long form content
-
-
-
-
-
-
-
-
-
+
diff --git a/app/(app)/article/[eventId]/page.tsx b/app/(app)/article/[eventId]/page.tsx
index 2d8b268..398f4e3 100644
--- a/app/(app)/article/[eventId]/page.tsx
+++ b/app/(app)/article/[eventId]/page.tsx
@@ -1,13 +1,5 @@
"use client";
-import { useMemo } from "react";
-import dynamic from "next/dynamic";
-import { Button } from "@/components/ui/button";
-import { RiCloseFill } from "react-icons/ri";
-import { Avatar, AvatarImage, AvatarFallback } from "@radix-ui/react-avatar";
-import { useRouter } from "next/navigation";
-const Viewer = dynamic(() => import("@/components/LongForm/Viewer"), {
- ssr: false,
-});
+import Article from "@/containers/Article";
export default function ArticlePage({
params: { eventId },
@@ -16,48 +8,5 @@ export default function ArticlePage({
eventId: string;
};
}) {
- const router = useRouter();
- const markdown = `This is a test
-### test text
-
-- First
-- Second
-1 nest`;
-
- return (
-
-
-
-
-
- SC
-
-
- Derek Seivers
-
-
-
-
-
-
-
- );
+ return ;
}
diff --git a/assets/Logo/index.tsx b/assets/Logo/index.tsx
index faca468..2a2b7ad 100644
--- a/assets/Logo/index.tsx
+++ b/assets/Logo/index.tsx
@@ -6,6 +6,7 @@ const Logo = (props: SVGProps) => (
width={188.303}
height={289.598}
viewBox="54.17 96.938 188.303 289.598"
+ fill="currentColor"
{...props}
>
diff --git a/bun.lockb b/bun.lockb
index 2ee3a5c..9717de9 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/components/KindCard/1.tsx b/components/KindCard/1.tsx
new file mode 100644
index 0000000..ad8befd
--- /dev/null
+++ b/components/KindCard/1.tsx
@@ -0,0 +1,18 @@
+import Container from "./components/Container";
+import { CardTitle, CardDescription } from "@/components/ui/card";
+import { type Event } from "nostr-tools";
+
+export default function Kind1({}: Event) {
+ return (
+
+
+ The start of the Nostr revolution
+
+
+ This is the summary of this artilce. Let's hope that it is a good
+ article and that it will end up being worth reading. I don't want to
+ waste my time on some random other stuff.
+
+
+ );
+}
diff --git a/components/KindCard/30023.tsx b/components/KindCard/30023.tsx
new file mode 100644
index 0000000..993237d
--- /dev/null
+++ b/components/KindCard/30023.tsx
@@ -0,0 +1,23 @@
+"use client";
+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 { removeDuplicates } from "@/lib/utils";
+
+export default function Kind30023({ content, tags }: Event) {
+ const title = getTagValues("title", tags);
+ const summary = getTagValues("summary", tags);
+ const contentTags = removeDuplicates(getTagsValues("t", tags));
+
+ return (
+
+
+ {title}
+
+
+ {summary ?? content}
+
+
+ );
+}
diff --git a/components/KindCard/3745.tsx b/components/KindCard/3745.tsx
new file mode 100644
index 0000000..9d9e839
--- /dev/null
+++ b/components/KindCard/3745.tsx
@@ -0,0 +1,18 @@
+import Container from "./components/Container";
+import { CardTitle, CardDescription } from "@/components/ui/card";
+import { type Event } from "nostr-tools";
+
+export default function Kind3745({}: Event) {
+ return (
+
+
+ The start of the Nostr revolution
+
+
+ This is the summary of this artilce. Let's hope that it is a good
+ article and that it will end up being worth reading. I don't want to
+ waste my time on some random other stuff.
+
+
+ );
+}
diff --git a/components/KindCard/components/Actions.tsx b/components/KindCard/components/Actions.tsx
new file mode 100644
index 0000000..9cd3f22
--- /dev/null
+++ b/components/KindCard/components/Actions.tsx
@@ -0,0 +1,27 @@
+import { Button } from "@/components/ui/button";
+import {
+ HiOutlineHandThumbUp,
+ HiOutlineChatBubbleLeftEllipsis,
+} from "react-icons/hi2";
+import { HiOutlineLightningBolt } from "react-icons/hi";
+
+export default function Actions() {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/KindCard/components/Container.tsx b/components/KindCard/components/Container.tsx
new file mode 100644
index 0000000..1b91571
--- /dev/null
+++ b/components/KindCard/components/Container.tsx
@@ -0,0 +1,42 @@
+"use client";
+import Image from "next/image";
+import Link from "next/link";
+import { RiMoreFill } from "react-icons/ri";
+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 Actions from "./Actions";
+import Tags from "./Tags";
+import { type Event } from "nostr-tools";
+
+type CreatorCardProps = {
+ contentTags?: string[];
+ children: ReactNode;
+};
+
+export default function Container({ children, contentTags }: CreatorCardProps) {
+ return (
+
+
+
+
+ );
+}
diff --git a/components/KindCard/default.tsx b/components/KindCard/default.tsx
new file mode 100644
index 0000000..c53af98
--- /dev/null
+++ b/components/KindCard/default.tsx
@@ -0,0 +1,18 @@
+import Container from "./components/Container";
+import { CardTitle, CardDescription } from "@/components/ui/card";
+import { type Event } from "nostr-tools";
+
+export default function KindDefault({}: Event) {
+ return (
+
+
+ The start of the Nostr revolution
+
+
+ This is the summary of this artilce. Let's hope that it is a good
+ article and that it will end up being worth reading. I don't want to
+ waste my time on some random other stuff.
+
+
+ );
+}
diff --git a/components/KindCard/index.tsx b/components/KindCard/index.tsx
new file mode 100644
index 0000000..e19a7b2
--- /dev/null
+++ b/components/KindCard/index.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import { type ComponentType } from "react";
+import dynamic from "next/dynamic";
+import { type Event } from "nostr-tools";
+
+const KindCard1 = dynamic(() => import("./1"), {
+ ssr: false,
+});
+const KindCard3745 = dynamic(() => import("./3745"), {
+ ssr: false,
+});
+const KindCard30023 = dynamic(() => import("./30023"), {
+ ssr: false,
+});
+const KindCardDefault = dynamic(() => import("./default"), {
+ ssr: false,
+});
+
+const componentMap: Record> = {
+ 1: KindCard1,
+ 30023: KindCard30023,
+ 3745: KindCard3745,
+};
+
+type KindCardProps = Event;
+export default function KindCard(props: KindCardProps) {
+ const { kind } = props;
+ const KindCard_ = componentMap[kind] ?? KindCardDefault;
+ return ;
+}
diff --git a/components/LongForm/Editor.tsx b/components/LongForm/Editor.tsx
index 3ae37ba..2635c09 100644
--- a/components/LongForm/Editor.tsx
+++ b/components/LongForm/Editor.tsx
@@ -1,59 +1,27 @@
"use client";
-import { useEffect, useState } from "react";
+import { useState } from "react";
import { useTheme } from "next-themes";
-import { BlockNoteEditor, PartialBlock, Block } from "@blocknote/core";
+import { BlockNoteEditor, PartialBlock } from "@blocknote/core";
import { BlockNoteView, useBlockNote } from "@blocknote/react";
-import Spinner from "../spinner";
import "@blocknote/core/style.css";
interface EditorProps {
- onChange: (value: string) => void;
- initialMarkdown?: string;
editable?: boolean;
}
-const Editor = ({ onChange, initialMarkdown, editable }: EditorProps) => {
+const Editor = ({ editable }: EditorProps) => {
const { resolvedTheme } = useTheme();
- const [loading, setLoading] = useState(true);
- const [initialContent, setInitialContent] = useState();
+ const [content, setContent] = useState("");
const editor: BlockNoteEditor = useBlockNote({
editable,
- initialContent: initialContent,
onEditorContentChange: (editor) => {
- onChange(JSON.stringify(editor.topLevelBlocks, null, 2));
+ setContent(JSON.stringify(editor.topLevelBlocks, null, 2));
},
});
- useEffect(() => {
- if (editor) {
- if (!initialContent && initialMarkdown) {
- // 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(initialMarkdown);
- setInitialContent(blocks);
- editor.replaceBlocks(editor.topLevelBlocks, blocks);
- setLoading(false);
- };
- void getBlocks();
- } else if (loading) {
- setLoading(false);
- }
- }
- }, [editor]);
-
- if (loading) {
- return (
-
-
-
- );
- }
-
return (
-
+
();
+ const [loading, setLoading] = useState(true);
+
+ const editor: BlockNoteEditor = useBlockNote({
+ editable: false,
+ });
+
+ 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);
+ };
+ void getBlocks();
+ } else if (loading) {
+ console.log("TURING LOADING OFF");
+ setLoading(false);
+ }
+ }
+ }, [editor]);
+
+ if (loading) {
+ return (
+
+
+
+ );
+ }
+ return (
+
+
+
+ );
+}
diff --git a/components/LongFormContentCard/index.tsx b/components/LongFormContentCard/index.tsx
deleted file mode 100644
index 37baf35..0000000
--- a/components/LongFormContentCard/index.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-"use client";
-import Image from "next/image";
-import Link from "next/link";
-import { RiMoreFill } from "react-icons/ri";
-import { HiOutlineLightningBolt } from "react-icons/hi";
-import {
- HiOutlineHandThumbUp,
- HiOutlineChatBubbleLeftEllipsis,
- HiOutlineEllipsisHorizontal,
-} from "react-icons/hi2";
-
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
-} from "@/components/ui/card";
-import { Avatar, AvatarImage, AvatarFallback } from "@radix-ui/react-avatar";
-import { formatDate } from "@/lib/utils/dates";
-import { Button } from "../ui/button";
-
-type CreatorCardProps = {
- displayName: string;
- about: string;
- picture: string;
- banner: string;
-};
-
-export default function LongFormContentCard() {
- return (
-
-
-
-
-
- SC
-
-
- Derek Seivers
-
-
-
- {formatDate(new Date("10-5-23"), "MMM Do")}
-
-
-
-
-
- The start of the Nostr revolution
-
-
- This is the summary of this artilce. Let's hope that it is a good
- article and that it will end up being worth reading. I don't want to
- waste my time on some random other stuff.
-
-
+ );
+}
diff --git a/components/ui/tabs.tsx b/components/ui/tabs.tsx
new file mode 100644
index 0000000..0f4caeb
--- /dev/null
+++ b/components/ui/tabs.tsx
@@ -0,0 +1,55 @@
+"use client"
+
+import * as React from "react"
+import * as TabsPrimitive from "@radix-ui/react-tabs"
+
+import { cn } from "@/lib/utils"
+
+const Tabs = TabsPrimitive.Root
+
+const TabsList = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+TabsList.displayName = TabsPrimitive.List.displayName
+
+const TabsTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
+
+const TabsContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+TabsContent.displayName = TabsPrimitive.Content.displayName
+
+export { Tabs, TabsList, TabsTrigger, TabsContent }
diff --git a/constants/dummy.ts b/constants/dummy.ts
new file mode 100644
index 0000000..2a76b6f
--- /dev/null
+++ b/constants/dummy.ts
@@ -0,0 +1,38 @@
+import { type Event } from "nostr-tools";
+import { unixTimeNowInSeconds } from "@/lib/nostr/dates";
+
+export const DUMMY_1: Event = {
+ id: "test",
+ content: "Time for nostr to take over twitter",
+ kind: 1,
+ pubkey: "235235",
+ sig: "wetwet",
+ tags: [["t", "nostr"]],
+ created_at: unixTimeNowInSeconds() - 3600,
+};
+export const DUMMY_30023: Event = {
+ kind: 30023,
+ created_at: 1675642635,
+ content:
+ "Lorem [ipsum][nostr:nevent1qqst8cujky046negxgwwm5ynqwn53t8aqjr6afd8g59nfqwxpdhylpcpzamhxue69uhhyetvv9ujuetcv9khqmr99e3k7mg8arnc9] dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\nRead more at nostr:naddr1qqzkjurnw4ksz9thwden5te0wfjkccte9ehx7um5wghx7un8qgs2d90kkcq3nk2jry62dyf50k0h36rhpdtd594my40w9pkal876jxgrqsqqqa28pccpzu.",
+ tags: [
+ ["d", "lorem-ipsum"],
+ ["title", "Lorem Ipsum"],
+ ["published_at", "1296962229"],
+ ["t", "placeholder"],
+ ["t", "nostr"],
+ [
+ "e",
+ "b3e392b11f5d4f28321cedd09303a748acfd0487aea5a7450b3481c60b6e4f87",
+ "wss://relay.example.com",
+ ],
+ [
+ "a",
+ "30023:a695f6b60119d9521934a691347d9f78e8770b56da16bb255ee286ddf9fda919:ipsum",
+ "wss://relay.nostr.org",
+ ],
+ ],
+ pubkey: "...",
+ id: "...",
+ sig: "wetwet",
+};
diff --git a/constants/index.ts b/constants/index.ts
index 6d2e816..5f94006 100644
--- a/constants/index.ts
+++ b/constants/index.ts
@@ -1 +1,2 @@
export * from "./relays";
+export * from "./dummy";
diff --git a/containers/Article/Actions.tsx b/containers/Article/Actions.tsx
new file mode 100644
index 0000000..db4a1bc
--- /dev/null
+++ b/containers/Article/Actions.tsx
@@ -0,0 +1,26 @@
+"use client";
+import { Button } from "@/components/ui/button";
+import {
+ HiOutlineHandThumbUp,
+ HiOutlineChatBubbleLeftEllipsis,
+} from "react-icons/hi2";
+import { HiOutlineLightningBolt } from "react-icons/hi";
+
+export default function Actions() {
+ return (
+
+
+
+
+
+
+
+ );
+}
diff --git a/containers/Article/index.tsx b/containers/Article/index.tsx
new file mode 100644
index 0000000..b894ac2
--- /dev/null
+++ b/containers/Article/index.tsx
@@ -0,0 +1,109 @@
+"use client";
+import dynamic from "next/dynamic";
+import { useMemo } from "react";
+import { Button } from "@/components/ui/button";
+import { RiCloseFill } from "react-icons/ri";
+import { Avatar, AvatarImage, AvatarFallback } from "@radix-ui/react-avatar";
+import { useRouter } from "next/navigation";
+import { formatDate } from "@/lib/utils/dates";
+import Actions from "./Actions";
+
+export default function ArticlePage() {
+ const Viewer = useMemo(
+ () => dynamic(() => import("@/components/LongForm"), { ssr: false }),
+ [],
+ );
+ 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`;
+
+ return (
+