@@ -628,8 +628,6 @@ export const HiveChatView: React.FC = observer(() => {
628
628
const lastRefreshTime = useRef < number > ( Date . now ( ) ) . current ;
629
629
const refreshIntervalRef = useRef < NodeJS . Timeout | null > ( null ) ;
630
630
const [ isRefreshingTitle , setIsRefreshingTitle ] = useState ( false ) ;
631
- const [ lastTitleRefreshTime , setLastTitleRefreshTime ] = useState ( Date . now ( ) ) ;
632
- const titleRefreshIntervalRef = useRef < NodeJS . Timeout | null > ( null ) ;
633
631
const [ sseLogs , setSseLogs ] = useState < SSEMessage [ ] > ( [ ] ) ;
634
632
useBrowserTabTitle ( 'Hive Chat' ) ;
635
633
@@ -908,7 +906,7 @@ export const HiveChatView: React.FC = observer(() => {
908
906
setIsChainVisible ( false ) ;
909
907
setIsActionSend ( false ) ;
910
908
911
- if ( data . artifacts . length === 0 ) {
909
+ if ( data . artifacts ? .length === 0 ) {
912
910
setLogs ( [ ] ) ;
913
911
setLastLogLine ( '' ) ;
914
912
}
@@ -947,7 +945,7 @@ export const HiveChatView: React.FC = observer(() => {
947
945
} , [ projectId , chatId , isVerboseLoggingEnabled , isActionSend ] ) ;
948
946
949
947
useEffect ( ( ) => {
950
- if ( logs . length > 0 ) {
948
+ if ( logs ? .length > 0 ) {
951
949
setLastLogLine ( logs [ logs . length - 1 ] ?. message || '' ) ;
952
950
}
953
951
} , [ logs ] ) ;
@@ -1089,7 +1087,7 @@ export const HiveChatView: React.FC = observer(() => {
1089
1087
1090
1088
useEffect ( ( ) => {
1091
1089
const checkForNewArtifacts = async ( ) => {
1092
- if ( ! chatId || ! isArtifactLoggingEnabled || messages . length === 0 ) return ;
1090
+ if ( ! chatId || ! isArtifactLoggingEnabled || messages ? .length === 0 ) return ;
1093
1091
1094
1092
const latestMessage = messages [ messages . length - 1 ] ;
1095
1093
if ( latestMessage && latestMessage . id !== lastProcessedMessageId ) {
@@ -1148,7 +1146,7 @@ export const HiveChatView: React.FC = observer(() => {
1148
1146
hasTextUpdates ? 'text' : null
1149
1147
] . filter ( Boolean ) as ( 'visual' | 'code' | 'text' | 'logs' ) [ ] ;
1150
1148
1151
- if ( availableTabs . length > 0 && ! availableTabs . includes ( artifactTab ) ) {
1149
+ if ( availableTabs ? .length > 0 && ! availableTabs . includes ( artifactTab ) ) {
1152
1150
setArtifactTab ( availableTabs [ 0 ] ) ;
1153
1151
}
1154
1152
}
@@ -1344,64 +1342,38 @@ export const HiveChatView: React.FC = observer(() => {
1344
1342
dividerRef . current ?. focus ( ) ;
1345
1343
} ;
1346
1344
1347
- useEffect ( ( ) => {
1348
- const handleMouseMove = ( e : MouseEvent ) => {
1349
- if ( ! isDraggingRef . current ) return ;
1350
-
1351
- const containerWidth = containerRef . current ?. clientWidth || 1000 ;
1352
- const deltaX = e . clientX - startXRef . current ;
1353
- const deltaPercentage = ( deltaX / containerWidth ) * 100 ;
1354
-
1355
- let newChatWidth = startChatWidthRef . current + deltaPercentage ;
1356
-
1357
- newChatWidth = Math . max ( 20 , Math . min ( 80 , newChatWidth ) ) ;
1358
- const newViewerWidth = 100 - newChatWidth ;
1359
-
1360
- setChatSectionWidth ( `${ newChatWidth } %` ) ;
1361
- setViewerSectionWidth ( `${ newViewerWidth } %` ) ;
1362
- } ;
1363
-
1364
- const handleMouseUp = ( ) => {
1365
- if ( isDraggingRef . current ) {
1366
- isDraggingRef . current = false ;
1367
- document . body . style . cursor = '' ;
1368
- document . body . style . userSelect = '' ;
1369
-
1370
- localStorage . setItem ( 'hiveChatSectionWidth' , chatSectionWidth ) ;
1371
- localStorage . setItem ( 'hiveViewerSectionWidth' , viewerSectionWidth ) ;
1372
- }
1373
- } ;
1374
-
1375
- document . addEventListener ( 'mousemove' , handleMouseMove ) ;
1376
- document . addEventListener ( 'mouseup' , handleMouseUp ) ;
1377
-
1378
- return ( ) => {
1379
- document . removeEventListener ( 'mousemove' , handleMouseMove ) ;
1380
- document . removeEventListener ( 'mouseup' , handleMouseUp ) ;
1381
- } ;
1382
- } , [ chatSectionWidth , viewerSectionWidth ] ) ;
1345
+ // Initialize refs at the top of your component
1346
+ const lastTitleRefreshTimeRef = useRef ( Date . now ( ) ) ;
1347
+ const titleRefreshIntervalRef = useRef < NodeJS . Timeout | null > ( null ) ;
1348
+ const isRefreshingTitleRef = useRef ( false ) ;
1383
1349
1384
1350
const refreshChatTitle = useCallback ( async ( ) => {
1385
- if ( isEditingTitle || isRefreshingTitle ) return ;
1351
+ // Use ref for internal state check to avoid dependency cycle
1352
+ if ( isEditingTitle || isRefreshingTitleRef . current ) return ;
1386
1353
1387
1354
try {
1355
+ // Track refreshing state in ref
1356
+ isRefreshingTitleRef . current = true ;
1357
+ // Also update state for UI purposes
1388
1358
setIsRefreshingTitle ( true ) ;
1389
1359
1390
- const currentChat = await chat . getWorkspaceChats ( uuid as string ) ;
1360
+ const currentChat = await chat . getWorkspaceChats ( uuid ) ;
1391
1361
const updatedChat = currentChat ?. find ( ( c ) => c . id === chatId ) ;
1392
1362
1393
1363
if ( updatedChat ?. title && updatedChat . title !== title ) {
1394
1364
setTitle ( updatedChat . title ) ;
1395
1365
chat . updateChat ( chatId , { title : updatedChat . title } ) ;
1396
1366
}
1397
1367
1398
- setLastTitleRefreshTime ( Date . now ( ) ) ;
1368
+ // Update timestamp ref
1369
+ lastTitleRefreshTimeRef . current = Date . now ( ) ;
1399
1370
} catch ( error ) {
1400
1371
console . error ( 'Error refreshing chat title:' , error ) ;
1401
1372
} finally {
1373
+ isRefreshingTitleRef . current = false ;
1402
1374
setIsRefreshingTitle ( false ) ;
1403
1375
}
1404
- } , [ chat , chatId , uuid , title , isEditingTitle , isRefreshingTitle ] ) ;
1376
+ } , [ chat , chatId , uuid , title , isEditingTitle ] ) ; // Removed isRefreshingTitle from deps
1405
1377
1406
1378
useEffect ( ( ) => {
1407
1379
if ( ! chatId || ! uuid ) return ;
@@ -1415,7 +1387,7 @@ export const HiveChatView: React.FC = observer(() => {
1415
1387
1416
1388
titleRefreshIntervalRef . current = setInterval ( ( ) => {
1417
1389
if ( document . visibilityState === 'visible' && ! isEditingTitle ) {
1418
- if ( Date . now ( ) - lastTitleRefreshTime > 1000 ) {
1390
+ if ( Date . now ( ) - lastTitleRefreshTimeRef . current > 1000 ) {
1419
1391
refreshChatTitle ( ) ;
1420
1392
}
1421
1393
}
@@ -1430,18 +1402,14 @@ export const HiveChatView: React.FC = observer(() => {
1430
1402
titleRefreshIntervalRef . current = null ;
1431
1403
}
1432
1404
} ;
1433
- } , [ chatId , uuid , refreshChatTitle , isEditingTitle , lastTitleRefreshTime ] ) ;
1405
+ } , [ chatId , uuid , refreshChatTitle , isEditingTitle ] ) ;
1434
1406
1435
1407
useEffect ( ( ) => {
1436
- const refreshTitleOnFocus = async ( ) => {
1437
- try {
1438
- if ( document . visibilityState === 'visible' && ! isEditingTitle ) {
1439
- if ( Date . now ( ) - lastTitleRefreshTime > 1000 ) {
1440
- await refreshChatTitle ( ) ;
1441
- }
1408
+ const refreshTitleOnFocus = ( ) => {
1409
+ if ( document . visibilityState === 'visible' && ! isEditingTitle ) {
1410
+ if ( Date . now ( ) - lastTitleRefreshTimeRef . current > 1000 ) {
1411
+ refreshChatTitle ( ) ;
1442
1412
}
1443
- } catch ( error ) {
1444
- console . error ( 'Error refreshing chat title on focus:' , error ) ;
1445
1413
}
1446
1414
} ;
1447
1415
@@ -1452,7 +1420,7 @@ export const HiveChatView: React.FC = observer(() => {
1452
1420
window . removeEventListener ( 'visibilitychange' , refreshTitleOnFocus ) ;
1453
1421
window . removeEventListener ( 'focus' , refreshTitleOnFocus ) ;
1454
1422
} ;
1455
- } , [ refreshChatTitle , isEditingTitle , lastTitleRefreshTime ] ) ;
1423
+ } , [ refreshChatTitle , isEditingTitle ] ) ;
1456
1424
1457
1425
const handleMinimizeToggle = ( ) => {
1458
1426
setIsMinimized ( ( prev ) => {
0 commit comments