|
1 | 1 | import { useEffect, useState, useRef, useCallback } from 'react'; |
2 | 2 | import { useRouter } from 'next/router'; |
| 3 | +import CloseIcon from '@mui/icons-material/Close'; |
3 | 4 |
|
4 | 5 | import { AssistantChatPanel } from '../components/AssistantChatPanel'; |
5 | 6 | import { GroupChatPanel } from '../components/GroupChatPanel'; |
@@ -30,6 +31,7 @@ import { useSessionJoin } from '../utils/useSessionJoin'; |
30 | 31 | import { NavigationBar, NavTab } from '../components/NavigationBar'; |
31 | 32 | import { PreferencesPanel } from '../components/PreferencesPanel'; |
32 | 33 | import { getFeedbackEligibleMessages } from '../utils/feedbackEligibility'; |
| 34 | +import { Button } from '@mui/material'; |
33 | 35 |
|
34 | 36 | export const getServerSideProps = async (context: { req: any }) => { |
35 | 37 | return CheckAuthHeader(context.req.headers); |
@@ -115,8 +117,10 @@ function EventAssistantRoom({ authType: _authType }: { authType: AuthType }) { |
115 | 117 | const hasJoinedConvRef = useRef(false); |
116 | 118 | const [agentId, setAgentId] = useState<string | null>(null); |
117 | 119 | const [agentActive, setAgentActive] = useState<boolean>(true); |
| 120 | + const [resourcesReminderActive, setResourcesReminderActive] = useState<boolean>(false); |
118 | 121 | const [agentIds, setAgentIds] = useState<string[]>([]); |
119 | 122 | const [conversationFeatures, setConversationFeatures] = useState<{ name: string; enabled?: boolean }[]>([]); |
| 123 | + |
120 | 124 | const conversationType = useConversationType(); |
121 | 125 | const setConversationType = useSetConversationType(); |
122 | 126 | const setBotNameContext = useSetBotName(); |
@@ -147,6 +151,9 @@ function EventAssistantRoom({ authType: _authType }: { authType: AuthType }) { |
147 | 151 | // Ref to track active tab for socket handler |
148 | 152 | const activeTabRef = useRef<NavTab>('assistant'); |
149 | 153 |
|
| 154 | + // Ref to track resources value |
| 155 | + const resourcesRef = useRef<Resource[]>(resources); |
| 156 | + |
150 | 157 | // Use custom hook for session joining |
151 | 158 | const { socket, pseudonym, userId, isConnected, errorMessage: sessionError, lastReconnectTime } = useSessionJoin(); |
152 | 159 |
|
@@ -235,21 +242,33 @@ function EventAssistantRoom({ authType: _authType }: { authType: AuthType }) { |
235 | 242 | }); |
236 | 243 | }; |
237 | 244 |
|
| 245 | + const conversationEndingHandler = () => { |
| 246 | + console.log('conversation:ending received'); |
| 247 | + |
| 248 | + // Don't activate the resources reminder if no resources are available |
| 249 | + if (resourcesRef.current.length === 0) return; |
| 250 | + setResourcesReminderActive(true); |
| 251 | + }; |
| 252 | + |
238 | 253 | const pollChoiceHandler = (data: { pollId: string; counts: Record<string, number> }) => { |
239 | 254 | if (!data?.pollId || !data?.counts) return; |
240 | 255 | setPollCounts((prev) => ({ ...prev, [data.pollId]: data.counts })); |
241 | 256 | }; |
242 | 257 |
|
243 | 258 | socket.on('message:new', messageHandler); |
244 | 259 | socket.on('resources:updated', resourcesUpdatedHandler); |
| 260 | + socket.on('conversation:ending', conversationEndingHandler); |
245 | 261 | socket.on('choice:new', pollChoiceHandler); |
246 | 262 |
|
| 263 | + console.log('Socket event listeners registered'); |
| 264 | + |
247 | 265 | return () => { |
248 | 266 | socket.off('message:new', messageHandler); |
249 | 267 | socket.off('resources:updated', resourcesUpdatedHandler); |
| 268 | + socket.off('conversation:ending', conversationEndingHandler); |
250 | 269 | socket.off('choice:new', pollChoiceHandler); |
251 | 270 | }; |
252 | | - }, [socket]); |
| 271 | + }, [socket, resourcesNavBadgeDismissed, resources.length]); |
253 | 272 |
|
254 | 273 | // Keep activeTabRef in sync with activeTab state |
255 | 274 | useEffect(() => { |
@@ -315,6 +334,7 @@ function EventAssistantRoom({ authType: _authType }: { authType: AuthType }) { |
315 | 334 | } |
316 | 335 |
|
317 | 336 | if (Array.isArray(conversation?.resources)) { |
| 337 | + console.log('Fetched conversation resources:', conversation.resources); |
318 | 338 | setResources(conversation.resources); |
319 | 339 | } |
320 | 340 |
|
@@ -757,6 +777,11 @@ function EventAssistantRoom({ authType: _authType }: { authType: AuthType }) { |
757 | 777 | return () => window.removeEventListener('keydown', handleKeyDown); |
758 | 778 | }, [controlledMode]); |
759 | 779 |
|
| 780 | + // Keep resourcesRef in sync with resources state |
| 781 | + useEffect(() => { |
| 782 | + resourcesRef.current = resources; |
| 783 | + }, [resources]); |
| 784 | + |
760 | 785 | const sendFeedbackRating = async (messageId: string, rating: string) => { |
761 | 786 | const conversationId = router.query.conversationId as string; |
762 | 787 | trackConversationEvent(conversationId, 'assistant', 'rating_submitted', rating); |
@@ -873,6 +898,35 @@ function EventAssistantRoom({ authType: _authType }: { authType: AuthType }) { |
873 | 898 | <> |
874 | 899 | {/* Chat / Assistant / Resources / Preferences panel */} |
875 | 900 | <div className="flex-1 flex flex-col relative overflow-hidden"> |
| 901 | + {/* Show dismissable resources reminder if active */} |
| 902 | + {resourcesReminderActive && ( |
| 903 | + <div className="absolute top-0 w-full z-10 bg-yellow-100 p-4 rounded shadow-2xl animate-slide-in"> |
| 904 | + <div className="flex justify-between font-bold"> |
| 905 | + <p> |
| 906 | + {resourcesNavBadgeDismissed |
| 907 | + ? "This event ends soon. Don't forget to review Resources and bookmark or save them for your reference." |
| 908 | + : "This event ends soon. Don't forget to check the Resources tab for follow-up readings worth bookmarking."} |
| 909 | + </p> |
| 910 | + <Button |
| 911 | + aria-label="Dismiss resources reminder" |
| 912 | + className="ml-4 px-2 py-2" |
| 913 | + onClick={() => setResourcesReminderActive(false)} |
| 914 | + color="error" |
| 915 | + > |
| 916 | + <CloseIcon /> |
| 917 | + </Button> |
| 918 | + </div> |
| 919 | + <button |
| 920 | + className="mt-2 px-3 py-1 bg-yellow-200 hover:bg-yellow-300 rounded" |
| 921 | + onClick={() => { |
| 922 | + handleTabChange('resources'); |
| 923 | + setResourcesReminderActive(false); |
| 924 | + }} |
| 925 | + > |
| 926 | + View Resources |
| 927 | + </button> |
| 928 | + </div> |
| 929 | + )} |
876 | 930 | {router.query.view === 'preferences' ? ( |
877 | 931 | <PreferencesPanel botName={botName} /> |
878 | 932 | ) : isConnected ? ( |
|
0 commit comments