Skip to content

Commit 741eb82

Browse files
committed
add relay group example
1 parent 5b8d634 commit 741eb82

File tree

2 files changed

+82
-6
lines changed

2 files changed

+82
-6
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { useEffect, useState } from "react";
2+
import { Button, Container, FormControl, FormHelperText, Input, InputLabel, Stack } from "@mui/material";
3+
import { decodeGroupPointer, getSeenRelays, GroupPointer } from "applesauce-core/helpers";
4+
import { EventStore, QueryStore } from "applesauce-core";
5+
import { SimplePool } from "nostr-tools";
6+
import { useStoreQuery } from "applesauce-react/hooks";
7+
import { TimelineQuery } from "applesauce-core/queries";
8+
import { npubEncode } from "nostr-tools/nip19";
9+
import { QueryStoreProvider } from "applesauce-react";
10+
11+
const eventStore = new EventStore();
12+
const queryStore = new QueryStore(eventStore);
13+
14+
const pool = new SimplePool();
15+
16+
function ChatLog({ pointer }: { pointer: GroupPointer }) {
17+
const [status, setStatus] = useState("connecting...");
18+
const url = `wss://${pointer.relay}`;
19+
20+
useEffect(() => {
21+
const sub = pool.subscribeMany([url], [{ kinds: [9], "#h": [pointer.id] }], {
22+
onevent: (event) => {
23+
setStatus("connected");
24+
eventStore.add(event, url);
25+
},
26+
onclose: () => setStatus("closed"),
27+
});
28+
return () => sub.close();
29+
}, [pointer, url]);
30+
31+
const messages = useStoreQuery(TimelineQuery, [{ kinds: [9], "#h": [pointer.id] }])?.filter((event) =>
32+
getSeenRelays(event)?.has(url),
33+
);
34+
35+
return (
36+
<Stack direction="column" spacing={1}>
37+
<center>{status}</center>
38+
{messages?.map((message) => (
39+
<p key={message.id}>
40+
{npubEncode(message.pubkey).slice(0, 10)}: {message.content}
41+
</p>
42+
))}
43+
</Stack>
44+
);
45+
}
46+
47+
export default function RelayGroupExample() {
48+
const [identifier, setIdentifier] = useState("");
49+
50+
const [pointer, setPointer] = useState<GroupPointer>();
51+
52+
const load = () => {
53+
try {
54+
setPointer(decodeGroupPointer(identifier));
55+
} catch (error) {}
56+
};
57+
58+
return (
59+
<QueryStoreProvider queryStore={queryStore}>
60+
<Container>
61+
<Stack direction="row" spacing={2} padding={2} width="600px" alignItems="center">
62+
<FormControl size="medium">
63+
<InputLabel htmlFor="group-id">Group Identifier</InputLabel>
64+
<Input
65+
id="group-id"
66+
aria-describedby="group-helper"
67+
value={identifier}
68+
onChange={(e) => setIdentifier(e.target.value)}
69+
/>
70+
<FormHelperText id="group-helper">The NIP-29 group identifier</FormHelperText>
71+
</FormControl>
72+
<Button onClick={load} variant="contained">
73+
Load
74+
</Button>
75+
</Stack>
76+
77+
{pointer && <ChatLog pointer={pointer} />}
78+
</Container>
79+
</QueryStoreProvider>
80+
);
81+
}

packages/examples/src/main.tsx

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { StrictMode } from "react";
21
import { createRoot } from "react-dom/client";
32

43
import "@fontsource/roboto/300.css";
@@ -8,8 +7,4 @@ import "@fontsource/roboto/700.css";
87

98
import App from "./App.tsx";
109

11-
createRoot(document.getElementById("root")!).render(
12-
<StrictMode>
13-
<App />
14-
</StrictMode>,
15-
);
10+
createRoot(document.getElementById("root")!).render(<App />);

0 commit comments

Comments
 (0)