added note connector (wip)
This commit is contained in:
@@ -35,9 +35,10 @@ CREATE TABLE
|
|||||||
CREATE TABLE
|
CREATE TABLE
|
||||||
cache_notes (
|
cache_notes (
|
||||||
id TEXT PRIMARY KEY,
|
id TEXT PRIMARY KEY,
|
||||||
note JSON,
|
pubkey TEXT NOT NULL,
|
||||||
|
created_at TEXT,
|
||||||
kind INTEGER NOT NULL DEFAULT 1,
|
kind INTEGER NOT NULL DEFAULT 1,
|
||||||
is_multi BOOLEAN DEFAULT 0,
|
tags TEXT NOT NULL,
|
||||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
content TEXT NOT NULL,
|
||||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
is_multi BOOLEAN DEFAULT 0
|
||||||
);
|
);
|
||||||
58
src/components/connectors/note.tsx
Normal file
58
src/components/connectors/note.tsx
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { DatabaseContext } from '@components/contexts/database';
|
||||||
|
import { RelayContext } from '@components/contexts/relay';
|
||||||
|
|
||||||
|
import { hoursAgo } from '@utils/getDate';
|
||||||
|
|
||||||
|
import { follows } from '@stores/follows';
|
||||||
|
import { relays } from '@stores/relays';
|
||||||
|
|
||||||
|
import { useStore } from '@nanostores/react';
|
||||||
|
import { dateToUnix } from 'nostr-react';
|
||||||
|
import { memo, useCallback, useContext, useRef } from 'react';
|
||||||
|
|
||||||
|
export const NoteConnector = memo(function NoteConnector() {
|
||||||
|
const db: any = useContext(DatabaseContext);
|
||||||
|
const relayPool: any = useContext(RelayContext);
|
||||||
|
|
||||||
|
const now = useRef(new Date());
|
||||||
|
|
||||||
|
const $follows = useStore(follows);
|
||||||
|
const $relays = useStore(relays);
|
||||||
|
|
||||||
|
const insertDB = useCallback(
|
||||||
|
async (event: any) => {
|
||||||
|
await db.execute(
|
||||||
|
`INSERT OR IGNORE INTO
|
||||||
|
cache_notes
|
||||||
|
(id, pubkey, created_at, kind, tags, content) VALUES
|
||||||
|
("${event.id}", "${event.pubkey}", "${event.created_at}", "${event.kind}", '${JSON.stringify(event.tags)}', "${event.content}");`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[db]
|
||||||
|
);
|
||||||
|
|
||||||
|
relayPool.subscribe(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
kinds: [1],
|
||||||
|
authors: $follows,
|
||||||
|
since: dateToUnix(hoursAgo(12, now.current)),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
$relays,
|
||||||
|
(event: any) => {
|
||||||
|
insertDB(event).catch(console.error);
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
(events: any, relayURL: any) => {
|
||||||
|
console.log(events, relayURL);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>Note</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import ActiveLink from '@components/activeLink';
|
import ActiveLink from '@components/activeLink';
|
||||||
|
import { NoteConnector } from '@components/connectors/note';
|
||||||
import CreatePost from '@components/navigatorBar/createPost';
|
import CreatePost from '@components/navigatorBar/createPost';
|
||||||
import { ProfileMenu } from '@components/navigatorBar/profileMenu';
|
import { ProfileMenu } from '@components/navigatorBar/profileMenu';
|
||||||
|
|
||||||
@@ -10,22 +11,20 @@ import { PlusIcon } from '@radix-ui/react-icons';
|
|||||||
|
|
||||||
export default function NavigatorBar() {
|
export default function NavigatorBar() {
|
||||||
const $currentUser: any = useStore(currentUser);
|
const $currentUser: any = useStore(currentUser);
|
||||||
const profile =
|
const profile = $currentUser.metadata !== undefined ? JSON.parse($currentUser.metadata) : { display_name: null, username: null };
|
||||||
$currentUser.metadata !== undefined
|
|
||||||
? JSON.parse($currentUser.metadata)
|
|
||||||
: { display_name: null, username: null };
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full flex-col flex-wrap justify-between overflow-hidden px-2 pt-3 pb-4">
|
<div className="flex h-full flex-col flex-wrap justify-between overflow-hidden px-2 pt-3 pb-4">
|
||||||
{/* main */}
|
{/* main */}
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
|
<div>
|
||||||
|
<NoteConnector />
|
||||||
|
</div>
|
||||||
{/* Create post */}
|
{/* Create post */}
|
||||||
<div className="flex flex-col rounded-lg bg-zinc-900 ring-1 ring-white/10">
|
<div className="flex flex-col rounded-lg bg-zinc-900 ring-1 ring-white/10">
|
||||||
<div className="flex flex-col p-2">
|
<div className="flex flex-col p-2">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h5 className="font-semibold leading-tight text-zinc-100">
|
<h5 className="font-semibold leading-tight text-zinc-100">{profile.display_name || ''}</h5>
|
||||||
{profile.display_name || ''}
|
|
||||||
</h5>
|
|
||||||
<ProfileMenu pubkey={$currentUser.pubkey} />
|
<ProfileMenu pubkey={$currentUser.pubkey} />
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm leading-tight text-zinc-500">@{profile.username || ''}</span>
|
<span className="text-sm leading-tight text-zinc-500">@{profile.username || ''}</span>
|
||||||
@@ -38,9 +37,7 @@ export default function NavigatorBar() {
|
|||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex items-center justify-between px-2">
|
<div className="flex items-center justify-between px-2">
|
||||||
<h3 className="text-sm font-bold text-zinc-400">Newsfeed</h3>
|
<h3 className="text-sm font-bold text-zinc-400">Newsfeed</h3>
|
||||||
<button
|
<button type="button" className="group flex h-6 w-6 items-center justify-center rounded-full hover:bg-zinc-900">
|
||||||
type="button"
|
|
||||||
className="group flex h-6 w-6 items-center justify-center rounded-full hover:bg-zinc-900">
|
|
||||||
<PlusIcon className="h-3 w-3 text-zinc-400 group-hover:text-zinc-100" />
|
<PlusIcon className="h-3 w-3 text-zinc-400 group-hover:text-zinc-100" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -65,9 +62,7 @@ export default function NavigatorBar() {
|
|||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex items-center justify-between px-2">
|
<div className="flex items-center justify-between px-2">
|
||||||
<h3 className="text-sm font-bold text-zinc-400">Direct Messages</h3>
|
<h3 className="text-sm font-bold text-zinc-400">Direct Messages</h3>
|
||||||
<button
|
<button type="button" className="group flex h-6 w-6 items-center justify-center rounded-full hover:bg-zinc-900">
|
||||||
type="button"
|
|
||||||
className="group flex h-6 w-6 items-center justify-center rounded-full hover:bg-zinc-900">
|
|
||||||
<PlusIcon className="h-3 w-3 text-zinc-400 group-hover:text-zinc-100" />
|
<PlusIcon className="h-3 w-3 text-zinc-400 group-hover:text-zinc-100" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,56 +3,29 @@ import BaseLayout from '@layouts/baseLayout';
|
|||||||
import NewsFeedLayout from '@layouts/newsfeedLayout';
|
import NewsFeedLayout from '@layouts/newsfeedLayout';
|
||||||
|
|
||||||
import { DatabaseContext } from '@components/contexts/database';
|
import { DatabaseContext } from '@components/contexts/database';
|
||||||
import { RelayContext } from '@components/contexts/relay';
|
|
||||||
import { Placeholder } from '@components/note/placeholder';
|
import { Placeholder } from '@components/note/placeholder';
|
||||||
import { Thread } from '@components/thread';
|
import { Thread } from '@components/thread';
|
||||||
|
|
||||||
import { hoursAgo } from '@utils/getDate';
|
|
||||||
|
|
||||||
import { follows } from '@stores/follows';
|
|
||||||
import { relays } from '@stores/relays';
|
|
||||||
|
|
||||||
import { useStore } from '@nanostores/react';
|
|
||||||
import { dateToUnix } from 'nostr-react';
|
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, Suspense, useContext, useEffect, useRef, useState } from 'react';
|
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, Suspense, useContext, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const db: any = useContext(DatabaseContext);
|
const db: any = useContext(DatabaseContext);
|
||||||
const relayPool: any = useContext(RelayContext);
|
const [data, setData] = useState([]);
|
||||||
|
const limit = useRef(25);
|
||||||
const now = useRef(new Date());
|
|
||||||
|
|
||||||
const $follows = useStore(follows);
|
|
||||||
const $relays = useStore(relays);
|
|
||||||
|
|
||||||
const [events, setEvents] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsub = relayPool.subscribe(
|
const getData = async () => {
|
||||||
[
|
const result = await db.select(`SELECT * FROM cache_notes ORDER BY created_at DESC LIMIT ${limit.current}`);
|
||||||
{
|
setData(result);
|
||||||
kinds: [1],
|
};
|
||||||
authors: $follows,
|
|
||||||
since: dateToUnix(hoursAgo(12, now.current)),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
$relays,
|
|
||||||
async (event: any) => {
|
|
||||||
setEvents((events) => [event, ...events]);
|
|
||||||
},
|
|
||||||
undefined,
|
|
||||||
(events: any, relayURL: any) => {
|
|
||||||
console.log(events, relayURL);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return () => unsub();
|
getData().catch(console.error);
|
||||||
}, [$follows, $relays, db, relayPool]);
|
}, [db]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full w-full">
|
<div className="h-full w-full">
|
||||||
<Suspense fallback={<Placeholder />}>
|
<Suspense fallback={<Placeholder />}>
|
||||||
<Thread data={events} />
|
<Thread data={data} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user