1- import React , { useState , useRef , useEffect } from 'react' ;
1+ import React , { useState , useRef , useEffect , useCallback } from 'react' ;
22import { ConfirmDialog } from '../ui/ConfirmDialog' ;
33
44interface EcoreFileBoxProps {
@@ -19,7 +19,6 @@ interface EcoreFileBoxProps {
1919 createdAt ?: string ;
2020}
2121
22- // Modal styles
2322const modalOverlayStyle : React . CSSProperties = {
2423 position : 'fixed' ,
2524 top : 0 ,
@@ -110,7 +109,6 @@ const modalFooterStyle: React.CSSProperties = {
110109 fontStyle : 'italic' ,
111110} ;
112111
113- // Academic-style design with better typography and colors
114112const boxStyle : React . CSSProperties = {
115113 position : 'absolute' ,
116114 background : 'linear-gradient(145deg, #ffffff 0%, #f8f9fa 100%)' ,
@@ -165,15 +163,7 @@ const fileNameStyle: React.CSSProperties = {
165163 marginBottom : '8px' ,
166164} ;
167165
168- const fileInfoStyle : React . CSSProperties = {
169- fontSize : '12px' ,
170- color : '#6c757d' ,
171- textAlign : 'center' ,
172- marginTop : '8px' ,
173- fontStyle : 'italic' ,
174- fontFamily : '"Segoe UI", "Roboto", sans-serif' ,
175- lineHeight : '1.5' ,
176- } ;
166+ // ... existing code ...
177167
178168const tooltipStyle : React . CSSProperties = {
179169 position : 'absolute' ,
@@ -364,66 +354,57 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({
364354 } ;
365355
366356 const handleMouseDown = ( e : React . MouseEvent ) => {
367- if ( e . button !== 0 ) return ; // Only left mouse button
357+ if ( e . button !== 0 ) return ;
368358
369359 e . preventDefault ( ) ;
370360 e . stopPropagation ( ) ;
371361
372- // Add a small delay to prevent accidental dragging
373362 const rect = boxRef . current ?. getBoundingClientRect ( ) ;
374363 if ( rect ) {
375364 setDragOffset ( {
376365 x : e . clientX - rect . left ,
377366 y : e . clientY - rect . top ,
378367 } ) ;
379368
380- // Small delay to prevent accidental dragging
381369 setTimeout ( ( ) => {
382370 setIsDragging ( true ) ;
383371 } , 50 ) ;
384372 }
385373 } ;
386374
387- const handleMouseMove = ( e : MouseEvent ) => {
375+ const handleMouseMove = useCallback ( ( e : MouseEvent ) => {
388376 if ( ! isDragging || ! onPositionChange ) return ;
389377
390- // Prevent default to avoid text selection
391378 e . preventDefault ( ) ;
392379
393- // Calculate new position with smooth movement
394380 const newX = e . clientX - dragOffset . x ;
395381 const newY = e . clientY - dragOffset . y ;
396382
397- // Add bounds checking to prevent boxes from going off-screen
398383 const minX = 20 ;
399384 const minY = 20 ;
400- const maxX = window . innerWidth - 300 ; // Box width + margin
401- const maxY = window . innerHeight - 200 ; // Box height + margin
385+ const maxX = window . innerWidth - 300 ;
386+ const maxY = window . innerHeight - 200 ;
402387
403388 const boundedX = Math . max ( minX , Math . min ( maxX , newX ) ) ;
404389 const boundedY = Math . max ( minY , Math . min ( maxY , newY ) ) ;
405390
406- // Use smooth movement with easing
407391 const currentPosition = { x : boundedX , y : boundedY } ;
408392 onPositionChange ( id , currentPosition ) ;
409- } ;
393+ } , [ isDragging , onPositionChange , dragOffset , id ] ) ;
410394
411- const handleMouseUp = ( ) => {
395+ const handleMouseUp = useCallback ( ( ) => {
412396 if ( isDragging ) {
413397 setIsDragging ( false ) ;
414- // Reset cursor and user select
415398 document . body . style . cursor = '' ;
416399 document . body . style . userSelect = '' ;
417400 }
418- } ;
401+ } , [ isDragging ] ) ;
419402
420403 useEffect ( ( ) => {
421404 if ( isDragging ) {
422- // Use passive: false for better performance and responsiveness
423405 document . addEventListener ( 'mousemove' , handleMouseMove , { passive : false } ) ;
424406 document . addEventListener ( 'mouseup' , handleMouseUp ) ;
425407
426- // Add cursor style to body
427408 document . body . style . cursor = 'grabbing' ;
428409 document . body . style . userSelect = 'none' ;
429410
@@ -434,7 +415,7 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({
434415 document . body . style . userSelect = '' ;
435416 } ;
436417 }
437- } , [ isDragging , dragOffset , onPositionChange , id ] ) ;
418+ } , [ isDragging , handleMouseMove , handleMouseUp ] ) ;
438419
439420 const handleFileNameDoubleClick = ( e : React . MouseEvent ) => {
440421 e . stopPropagation ( ) ;
@@ -466,16 +447,7 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({
466447 handleSaveEdit ( ) ;
467448 } ;
468449
469- const getFileSize = ( ) => {
470- const size = fileContent . length ;
471- if ( size < 1024 ) return `${ size } chars` ;
472- if ( size < 1024 * 1024 ) return `${ ( size / 1024 ) . toFixed ( 1 ) } KB` ;
473- return `${ ( size / ( 1024 * 1024 ) ) . toFixed ( 1 ) } MB` ;
474- } ;
475-
476- const getFileType = ( ) => {
477- return fileName . endsWith ( '.ecore' ) ? 'ECORE Model' : 'Model File' ;
478- } ;
450+ // ... existing code ...
479451
480452 const formatDate = ( dateString : string ) => {
481453 try {
@@ -487,21 +459,17 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({
487459 } ;
488460
489461 const getAuthorName = ( ) => {
490- // Try to extract author from file content
491462 try {
492- // Look for common author patterns in ECORE files
493463 const authorMatch = fileContent . match ( / < e A n n o t a t i o n s .* ?s o u r c e = " h t t p : \/ \/ w w w \. e c l i p s e \. o r g \/ e m f \/ 2 0 0 2 \/ G e n M o d e l " .* ?< d e t a i l s .* ?k e y = " d o c u m e n t a t i o n " .* ?v a l u e = " ( [ ^ " ] * ) " / ) ;
494464 if ( authorMatch && authorMatch [ 1 ] ) {
495465 return authorMatch [ 1 ] . trim ( ) ;
496466 }
497467
498- // Look for other author patterns
499468 const otherAuthorMatch = fileContent . match ( / a u t h o r [ " \s ] * [: = ] [ " \s ] * ( [ ^ " \n \r ] + ) / i) ;
500469 if ( otherAuthorMatch && otherAuthorMatch [ 1 ] ) {
501470 return otherAuthorMatch [ 1 ] . trim ( ) ;
502471 }
503472
504- // Default author if none found
505473 return 'Unknown Author' ;
506474 } catch ( error ) {
507475 return 'Unknown Author' ;
@@ -520,7 +488,7 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({
520488 left : position . x ,
521489 top : position . y ,
522490 transform : isSelected && ! isDragging ? 'scale(1.02)' : 'scale(1)' ,
523- display : isExpanded ? 'none' : 'block' , // Hide box when expanded
491+ display : isExpanded ? 'none' : 'block' ,
524492 } }
525493 onClick = { handleClick }
526494 onDoubleClick = { handleDoubleClick }
@@ -688,7 +656,7 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({
688656 onCancel = { cancelDelete }
689657 />
690658
691- { /* Tooltip for file content preview */ }
659+
692660 { isHovered && (
693661 < div style = { {
694662 ...tooltipStyle ,
@@ -714,7 +682,6 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({
714682 </ div >
715683 ) }
716684
717- { /* Description Modal */ }
718685 { showDescriptionModal && (
719686 < div style = { modalOverlayStyle } onClick = { handleModalOverlayClick } >
720687 < div style = { modalContentStyle } >
@@ -749,7 +716,6 @@ export const EcoreFileBox: React.FC<EcoreFileBoxProps> = ({
749716 </ div >
750717 ) }
751718
752- { /* Keywords Modal */ }
753719 { showKeywordsModal && (
754720 < div style = { modalOverlayStyle } onClick = { handleKeywordsModalOverlayClick } >
755721 < div style = { modalContentStyle } >
0 commit comments