11import { Button } from '@/components/ui/button' ;
2+ import { assertExhaustive } from '@/lib/assertExhaustive' ;
23import { createFileRoute } from '@tanstack/react-router' ;
3- import { createIdentity , createSpace } from 'graph-framework' ;
4+ import * as Schema from 'effect/Schema' ;
5+ import type { EventMessage , RequestListSpaces , RequestSubscribeToSpace } from 'graph-framework' ;
6+ import { ResponseMessage , createIdentity , createSpace } from 'graph-framework' ;
47import { useEffect , useState } from 'react' ;
58
9+ const decodeResponseMessage = Schema . decodeUnknownEither ( ResponseMessage ) ;
10+
611export const Route = createFileRoute ( '/playground' ) ( {
7- component : ( ) => < Playground /> ,
12+ component : ( ) => < ChooseAccount /> ,
813} ) ;
914
10- const Playground = ( ) => {
15+ const App = ( { accountId } : { accountId : string } ) => {
1116 const [ websocketConnection , setWebsocketConnection ] = useState < WebSocket > ( ) ;
17+ const [ spaces , setSpaces ] = useState < { id : string } [ ] > ( [ ] ) ;
1218
1319 useEffect ( ( ) => {
14- const websocketConnection = new WebSocket ( `ws://localhost:3030/` ) ;
20+ // temporary until we have a way to create accounts and authenticate them
21+ const websocketConnection = new WebSocket ( `ws://localhost:3030/?accountId=${ accountId } ` ) ;
1522 setWebsocketConnection ( websocketConnection ) ;
1623
1724 const onMessage = ( event : MessageEvent ) => {
1825 console . log ( 'message received' , event . data ) ;
26+ const data = JSON . parse ( event . data ) ;
27+ const message = decodeResponseMessage ( data ) ;
28+ if ( message . _tag === 'Right' ) {
29+ const response = message . right ;
30+ switch ( response . type ) {
31+ case 'list-spaces' : {
32+ setSpaces ( response . spaces . map ( ( space ) => ( { id : space . id } ) ) ) ;
33+ break ;
34+ }
35+ case 'space' : {
36+ console . log ( 'space' , response ) ;
37+ break ;
38+ }
39+ case 'event' : {
40+ console . log ( 'event' , response ) ;
41+ break ;
42+ }
43+ default :
44+ assertExhaustive ( response ) ;
45+ }
46+ }
1947 } ;
2048 websocketConnection . addEventListener ( 'message' , onMessage ) ;
2149
@@ -41,19 +69,89 @@ const Playground = () => {
4169 websocketConnection . removeEventListener ( 'close' , onClose ) ;
4270 websocketConnection . close ( ) ;
4371 } ;
44- } , [ ] ) ;
72+ } , [ accountId ] ) ;
73+
74+ return (
75+ < >
76+ < div >
77+ < Button
78+ onClick = { ( ) => {
79+ const identity = createIdentity ( ) ;
80+ const spaceEvent = createSpace ( { author : identity } ) ;
81+ const message : EventMessage = { type : 'event' , event : spaceEvent } ;
82+ websocketConnection ?. send ( JSON . stringify ( message ) ) ;
83+ } }
84+ >
85+ Create space
86+ </ Button >
87+
88+ < Button
89+ onClick = { ( ) => {
90+ const message : RequestListSpaces = { type : 'list-spaces' } ;
91+ websocketConnection ?. send ( JSON . stringify ( message ) ) ;
92+ } }
93+ >
94+ List Spaces
95+ </ Button >
96+ </ div >
97+ < h2 > Spaces</ h2 >
98+ < ul >
99+ { spaces . map ( ( space ) => {
100+ return (
101+ < li key = { space . id } >
102+ < h3 > { space . id } </ h3 >
103+ < Button
104+ onClick = { ( ) => {
105+ const message : RequestSubscribeToSpace = { type : 'subscribe-space' , id : space . id } ;
106+ websocketConnection ?. send ( JSON . stringify ( message ) ) ;
107+ } }
108+ >
109+ Get data and subscribe to Space
110+ </ Button >
111+ </ li >
112+ ) ;
113+ } ) }
114+ </ ul >
115+ </ >
116+ ) ;
117+ } ;
118+
119+ export const ChooseAccount = ( ) => {
120+ const [ accountId , setAccountId ] = useState < string | null > ( ) ;
45121
46122 return (
47123 < div >
124+ < h1 > Choose account</ h1 >
125+ < Button
126+ onClick = { ( ) => {
127+ setAccountId ( 'abc' ) ;
128+ } }
129+ >
130+ `abc`
131+ </ Button >
132+ < Button
133+ onClick = { ( ) => {
134+ setAccountId ( 'cde' ) ;
135+ } }
136+ >
137+ `cde`
138+ </ Button >
48139 < Button
49140 onClick = { ( ) => {
50- const identity = createIdentity ( ) ;
51- const spaceEvent = createSpace ( { author : identity } ) ;
52- websocketConnection ?. send ( JSON . stringify ( spaceEvent ) ) ;
141+ setAccountId ( 'def' ) ;
53142 } }
54143 >
55- Create space
144+ `def`
56145 </ Button >
146+ Account: { accountId ? accountId : 'none' }
147+ < hr />
148+ { accountId && (
149+ < App
150+ // forcing a remount of the App component when the accountId changes
151+ key = { accountId }
152+ accountId = { accountId }
153+ />
154+ ) }
57155 </ div >
58156 ) ;
59157} ;
0 commit comments