@@ -42,22 +42,82 @@ const ChatEvents = [
4242 description :
4343 "Triggered when the user stops typing. Wire this to chatController.stopTyping()." ,
4444 } ,
45+ {
46+ label : "Room Switch" ,
47+ value : "roomSwitch" ,
48+ description :
49+ "User clicked a room they are already a member of. Read chatBox.pendingRoomId, then call chatController.switchRoom({{chatBox1.pendingRoomId}})." ,
50+ } ,
51+ {
52+ label : "Room Join" ,
53+ value : "roomJoin" ,
54+ description :
55+ "User wants to join a room from search results. Read chatBox.pendingRoomId, then call chatController.joinRoom({{chatBox1.pendingRoomId}})." ,
56+ } ,
57+ {
58+ label : "Room Leave" ,
59+ value : "roomLeave" ,
60+ description :
61+ "User clicked leave on a room. Read chatBox.pendingRoomId, then call chatController.leaveRoom({{chatBox1.pendingRoomId}})." ,
62+ } ,
63+ {
64+ label : "Room Create" ,
65+ value : "roomCreate" ,
66+ description :
67+ "User submitted the create-room form. Read chatBox.newRoomName, newRoomType, newRoomDescription, newRoomLlmQuery, then call chatController.createRoom(...)." ,
68+ } ,
69+ {
70+ label : "Invite Send" ,
71+ value : "inviteSend" ,
72+ description :
73+ "User sent a room invite. Read chatBox.inviteTargetUserId, then call chatController.sendInvite(currentRoomId, {{chatBox1.inviteTargetUserId}})." ,
74+ } ,
75+ {
76+ label : "Invite Accept" ,
77+ value : "inviteAccept" ,
78+ description :
79+ "User accepted a pending invite. Read chatBox.pendingInviteId, then call chatController.acceptInvite({{chatBox1.pendingInviteId}})." ,
80+ } ,
81+ {
82+ label : "Invite Decline" ,
83+ value : "inviteDecline" ,
84+ description :
85+ "User declined a pending invite. Read chatBox.pendingInviteId, then call chatController.declineInvite({{chatBox1.pendingInviteId}})." ,
86+ } ,
4587] as const ;
4688
4789// ─── Children map ────────────────────────────────────────────────────────────
4890
4991const childrenMap = {
92+ // ── Chat content ─────────────────────────────────────────────────
5093 chatTitle : stringExposingStateControl ( "chatTitle" , "Chat" ) ,
5194 showHeader : withDefault ( BoolControl , true ) ,
52-
5395 messages : jsonArrayControl ( [ ] ) ,
5496 currentUserId : withDefault ( StringControl , "user_1" ) ,
5597 currentUserName : withDefault ( StringControl , "User" ) ,
5698 typingUsers : jsonArrayControl ( [ ] ) ,
57-
5899 lastSentMessageText : stringExposingStateControl ( "lastSentMessageText" , "" ) ,
59100 messageText : stringExposingStateControl ( "messageText" , "" ) ,
60101
102+ // ── Rooms panel ──────────────────────────────────────────────────
103+ rooms : jsonArrayControl ( [ ] ) ,
104+ currentRoomId : withDefault ( StringControl , "" ) ,
105+ pendingInvites : jsonArrayControl ( [ ] ) ,
106+ showRoomsPanel : withDefault ( BoolControl , true ) ,
107+ roomsPanelWidth : withDefault ( StringControl , "240px" ) ,
108+ allowRoomCreation : withDefault ( BoolControl , true ) ,
109+ allowRoomSearch : withDefault ( BoolControl , true ) ,
110+
111+ // ── Exposed state written on user interactions ────────────────────
112+ pendingRoomId : stringExposingStateControl ( "pendingRoomId" , "" ) ,
113+ newRoomName : stringExposingStateControl ( "newRoomName" , "" ) ,
114+ newRoomType : stringExposingStateControl ( "newRoomType" , "public" ) ,
115+ newRoomDescription : stringExposingStateControl ( "newRoomDescription" , "" ) ,
116+ newRoomLlmQuery : stringExposingStateControl ( "newRoomLlmQuery" , "" ) ,
117+ inviteTargetUserId : stringExposingStateControl ( "inviteTargetUserId" , "" ) ,
118+ pendingInviteId : stringExposingStateControl ( "pendingInviteId" , "" ) ,
119+
120+ // ── Style / layout ────────────────────────────────────────────────
61121 autoHeight : AutoHeightControl ,
62122 onEvent : eventHandlerControl ( ChatEvents ) ,
63123 style : styleControl ( TextStyle , "style" ) ,
@@ -93,6 +153,31 @@ const ChatBoxPropertyView = React.memo((props: { children: any }) => {
93153 } ) }
94154 </ Section >
95155
156+ < Section name = "Rooms Panel" >
157+ { children . showRoomsPanel . propertyView ( { label : "Show Rooms Panel" } ) }
158+ { children . roomsPanelWidth . propertyView ( {
159+ label : "Panel Width" ,
160+ tooltip : "Width of the rooms sidebar, e.g. 240px or 30%" ,
161+ } ) }
162+ { children . rooms . propertyView ( {
163+ label : "Rooms" ,
164+ tooltip :
165+ "Bind to {{ chatController1.userRooms }} — the list of rooms visible to the current user." ,
166+ } ) }
167+ { children . currentRoomId . propertyView ( {
168+ label : "Current Room ID" ,
169+ tooltip :
170+ "Bind to {{ chatController1.currentRoomId }} to highlight the active room." ,
171+ } ) }
172+ { children . pendingInvites . propertyView ( {
173+ label : "Pending Invites" ,
174+ tooltip :
175+ "Bind to {{ chatController1.pendingInvites }} to show invite notifications." ,
176+ } ) }
177+ { children . allowRoomCreation . propertyView ( { label : "Allow Room Creation" } ) }
178+ { children . allowRoomSearch . propertyView ( { label : "Allow Room Search" } ) }
179+ </ Section >
180+
96181 < Section name = "Real-time" >
97182 { children . typingUsers . propertyView ( {
98183 label : "Typing Users" ,
@@ -148,6 +233,46 @@ let ChatBoxV2Tmp = (function () {
148233 style = { props . style }
149234 animationStyle = { props . animationStyle }
150235 onEvent = { props . onEvent }
236+ // Rooms panel
237+ rooms = { props . rooms }
238+ currentRoomId = { props . currentRoomId }
239+ pendingInvites = { props . pendingInvites }
240+ showRoomsPanel = { props . showRoomsPanel }
241+ roomsPanelWidth = { props . roomsPanelWidth }
242+ allowRoomCreation = { props . allowRoomCreation }
243+ allowRoomSearch = { props . allowRoomSearch }
244+ // Callbacks that set state then fire events
245+ onRoomSwitch = { ( roomId ) => {
246+ props . pendingRoomId . onChange ( roomId ) ;
247+ props . onEvent ( "roomSwitch" ) ;
248+ } }
249+ onRoomJoin = { ( roomId ) => {
250+ props . pendingRoomId . onChange ( roomId ) ;
251+ props . onEvent ( "roomJoin" ) ;
252+ } }
253+ onRoomLeave = { ( roomId ) => {
254+ props . pendingRoomId . onChange ( roomId ) ;
255+ props . onEvent ( "roomLeave" ) ;
256+ } }
257+ onRoomCreate = { ( name , type , description , llmQueryName ) => {
258+ props . newRoomName . onChange ( name ) ;
259+ props . newRoomType . onChange ( type ) ;
260+ props . newRoomDescription . onChange ( description || "" ) ;
261+ props . newRoomLlmQuery . onChange ( llmQueryName || "" ) ;
262+ props . onEvent ( "roomCreate" ) ;
263+ } }
264+ onInviteSend = { ( toUserId ) => {
265+ props . inviteTargetUserId . onChange ( toUserId ) ;
266+ props . onEvent ( "inviteSend" ) ;
267+ } }
268+ onInviteAccept = { ( inviteId ) => {
269+ props . pendingInviteId . onChange ( inviteId ) ;
270+ props . onEvent ( "inviteAccept" ) ;
271+ } }
272+ onInviteDecline = { ( inviteId ) => {
273+ props . pendingInviteId . onChange ( inviteId ) ;
274+ props . onEvent ( "inviteDecline" ) ;
275+ } }
151276 />
152277 ) ;
153278 } )
@@ -170,5 +295,27 @@ export const ChatBoxV2Comp = withExposingConfigs(ChatBoxV2Tmp, [
170295 "Text of the last message sent by the user — use in your save query" ,
171296 ) ,
172297 new NameConfig ( "messageText" , "Current text in the message input" ) ,
298+ new NameConfig (
299+ "pendingRoomId" ,
300+ "Room ID the user wants to switch to, join, or leave — read in roomSwitch/roomJoin/roomLeave events" ,
301+ ) ,
302+ new NameConfig ( "newRoomName" , "Name entered in the create-room form" ) ,
303+ new NameConfig (
304+ "newRoomType" ,
305+ "Type selected in the create-room form: public | private | llm" ,
306+ ) ,
307+ new NameConfig ( "newRoomDescription" , "Description entered in the create-room form" ) ,
308+ new NameConfig (
309+ "newRoomLlmQuery" ,
310+ "Query name entered for LLM rooms in the create-room form" ,
311+ ) ,
312+ new NameConfig (
313+ "inviteTargetUserId" ,
314+ "User ID entered in the invite form — read in inviteSend event" ,
315+ ) ,
316+ new NameConfig (
317+ "pendingInviteId" ,
318+ "Invite ID the user accepted or declined — read in inviteAccept/inviteDecline events" ,
319+ ) ,
173320 NameConfigHidden ,
174321] ) ;
0 commit comments