wip: migrated to nostr-relaypool

This commit is contained in:
Ren Amamiya 2023-02-26 18:01:28 +07:00
parent 3fbe6b3986
commit f3da53f098
6 changed files with 106 additions and 44 deletions

View File

@ -28,6 +28,7 @@
"next": "^13.2.1",
"next-remove-imports": "^1.0.10",
"nostr-react": "^0.6.4",
"nostr-relaypool": "^0.5.3",
"nostr-tools": "^1.6.0",
"qrcode.react": "^3.1.0",
"react": "^18.2.0",
@ -37,7 +38,8 @@
"react-player": "^2.11.2",
"react-virtuoso": "^4.1.0",
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql",
"unique-names-generator": "^4.7.1"
"unique-names-generator": "^4.7.1",
"ws": "^8.12.1"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.9",

View File

@ -34,6 +34,7 @@ specifiers:
next: ^13.2.1
next-remove-imports: ^1.0.10
nostr-react: ^0.6.4
nostr-relaypool: ^0.5.3
nostr-tools: ^1.6.0
postcss: ^8.4.21
prettier: ^2.8.4
@ -50,6 +51,7 @@ specifiers:
tauri-plugin-sql-api: github:tauri-apps/tauri-plugin-sql
typescript: ^4.9.5
unique-names-generator: ^4.7.1
ws: ^8.12.1
dependencies:
'@nanostores/persistent': 0.7.0_nanostores@0.7.4
@ -68,6 +70,7 @@ dependencies:
next: 13.2.1_biqbaboplfbrettd7655fr4n2y
next-remove-imports: 1.0.10
nostr-react: 0.6.4_react@18.2.0
nostr-relaypool: 0.5.3_ws@8.12.1
nostr-tools: 1.6.0
qrcode.react: 3.1.0_react@18.2.0
react: 18.2.0
@ -78,6 +81,7 @@ dependencies:
react-virtuoso: 4.1.0_biqbaboplfbrettd7655fr4n2y
tauri-plugin-sql-api: github.com/tauri-apps/tauri-plugin-sql/abd8759ef49e1ba441540a2260b453d43d86c7ee
unique-names-generator: 4.7.1
ws: 8.12.1
devDependencies:
'@tailwindcss/typography': 0.5.9_tailwindcss@3.2.7
@ -411,6 +415,15 @@ packages:
resolution: { integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== }
dev: true
/@jest/source-map/29.4.3:
resolution: { integrity: sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== }
engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 }
dependencies:
'@jridgewell/trace-mapping': 0.3.17
callsites: 3.1.0
graceful-fs: 4.2.10
dev: false
/@jridgewell/gen-mapping/0.1.1:
resolution: { integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== }
engines: { node: '>=6.0.0' }
@ -1729,7 +1742,6 @@ packages:
/callsites/3.1.0:
resolution: { integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== }
engines: { node: '>=6' }
dev: true
/camelcase-css/2.0.1:
resolution: { integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== }
@ -2734,7 +2746,6 @@ packages:
/graceful-fs/4.2.10:
resolution: { integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== }
dev: true
/grapheme-splitter/1.0.4:
resolution: { integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== }
@ -3187,6 +3198,14 @@ packages:
resolution: { integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== }
dev: true
/isomorphic-ws/5.0.0_ws@8.12.1:
resolution: { integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== }
peerDependencies:
ws: '*'
dependencies:
ws: 8.12.1
dev: false
/javascript-natural-sort/0.7.1:
resolution: { integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw== }
dev: true
@ -3983,6 +4002,17 @@ packages:
- jotai-zustand
dev: false
/nostr-relaypool/0.5.3_ws@8.12.1:
resolution: { integrity: sha512-1INGKleOTuUTFUs3RnnZrew4+G/idLUewh44WBtmTTJ9g+kRiQtMMaBGTVUpf9621nBNleEVOB8p3XSNcaX3FQ== }
dependencies:
'@jest/source-map': 29.4.3
isomorphic-ws: 5.0.0_ws@8.12.1
nostr-tools: 1.6.0
safe-stable-stringify: 2.4.2
transitivePeerDependencies:
- ws
dev: false
/nostr-tools/1.6.0:
resolution: { integrity: sha512-qjjJQ7YxJUMzgS24eVlxkZ87PKJtU6dlH04OzVuK6w+GSPL+VdUZkMe2lfSpnb7OkCrDIzmbFbtx+Q4LXdU2xw== }
dependencies:
@ -4824,6 +4854,11 @@ packages:
is-regex: 1.1.4
dev: true
/safe-stable-stringify/2.4.2:
resolution: { integrity: sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA== }
engines: { node: '>=10' }
dev: false
/scheduler/0.23.0:
resolution: { integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== }
dependencies:
@ -5447,6 +5482,19 @@ packages:
resolution: { integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== }
dev: true
/ws/8.12.1:
resolution: { integrity: sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew== }
engines: { node: '>=10.0.0' }
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
dev: false
/xtend/4.0.2:
resolution: { integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== }
engines: { node: '>=0.4' }

View File

@ -1,11 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import RelayProvider from '@stores/context';
import { relays } from '@stores/relays';
import { useStore } from '@nanostores/react';
import type { NextPage } from 'next';
import type { AppProps } from 'next/app';
import { NostrProvider } from 'nostr-react';
import type { ReactElement, ReactNode } from 'react';
import { ReactElement, ReactNode } from 'react';
import '../App.css';
@ -21,12 +21,8 @@ type AppPropsWithLayout = AppProps & {
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
// Get relays
// Get all relays
const $relays = useStore(relays);
return (
<NostrProvider relayUrls={$relays} debug={false}>
{getLayout(<Component {...pageProps} />)}
</NostrProvider>
);
return <RelayProvider relays={$relays}>{getLayout(<Component {...pageProps} />)}</RelayProvider>;
}

View File

@ -1,54 +1,59 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import BaseLayout from '@layouts/baseLayout';
import NewsFeedLayout from '@layouts/newsfeedLayout';
import { Placeholder } from '@components/note/placeholder';
import { Thread } from '@components/thread';
import { hoursAgo } from '@utils/getDate';
import { RelayContext } from '@stores/context';
import { follows } from '@stores/follows';
import { relays } from '@stores/relays';
import { useStore } from '@nanostores/react';
import { dateToUnix, useNostrEvents } from 'nostr-react';
import {
JSXElementConstructor,
ReactElement,
ReactFragment,
ReactPortal,
Suspense,
useRef,
} from 'react';
import { dateToUnix } from 'nostr-react';
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useContext, useEffect, useRef, useState } from 'react';
export default function Page() {
const $follows = useStore(follows);
const relayPool: any = useContext(RelayContext);
const [data, setData] = useState([]);
const now = useRef(new Date());
const { events } = useNostrEvents({
filter: {
authors: $follows,
since: dateToUnix(hoursAgo(6, now.current)),
kinds: [1],
limit: 100,
},
});
const $follows = useStore(follows);
const $relays = useStore(relays);
useEffect(() => {
const unsub = relayPool.subscribe(
[
{
kinds: [1],
authors: $follows,
since: dateToUnix(hoursAgo(12, now.current)),
},
],
$relays,
(event: any) => {
setData((data) => [event, ...data]);
},
undefined,
(events: any, relayURL: any) => {
console.log(events, relayURL);
}
);
return () => unsub();
}, [$follows, $relays, relayPool]);
return (
<div className="h-full w-full">
<Suspense fallback={<Placeholder />}>
<Thread data={events} />
</Suspense>
{data.map((item, index) => (
<p key={index}>{item.id}</p>
))}
</div>
);
}
Page.getLayout = function getLayout(
page:
| string
| number
| boolean
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
| ReactFragment
| ReactPortal
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
) {
return (
<BaseLayout>

View File

@ -40,7 +40,7 @@ export default function Page() {
return result;
}, []);
const getFollows = useCallback(async (account) => {
const getFollows = useCallback(async (account: { id: string }) => {
const arr = [];
const result: any = await db.select(`SELECT pubkey FROM follows WHERE account = "${account.id}"`);
@ -82,7 +82,7 @@ export default function Page() {
})
.catch(console.error);
});
}, [getAccount, getFollows, requestNotification, router]);
}, [requestNotification, getAccount, getFollows, router]);
return (
<div className="relative flex h-full flex-col items-center justify-between">

11
src/stores/context.tsx Normal file
View File

@ -0,0 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { RelayPool } from 'nostr-relaypool';
import { createContext, useMemo } from 'react';
export const RelayContext = createContext({});
export default function RelayProvider({ relays, children }: { relays: any; children: React.ReactNode }) {
const value = useMemo(() => new RelayPool(relays, { useEventCache: true }), [relays]);
return <RelayContext.Provider value={value}>{children}</RelayContext.Provider>;
}