import React , { useEffect , useRef , CSSProperties } from 'react' ; import TdpClient , { ImageFragment , TdpClientEvent , } from 'teleport/lib/tdp/client' ; export default function TdpClientCanvas ( props ) { const { tdpCli , tdpCliOnImageFragment , tdpCliOnTdpError , tdpCliOnWsClose , tdpCliOnWsOpen , onKeyDown , onKeyUp , onMouseMove , onMouseDown , onMouseUp , onMouseWheelScroll , style , } = props ; const canvasRef = useRef < HTMLCanvasElement > ( null ) ; useEffect ( ( ) => { if ( tdpCli ) { const canvas = canvasRef . current ; canvas . tabIndex = - 1 ; canvas . style . outline = 'none' ; canvas . focus ( ) ; const ctx = canvas . getContext ( '2d' ) ; var buffer = [ ] ; const renderBuffer = ( ) => { if ( buffer . length ) { for ( let i = 0 ; i < buffer . length ; i ++ ) { tdpCliOnImageFragment ( ctx , buffer [ i ] ) ; } buffer = [ ] ; } requestAnimationFrame ( renderBuffer ) ; } ; requestAnimationFrame ( renderBuffer ) ; tdpCli . on ( TdpClientEvent . IMAGE_FRAGMENT , ( data ) => { buffer . push ( data ) ; } ) ; tdpCli . on ( TdpClientEvent . TDP_ERROR , ( err ) => { tdpCliOnTdpError ( err ) ; } ) ; tdpCli . on ( TdpClientEvent . WS_CLOSE , ( ) => { tdpCliOnWsClose ( ) ; } ) ; tdpCli . on ( TdpClientEvent . WS_OPEN , ( ) => { tdpCliOnWsOpen ( ) ; } ) ; const oncontextmenu = ( ) => false ; canvas . oncontextmenu = oncontextmenu ; const onmousemove = ( e ) => { onMouseMove ( tdpCli , canvas , e ) ; } ; canvas . onmousemove = onmousemove ; const onmousedown = ( e ) => { onMouseDown ( tdpCli , e ) ; } ; canvas . onmousedown = onmousedown ; const onmouseup = ( e ) => { onMouseUp ( tdpCli , e ) ; } ; canvas . onmouseup = onmouseup ; const onwheel = ( e ) => { e . preventDefault ( ) ; onMouseWheelScroll ( tdpCli , e ) ; } ; canvas . onwheel = onwheel ; const onkeydown = ( e ) => { e . preventDefault ( ) ; onKeyDown ( tdpCli , e ) ; } ; canvas . onkeydown = onkeydown ; const onkeyup = ( e ) => { e . preventDefault ( ) ; onKeyUp ( tdpCli , e ) ; } ; canvas . onkeyup = onkeyup ; tdpCli . init ( ) ; return ( ) => { tdpCli . nuke ( ) ; canvas . removeEventListener ( 'contextmenu' , oncontextmenu ) ; canvas . removeEventListener ( 'mousemove' , onmousemove ) ; canvas . removeEventListener ( 'mousedown' , onmousedown ) ; canvas . removeEventListener ( 'mouseup' , onmouseup ) ; canvas . removeEventListener ( 'keydown' , onkeydown ) ; canvas . removeEventListener ( 'keyup' , onkeyup ) ; canvas . removeEventListener ( 'wheel' , onwheel ) ; } ; } } , [ tdpCli ] ) ; return < canvas style = { { ... style } } ref = { canvasRef } / > ; } export type Props = { tdpCli : TdpClient | null ; tdpCliOnImageFragment : ( ctx : CanvasRenderingContext2D , data : ImageFragment ) => void ; tdpCliOnTdpError : ( err : Error ) => void ; tdpCliOnWsClose : ( ) => void ; tdpCliOnWsOpen : ( ) => void ; onKeyDown : ( cli : TdpClient , e : KeyboardEvent ) => void ; onKeyUp : ( cli : TdpClient , e : KeyboardEvent ) => void ; onMouseMove : ( cli : TdpClient , canvas : HTMLCanvasElement , e : MouseEvent ) => void ; onMouseDown : ( cli : TdpClient , e : MouseEvent ) => void ; onMouseUp : ( cli : TdpClient , e : MouseEvent ) => void ; onMouseWheelScroll : ( cli : TdpClient , e : WheelEvent ) => void ; style ? : CSSProperties ; } ;