@@ -21,9 +21,6 @@ interface MessageListProps {
2121interface ProcessedMessageProps {
2222 messageContent : string ;
2323 index : number ;
24- modifierPressed : boolean ;
25- urlRegex : RegExp ;
26- handleClick : ( e : React . MouseEvent < HTMLAnchorElement > , url : string ) => void ;
2724}
2825
2926export default function MessageList ( { messages} : MessageListProps ) {
@@ -46,20 +43,14 @@ export default function MessageList({messages}: MessageListProps) {
4643 return scrollTop + clientHeight >= scrollHeight - 10 ; // 10px tolerance
4744 } , [ ] ) ;
4845
49- // Regex to find URLs
50- // https://stackoverflow.com/a/17773849
51- const urlRegex = useMemo < RegExp > ( ( ) => / ( h t t p s ? : \/ \/ (?: w w w \. | (? ! w w w ) ) [ a - z A - Z 0 - 9 ] [ a - z A - Z 0 - 9 - ] + [ a - z A - Z 0 - 9 ] \. [ ^ \s ] { 2 , } | w w w \. [ a - z A - Z 0 - 9 ] [ a - z A - Z 0 - 9 - ] + [ a - z A - Z 0 - 9 ] \. [ ^ \s ] { 2 , } | h t t p s ? : \/ \/ (?: w w w \. | (? ! w w w ) ) [ a - z A - Z 0 - 9 ] + \. [ ^ \s ] { 2 , } | w w w \. [ a - z A - Z 0 - 9 ] + \. [ ^ \s ] { 2 , } ) / g, [ ] ) ;
52-
53- const [ modifierPressed , setModifierPressed ] = useState ( false ) ;
54-
5546 // Track Ctrl (Windows/Linux) or Cmd (Mac) key state
5647 // This is so that underline is only visible when hover + cmd/ctrl
5748 useEffect ( ( ) => {
5849 const handleKeyDown = ( e : KeyboardEvent ) => {
59- if ( e . ctrlKey || e . metaKey ) setModifierPressed ( true ) ;
50+ if ( e . ctrlKey || e . metaKey ) document . documentElement . classList . add ( 'modifier-pressed' ) ;
6051 } ;
6152 const handleKeyUp = ( e : KeyboardEvent ) => {
62- if ( ! e . ctrlKey && ! e . metaKey ) setModifierPressed ( false ) ;
53+ if ( ! e . ctrlKey && ! e . metaKey ) document . documentElement . classList . remove ( 'modifier-pressed' ) ;
6354 } ;
6455
6556 window . addEventListener ( "keydown" , handleKeyDown ) ;
@@ -68,6 +59,8 @@ export default function MessageList({messages}: MessageListProps) {
6859 return ( ) => {
6960 window . removeEventListener ( "keydown" , handleKeyDown ) ;
7061 window . removeEventListener ( "keyup" , handleKeyUp ) ;
62+ document . documentElement . classList . remove ( 'modifier-pressed' ) ;
63+
7164 } ;
7265 } , [ ] ) ;
7366
@@ -125,14 +118,6 @@ export default function MessageList({messages}: MessageListProps) {
125118 lastScrollHeightRef . current = currentScrollHeight ;
126119 } , [ messages ] ) ;
127120
128- const handleClick = useCallback ( ( ) => ( e : React . MouseEvent < HTMLAnchorElement > , url : string ) => {
129- if ( e . metaKey || e . ctrlKey ) {
130- window . open ( url , "_blank" ) ;
131- } else {
132- e . preventDefault ( ) ; // disable normal click to emulate terminal behaviour
133- }
134- } , [ ] ) ;
135-
136121 // If no messages, show a placeholder
137122 if ( messages . length === 0 ) {
138123 return (
@@ -171,9 +156,6 @@ export default function MessageList({messages}: MessageListProps) {
171156 < ProcessedMessage
172157 messageContent = { message . content }
173158 index = { index }
174- modifierPressed = { modifierPressed }
175- urlRegex = { urlRegex }
176- handleClick = { handleClick }
177159 />
178160 ) }
179161 </ div >
@@ -207,29 +189,37 @@ const LoadingDots = () => (
207189const ProcessedMessage = React . memo ( function ProcessedMessage ( {
208190 messageContent,
209191 index,
210- modifierPressed,
211- urlRegex,
212- handleClick
213192 } : ProcessedMessageProps ) {
193+ // Regex to find URLs
194+ // https://stackoverflow.com/a/17773849
195+ const urlRegex = useMemo < RegExp > ( ( ) => / ( h t t p s ? : \/ \/ (?: w w w \. | (? ! w w w ) ) [ a - z A - Z 0 - 9 ] [ a - z A - Z 0 - 9 - ] + [ a - z A - Z 0 - 9 ] \. [ ^ \s ] { 2 , } | w w w \. [ a - z A - Z 0 - 9 ] [ a - z A - Z 0 - 9 - ] + [ a - z A - Z 0 - 9 ] \. [ ^ \s ] { 2 , } | h t t p s ? : \/ \/ (?: w w w \. | (? ! w w w ) ) [ a - z A - Z 0 - 9 ] + \. [ ^ \s ] { 2 , } | w w w \. [ a - z A - Z 0 - 9 ] + \. [ ^ \s ] { 2 , } ) / g, [ ] ) ;
196+
197+ const handleClick = ( e : React . MouseEvent < HTMLAnchorElement > , url : string ) => {
198+ if ( e . metaKey || e . ctrlKey ) {
199+ window . open ( url , "_blank" ) ;
200+ } else {
201+ e . preventDefault ( ) ; // disable normal click to emulate terminal behaviour
202+ }
203+ }
204+
214205 const linkedContent = useMemo ( ( ) => {
215206 return messageContent . split ( urlRegex ) . map ( ( content , idx ) => {
207+ console . log ( content )
216208 if ( urlRegex . test ( content ) ) {
217209 return (
218210 < a
219211 key = { `${ index } -${ idx } ` }
220212 href = { content }
221213 onClick = { ( e ) => handleClick ( e , content ) }
222- className = { `${
223- modifierPressed ? "hover:underline cursor-pointer" : "cursor-default"
224- } `}
214+ className = "cursor-default [.modifier-pressed_&]:hover:underline [.modifier-pressed_&]:hover:cursor-pointer"
225215 >
226216 { content }
227217 </ a >
228218 ) ;
229219 }
230220 return < span key = { `${ index } -${ idx } ` } > { content } </ span > ;
231221 } ) ;
232- } , [ handleClick , index , messageContent , modifierPressed , urlRegex ] ) ;
222+ } , [ index , messageContent , urlRegex ] ) ;
233223
234224 return < > { linkedContent } </ > ;
235225} ) ;
0 commit comments