2023-06-22 16:43:33 +10:00
|
|
|
import { MouseEventHandler, useEffect, useRef } from 'react'
|
2023-03-06 20:13:34 +11:00
|
|
|
import { PanelHeader } from '../components/PanelHeader'
|
2023-06-21 09:15:02 +10:00
|
|
|
import { v4 as uuidv4 } from 'uuid'
|
2023-06-22 16:43:33 +10:00
|
|
|
import { useStore } from '../useStore'
|
|
|
|
import { throttle } from '../lib/utils'
|
2023-08-02 15:41:59 +10:00
|
|
|
import { EngineCommand } from '../lang/std/engineConnection'
|
2023-03-06 20:13:34 +11:00
|
|
|
|
|
|
|
export const Stream = () => {
|
|
|
|
const videoRef = useRef<HTMLVideoElement>(null)
|
2023-06-22 16:43:33 +10:00
|
|
|
const cmdId = useRef('')
|
|
|
|
const { mediaStream, engineCommandManager } = useStore((s) => ({
|
|
|
|
mediaStream: s.mediaStream,
|
|
|
|
engineCommandManager: s.engineCommandManager,
|
|
|
|
}))
|
2023-03-06 20:13:34 +11:00
|
|
|
|
|
|
|
useEffect(() => {
|
2023-03-07 15:45:59 +11:00
|
|
|
if (
|
|
|
|
typeof window === 'undefined' ||
|
|
|
|
typeof RTCPeerConnection === 'undefined'
|
|
|
|
)
|
|
|
|
return
|
2023-06-22 16:43:33 +10:00
|
|
|
if (!videoRef.current) return
|
|
|
|
if (!mediaStream) return
|
|
|
|
videoRef.current.srcObject = mediaStream
|
|
|
|
}, [mediaStream, engineCommandManager])
|
|
|
|
|
|
|
|
const file_id = uuidv4()
|
|
|
|
|
2023-08-02 15:41:59 +10:00
|
|
|
const debounceSocketSend = throttle<EngineCommand>((message) => {
|
2023-06-22 16:43:33 +10:00
|
|
|
engineCommandManager?.sendSceneCommand(message)
|
2023-06-23 09:56:37 +10:00
|
|
|
}, 16)
|
2023-06-22 16:43:33 +10:00
|
|
|
const handleMouseMove: MouseEventHandler<HTMLVideoElement> = ({
|
|
|
|
clientX,
|
|
|
|
clientY,
|
2023-07-20 14:08:32 -04:00
|
|
|
ctrlKey,
|
2023-06-22 16:43:33 +10:00
|
|
|
}) => {
|
|
|
|
if (!videoRef.current) return
|
|
|
|
if (!cmdId.current) return
|
|
|
|
const { left, top } = videoRef.current.getBoundingClientRect()
|
|
|
|
const x = clientX - left
|
|
|
|
const y = clientY - top
|
2023-07-20 14:08:32 -04:00
|
|
|
const interaction = ctrlKey ? 'pan' : 'rotate'
|
|
|
|
|
2023-06-22 16:43:33 +10:00
|
|
|
debounceSocketSend({
|
2023-08-02 15:41:59 +10:00
|
|
|
type: 'modeling_cmd_req',
|
2023-06-22 16:43:33 +10:00
|
|
|
cmd: {
|
2023-08-02 15:41:59 +10:00
|
|
|
type: 'camera_drag_move',
|
|
|
|
interaction,
|
2023-08-03 07:28:06 +10:00
|
|
|
window: { x, y },
|
2023-06-22 16:43:33 +10:00
|
|
|
},
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
file_id: file_id,
|
2023-03-06 20:13:34 +11:00
|
|
|
})
|
2023-06-22 16:43:33 +10:00
|
|
|
}
|
2023-03-06 20:13:34 +11:00
|
|
|
|
2023-06-22 16:43:33 +10:00
|
|
|
const handleMouseDown: MouseEventHandler<HTMLVideoElement> = ({
|
|
|
|
clientX,
|
|
|
|
clientY,
|
2023-07-20 14:08:32 -04:00
|
|
|
ctrlKey,
|
2023-06-22 16:43:33 +10:00
|
|
|
}) => {
|
|
|
|
if (!videoRef.current) return
|
|
|
|
const { left, top } = videoRef.current.getBoundingClientRect()
|
|
|
|
const x = clientX - left
|
|
|
|
const y = clientY - top
|
|
|
|
console.log('click', x, y)
|
|
|
|
|
|
|
|
const newId = uuidv4()
|
|
|
|
cmdId.current = newId
|
|
|
|
|
2023-07-20 14:08:32 -04:00
|
|
|
const interaction = ctrlKey ? 'pan' : 'rotate'
|
|
|
|
|
2023-06-22 16:43:33 +10:00
|
|
|
engineCommandManager?.sendSceneCommand({
|
2023-08-02 15:41:59 +10:00
|
|
|
type: 'modeling_cmd_req',
|
2023-06-22 16:43:33 +10:00
|
|
|
cmd: {
|
2023-08-02 15:41:59 +10:00
|
|
|
type: 'camera_drag_start',
|
|
|
|
interaction,
|
2023-08-03 07:28:06 +10:00
|
|
|
window: { x, y },
|
2023-06-22 16:43:33 +10:00
|
|
|
},
|
|
|
|
cmd_id: newId,
|
|
|
|
file_id,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
const handleMouseUp: MouseEventHandler<HTMLVideoElement> = ({
|
|
|
|
clientX,
|
|
|
|
clientY,
|
2023-07-20 14:08:32 -04:00
|
|
|
ctrlKey,
|
2023-06-22 16:43:33 +10:00
|
|
|
}) => {
|
|
|
|
if (!videoRef.current) return
|
|
|
|
const { left, top } = videoRef.current.getBoundingClientRect()
|
|
|
|
const x = clientX - left
|
|
|
|
const y = clientY - top
|
|
|
|
|
|
|
|
if (cmdId.current == null) {
|
|
|
|
return
|
2023-06-21 09:15:02 +10:00
|
|
|
}
|
|
|
|
|
2023-07-20 14:08:32 -04:00
|
|
|
const interaction = ctrlKey ? 'pan' : 'rotate'
|
|
|
|
|
2023-06-22 16:43:33 +10:00
|
|
|
engineCommandManager?.sendSceneCommand({
|
2023-08-02 15:41:59 +10:00
|
|
|
type: 'modeling_cmd_req',
|
2023-06-22 16:43:33 +10:00
|
|
|
cmd: {
|
2023-08-02 15:41:59 +10:00
|
|
|
type: 'camera_drag_end',
|
|
|
|
interaction,
|
2023-08-03 07:28:06 +10:00
|
|
|
window: { x, y },
|
2023-06-22 16:43:33 +10:00
|
|
|
},
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
file_id: file_id,
|
|
|
|
})
|
|
|
|
cmdId.current = ''
|
|
|
|
}
|
2023-03-06 20:13:34 +11:00
|
|
|
|
|
|
|
return (
|
2023-07-25 10:40:26 -04:00
|
|
|
<div id="stream">
|
2023-03-06 20:13:34 +11:00
|
|
|
<PanelHeader title="Stream" />
|
2023-06-22 16:43:33 +10:00
|
|
|
<video
|
|
|
|
ref={videoRef}
|
|
|
|
muted
|
|
|
|
autoPlay
|
|
|
|
controls={false}
|
|
|
|
onMouseMove={handleMouseMove}
|
|
|
|
onMouseDown={handleMouseDown}
|
|
|
|
onMouseUp={handleMouseUp}
|
2023-06-29 20:11:51 +10:00
|
|
|
onMouseLeave={handleMouseUp}
|
2023-07-20 14:08:32 -04:00
|
|
|
onContextMenu={(e) => e.preventDefault()}
|
|
|
|
onContextMenuCapture={(e) => e.preventDefault()}
|
2023-06-22 16:43:33 +10:00
|
|
|
/>
|
2023-03-06 20:13:34 +11:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|