2023-08-08 18:30:26 -04:00
|
|
|
import {
|
|
|
|
MouseEventHandler,
|
|
|
|
WheelEventHandler,
|
|
|
|
useEffect,
|
|
|
|
useRef,
|
|
|
|
useState,
|
|
|
|
} from 'react'
|
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'
|
2024-01-12 09:14:37 +11:00
|
|
|
import { getNormalisedCoordinates, throttle } from '../lib/utils'
|
2023-08-10 16:22:45 -04:00
|
|
|
import Loading from './Loading'
|
2023-09-08 10:13:35 -04:00
|
|
|
import { cameraMouseDragGuards } from 'lib/cameraControls'
|
|
|
|
import { useGlobalStateContext } from 'hooks/useGlobalStateContext'
|
|
|
|
import { CameraDragInteractionType_type } from '@kittycad/lib/dist/types/src/models'
|
2023-09-13 08:36:47 +10:00
|
|
|
import { Models } from '@kittycad/lib'
|
2023-09-14 09:34:37 -04:00
|
|
|
import { getNodeFromPath } from 'lang/queryAst'
|
2023-11-07 14:29:50 +11:00
|
|
|
import { VariableDeclarator, recast, CallExpression } from 'lang/wasm'
|
2023-09-25 19:49:53 -07:00
|
|
|
import { engineCommandManager } from '../lang/std/engineConnection'
|
2023-10-11 13:36:54 +11:00
|
|
|
import { useModelingContext } from 'hooks/useModelingContext'
|
|
|
|
import { kclManager, useKclContext } from 'lang/KclSinglton'
|
2023-10-14 03:47:46 +11:00
|
|
|
import { changeSketchArguments } from 'lang/std/sketch'
|
2023-03-06 20:13:34 +11:00
|
|
|
|
2023-08-06 21:29:26 -04:00
|
|
|
export const Stream = ({ className = '' }) => {
|
2023-08-10 16:22:45 -04:00
|
|
|
const [isLoading, setIsLoading] = useState(true)
|
2023-09-06 01:32:53 -04:00
|
|
|
const [clickCoords, setClickCoords] = useState<{ x: number; y: number }>()
|
2023-03-06 20:13:34 +11:00
|
|
|
const videoRef = useRef<HTMLVideoElement>(null)
|
2023-08-06 21:29:26 -04:00
|
|
|
const {
|
|
|
|
mediaStream,
|
2023-09-08 10:13:35 -04:00
|
|
|
setButtonDownInStream,
|
2023-08-09 20:49:10 +10:00
|
|
|
didDragInStream,
|
|
|
|
setDidDragInStream,
|
|
|
|
streamDimensions,
|
2023-08-06 21:29:26 -04:00
|
|
|
} = useStore((s) => ({
|
2023-06-22 16:43:33 +10:00
|
|
|
mediaStream: s.mediaStream,
|
2023-09-08 10:13:35 -04:00
|
|
|
setButtonDownInStream: s.setButtonDownInStream,
|
2023-08-09 20:49:10 +10:00
|
|
|
didDragInStream: s.didDragInStream,
|
|
|
|
setDidDragInStream: s.setDidDragInStream,
|
|
|
|
streamDimensions: s.streamDimensions,
|
2023-06-22 16:43:33 +10:00
|
|
|
}))
|
2023-10-11 13:36:54 +11:00
|
|
|
const { settings } = useGlobalStateContext()
|
|
|
|
const cameraControls = settings?.context?.cameraControls
|
|
|
|
const { send, state, context } = useModelingContext()
|
|
|
|
const { isExecuting } = useKclContext()
|
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
|
2023-09-25 19:49:53 -07:00
|
|
|
}, [mediaStream])
|
2023-03-06 20:13:34 +11:00
|
|
|
|
2023-09-08 10:13:35 -04:00
|
|
|
const handleMouseDown: MouseEventHandler<HTMLVideoElement> = (e) => {
|
2023-06-22 16:43:33 +10:00
|
|
|
if (!videoRef.current) return
|
2023-08-09 20:49:10 +10:00
|
|
|
const { x, y } = getNormalisedCoordinates({
|
2023-09-08 10:13:35 -04:00
|
|
|
clientX: e.clientX,
|
|
|
|
clientY: e.clientY,
|
2023-08-09 20:49:10 +10:00
|
|
|
el: videoRef.current,
|
|
|
|
...streamDimensions,
|
|
|
|
})
|
2023-06-22 16:43:33 +10:00
|
|
|
|
|
|
|
const newId = uuidv4()
|
|
|
|
|
2023-09-08 10:13:35 -04:00
|
|
|
const interactionGuards = cameraMouseDragGuards[cameraControls]
|
2023-09-13 08:36:47 +10:00
|
|
|
let interaction: CameraDragInteractionType_type = 'rotate'
|
2023-09-08 10:13:35 -04:00
|
|
|
|
2023-09-11 16:21:23 -04:00
|
|
|
if (
|
|
|
|
interactionGuards.pan.callback(e) ||
|
|
|
|
interactionGuards.pan.lenientDragStartButton === e.button
|
|
|
|
) {
|
2023-09-08 10:13:35 -04:00
|
|
|
interaction = 'pan'
|
2023-09-11 16:21:23 -04:00
|
|
|
} else if (
|
|
|
|
interactionGuards.rotate.callback(e) ||
|
|
|
|
interactionGuards.rotate.lenientDragStartButton === e.button
|
|
|
|
) {
|
2023-09-08 10:13:35 -04:00
|
|
|
interaction = 'rotate'
|
2023-09-11 16:21:23 -04:00
|
|
|
} else if (
|
|
|
|
interactionGuards.zoom.dragCallback(e) ||
|
|
|
|
interactionGuards.zoom.lenientDragStartButton === e.button
|
|
|
|
) {
|
2023-09-08 10:13:35 -04:00
|
|
|
interaction = 'zoom'
|
|
|
|
}
|
2023-07-20 14:08:32 -04:00
|
|
|
|
2023-10-11 13:36:54 +11:00
|
|
|
if (state.matches('Sketch.Move Tool')) {
|
2023-10-14 03:47:46 +11:00
|
|
|
if (
|
|
|
|
state.matches('Sketch.Move Tool.No move') ||
|
|
|
|
state.matches('Sketch.Move Tool.Move with execute')
|
|
|
|
) {
|
|
|
|
return
|
|
|
|
}
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand({
|
2023-09-13 08:36:47 +10:00
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
cmd: {
|
|
|
|
type: 'handle_mouse_drag_start',
|
|
|
|
window: { x, y },
|
|
|
|
},
|
|
|
|
cmd_id: newId,
|
|
|
|
})
|
2023-10-11 13:36:54 +11:00
|
|
|
} else if (!state.matches('Sketch.Line Tool')) {
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand({
|
2023-09-13 08:36:47 +10:00
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
cmd: {
|
|
|
|
type: 'camera_drag_start',
|
|
|
|
interaction,
|
|
|
|
window: { x, y },
|
|
|
|
},
|
|
|
|
cmd_id: newId,
|
|
|
|
})
|
|
|
|
}
|
2023-08-06 21:29:26 -04:00
|
|
|
|
2023-09-08 10:13:35 -04:00
|
|
|
setButtonDownInStream(e.button)
|
2023-09-06 01:32:53 -04:00
|
|
|
setClickCoords({ x, y })
|
2023-06-22 16:43:33 +10:00
|
|
|
}
|
2023-08-06 21:29:26 -04:00
|
|
|
|
2024-01-12 09:14:37 +11:00
|
|
|
const fps = 60
|
|
|
|
const handleScroll: WheelEventHandler<HTMLVideoElement> = throttle((e) => {
|
2023-09-08 10:13:35 -04:00
|
|
|
if (!cameraMouseDragGuards[cameraControls].zoom.scrollCallback(e)) return
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand({
|
2023-08-08 18:30:26 -04:00
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
cmd: {
|
2023-08-21 10:52:41 -04:00
|
|
|
type: 'default_camera_zoom',
|
|
|
|
magnitude: e.deltaY * 0.4,
|
2023-08-08 18:30:26 -04:00
|
|
|
},
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
})
|
2024-01-12 09:14:37 +11:00
|
|
|
}, Math.round(1000 / fps))
|
2023-08-08 18:30:26 -04:00
|
|
|
|
2023-06-22 16:43:33 +10:00
|
|
|
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
|
2023-09-13 08:36:47 +10:00
|
|
|
setButtonDownInStream(undefined)
|
2023-08-09 20:49:10 +10:00
|
|
|
const { x, y } = getNormalisedCoordinates({
|
|
|
|
clientX,
|
|
|
|
clientY,
|
|
|
|
el: videoRef.current,
|
|
|
|
...streamDimensions,
|
|
|
|
})
|
2023-06-22 16:43:33 +10:00
|
|
|
|
2023-08-06 21:29:26 -04:00
|
|
|
const newCmdId = uuidv4()
|
2023-07-20 14:08:32 -04:00
|
|
|
const interaction = ctrlKey ? 'pan' : 'rotate'
|
|
|
|
|
2023-09-13 08:36:47 +10:00
|
|
|
const command: Models['WebSocketRequest_type'] = {
|
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
|
|
|
},
|
2023-08-06 21:29:26 -04:00
|
|
|
cmd_id: newCmdId,
|
2023-09-13 08:36:47 +10:00
|
|
|
}
|
2023-08-06 21:29:26 -04:00
|
|
|
|
2023-10-11 13:36:54 +11:00
|
|
|
if (!didDragInStream && state.matches('Sketch no face')) {
|
2023-09-13 08:36:47 +10:00
|
|
|
command.cmd = {
|
|
|
|
type: 'select_with_point',
|
|
|
|
selection_type: 'add',
|
|
|
|
selected_at_window: { x, y },
|
|
|
|
}
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand(command)
|
2023-10-11 13:36:54 +11:00
|
|
|
} else if (!didDragInStream && state.matches('Sketch.Line Tool')) {
|
2023-09-13 08:36:47 +10:00
|
|
|
command.cmd = {
|
|
|
|
type: 'mouse_click',
|
|
|
|
window: { x, y },
|
|
|
|
}
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand(command).then(async (resp) => {
|
2023-10-11 13:36:54 +11:00
|
|
|
const entities_modified = resp?.data?.data?.entities_modified
|
|
|
|
if (!entities_modified) return
|
|
|
|
if (state.matches('Sketch.Line Tool.No Points')) {
|
|
|
|
send('Add point')
|
|
|
|
} else if (state.matches('Sketch.Line Tool.Point Added')) {
|
|
|
|
const curve = await engineCommandManager.sendSceneCommand({
|
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
cmd: {
|
|
|
|
type: 'curve_get_control_points',
|
|
|
|
curve_id: entities_modified[0],
|
|
|
|
},
|
|
|
|
})
|
|
|
|
const coords: { x: number; y: number }[] =
|
|
|
|
curve.data.data.control_points
|
|
|
|
// We need the normal for the plane we are on.
|
|
|
|
const plane = await engineCommandManager.sendSceneCommand({
|
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
cmd: {
|
|
|
|
type: 'get_sketch_mode_plane',
|
|
|
|
},
|
|
|
|
})
|
|
|
|
const z_axis = plane.data.data.z_axis
|
|
|
|
|
|
|
|
// Get the current axis.
|
|
|
|
let currentAxis: 'xy' | 'xz' | 'yz' | '-xy' | '-xz' | '-yz' | null =
|
|
|
|
null
|
|
|
|
if (context.sketchPlaneId === kclManager.getPlaneId('xy')) {
|
|
|
|
if (z_axis.z === -1) {
|
|
|
|
currentAxis = '-xy'
|
|
|
|
} else {
|
|
|
|
currentAxis = 'xy'
|
|
|
|
}
|
|
|
|
} else if (context.sketchPlaneId === kclManager.getPlaneId('yz')) {
|
|
|
|
if (z_axis.x === -1) {
|
|
|
|
currentAxis = '-yz'
|
|
|
|
} else {
|
|
|
|
currentAxis = 'yz'
|
|
|
|
}
|
|
|
|
} else if (context.sketchPlaneId === kclManager.getPlaneId('xz')) {
|
|
|
|
if (z_axis.y === -1) {
|
|
|
|
currentAxis = '-xz'
|
|
|
|
} else {
|
|
|
|
currentAxis = 'xz'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-14 03:47:46 +11:00
|
|
|
send({
|
|
|
|
type: 'Add point',
|
|
|
|
data: {
|
|
|
|
coords,
|
|
|
|
axis: currentAxis,
|
|
|
|
segmentId: entities_modified[0],
|
|
|
|
},
|
|
|
|
})
|
2023-10-11 13:36:54 +11:00
|
|
|
} else if (state.matches('Sketch.Line Tool.Segment Added')) {
|
|
|
|
const curve = await engineCommandManager.sendSceneCommand({
|
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
cmd: {
|
|
|
|
type: 'curve_get_control_points',
|
|
|
|
curve_id: entities_modified[0],
|
|
|
|
},
|
|
|
|
})
|
|
|
|
const coords: { x: number; y: number }[] =
|
|
|
|
curve.data.data.control_points
|
2023-10-14 03:47:46 +11:00
|
|
|
send({
|
|
|
|
type: 'Add point',
|
|
|
|
data: { coords, axis: null, segmentId: entities_modified[0] },
|
|
|
|
})
|
2023-10-11 13:36:54 +11:00
|
|
|
}
|
|
|
|
})
|
2023-09-13 08:36:47 +10:00
|
|
|
} else if (
|
2023-10-11 13:36:54 +11:00
|
|
|
!didDragInStream &&
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
(state.matches('Sketch.SketchIdle') || state.matches('idle'))
|
2023-09-13 08:36:47 +10:00
|
|
|
) {
|
2023-10-11 13:36:54 +11:00
|
|
|
command.cmd = {
|
|
|
|
type: 'select_with_point',
|
|
|
|
selected_at_window: { x, y },
|
|
|
|
selection_type: 'add',
|
|
|
|
}
|
Command bar: add extrude command, nonlinear editing, etc (#1204)
* Tweak toaster look and feel
* Add icons, tweak plus icon names
* Rename commandBarMeta to commandBarConfig
* Refactor command bar, add support for icons
* Create a tailwind plugin for aria-pressed button state
* Remove overlay from behind command bar
* Clean up toolbar
* Button and other style tweaks
* Icon tweaks follow-up: make old icons work with new sizing
* Delete unused static icons
* More CSS tweaks
* Small CSS tweak to project sidebar
* Add command bar E2E test
* fumpt
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* fix typo in a comment
* Fix icon padding (built version only)
* Update onboarding and warning banner icons padding
* Misc minor style fixes
* Get Extrude opening and canceling from command bar
* Iconography tweaks
* Get extrude kind of working
* Refactor command bar config types and organization
* Move command bar configs to be co-located with each other
* Start building a state machine for the command bar
* Start converting command bar to state machine
* Add support for multiple args, confirmation step
* Submission behavior, hotkeys, code organization
* Add new test for extruding from command bar
* Polish step back and selection hotkeys, CSS tweaks
* Loading style tweaks
* Validate selection inputs, polish UX of args re-editing
* Prevent submission with multiple selection on singlular arg
* Remove stray console logs
* Tweak test, CSS nit, remove extrude "result" argument
* Fix linting warnings
* Show Ctrl+/ instead of ⌘K on all platforms but Mac
* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)
* Add "Enter sketch" to command bar
* fix command bar test
* Fix flaky cmd bar extrude test by waiting for engine select response
* Cover both button labels '⌘K' and 'Ctrl+/' in test
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-12-13 12:49:01 -05:00
|
|
|
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand(command)
|
2023-10-11 13:36:54 +11:00
|
|
|
} else if (!didDragInStream && state.matches('Sketch.Move Tool')) {
|
|
|
|
command.cmd = {
|
|
|
|
type: 'select_with_point',
|
|
|
|
selected_at_window: { x, y },
|
|
|
|
selection_type: 'add',
|
|
|
|
}
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand(command)
|
2023-10-11 13:36:54 +11:00
|
|
|
} else if (didDragInStream && state.matches('Sketch.Move Tool')) {
|
2023-09-13 08:36:47 +10:00
|
|
|
command.cmd = {
|
|
|
|
type: 'handle_mouse_drag_end',
|
|
|
|
window: { x, y },
|
|
|
|
}
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand(command).then(async () => {
|
2023-10-11 13:36:54 +11:00
|
|
|
if (!context.sketchPathToNode) return
|
2023-11-01 07:39:31 -04:00
|
|
|
getNodeFromPath<VariableDeclarator>(
|
2023-10-11 13:36:54 +11:00
|
|
|
kclManager.ast,
|
|
|
|
context.sketchPathToNode,
|
|
|
|
'VariableDeclarator'
|
2023-11-01 07:39:31 -04:00
|
|
|
)
|
2023-10-05 14:27:48 -07:00
|
|
|
// Get the current plane string for plane we are on.
|
|
|
|
let currentPlaneString = ''
|
2023-10-11 13:36:54 +11:00
|
|
|
if (context.sketchPlaneId === kclManager.getPlaneId('xy')) {
|
2023-10-05 14:27:48 -07:00
|
|
|
currentPlaneString = 'XY'
|
2023-10-11 13:36:54 +11:00
|
|
|
} else if (context.sketchPlaneId === kclManager.getPlaneId('yz')) {
|
2023-10-05 14:27:48 -07:00
|
|
|
currentPlaneString = 'YZ'
|
2023-10-11 13:36:54 +11:00
|
|
|
} else if (context.sketchPlaneId === kclManager.getPlaneId('xz')) {
|
2023-10-05 14:27:48 -07:00
|
|
|
currentPlaneString = 'XZ'
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not supporting editing/moving lines on a non-default plane.
|
|
|
|
// Eventually we can support this but for now we will just throw an
|
|
|
|
// error.
|
|
|
|
if (currentPlaneString === '') return
|
|
|
|
|
2023-10-14 03:47:46 +11:00
|
|
|
const pathInfo = await engineCommandManager.sendSceneCommand({
|
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
cmd: {
|
|
|
|
type: 'path_get_info',
|
|
|
|
path_id: context.sketchEnginePathId,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
const segmentsWithMappings = (
|
|
|
|
pathInfo?.data?.data?.segments as { command_id: string }[]
|
|
|
|
)
|
|
|
|
.filter(({ command_id }) => {
|
|
|
|
return command_id && engineCommandManager.artifactMap[command_id]
|
|
|
|
})
|
|
|
|
.map(({ command_id }) => command_id)
|
|
|
|
const segment2dInfo = await Promise.all(
|
|
|
|
segmentsWithMappings.map(async (segmentId) => {
|
|
|
|
const response = await engineCommandManager.sendSceneCommand({
|
|
|
|
type: 'modeling_cmd_req',
|
|
|
|
cmd_id: uuidv4(),
|
|
|
|
cmd: {
|
|
|
|
type: 'curve_get_control_points',
|
|
|
|
curve_id: segmentId,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
const controlPoints: [
|
|
|
|
{ x: number; y: number },
|
|
|
|
{ x: number; y: number }
|
|
|
|
] = response.data.data.control_points
|
|
|
|
return {
|
|
|
|
controlPoints,
|
|
|
|
segmentId,
|
|
|
|
}
|
|
|
|
})
|
2023-09-14 09:34:37 -04:00
|
|
|
)
|
2023-10-14 03:47:46 +11:00
|
|
|
|
|
|
|
let modifiedAst = { ...kclManager.ast }
|
|
|
|
let code = kclManager.code
|
|
|
|
for (const controlPoint of segment2dInfo) {
|
|
|
|
const range =
|
|
|
|
engineCommandManager.artifactMap[controlPoint.segmentId].range
|
|
|
|
if (!range) continue
|
|
|
|
const from = controlPoint.controlPoints[0]
|
|
|
|
const to = controlPoint.controlPoints[1]
|
|
|
|
const modded = changeSketchArguments(
|
|
|
|
modifiedAst,
|
|
|
|
kclManager.programMemory,
|
|
|
|
range,
|
|
|
|
[to.x, to.y],
|
|
|
|
[from.x, from.y]
|
|
|
|
)
|
|
|
|
modifiedAst = modded.modifiedAst
|
|
|
|
|
|
|
|
// update artifact map ranges now that we have updated the ast.
|
|
|
|
code = recast(modded.modifiedAst)
|
2023-11-06 17:47:45 +11:00
|
|
|
const astWithCurrentRanges = kclManager.safeParse(code)
|
|
|
|
if (!astWithCurrentRanges) return
|
2023-10-14 03:47:46 +11:00
|
|
|
const updateNode = getNodeFromPath<CallExpression>(
|
|
|
|
astWithCurrentRanges,
|
|
|
|
modded.pathToNode
|
|
|
|
).node
|
|
|
|
engineCommandManager.artifactMap[controlPoint.segmentId].range = [
|
|
|
|
updateNode.start,
|
|
|
|
updateNode.end,
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2024-01-31 10:17:24 +01:00
|
|
|
void kclManager.executeAstMock(modifiedAst, true)
|
2023-10-11 13:36:54 +11:00
|
|
|
})
|
2023-11-24 08:59:24 +11:00
|
|
|
} else {
|
2024-01-31 10:17:24 +01:00
|
|
|
void engineCommandManager.sendSceneCommand(command)
|
2023-10-11 13:36:54 +11:00
|
|
|
}
|
2023-09-14 09:34:37 -04:00
|
|
|
|
2023-08-09 20:49:10 +10:00
|
|
|
setDidDragInStream(false)
|
2023-09-06 01:32:53 -04:00
|
|
|
setClickCoords(undefined)
|
|
|
|
}
|
|
|
|
|
|
|
|
const handleMouseMove: MouseEventHandler<HTMLVideoElement> = (e) => {
|
|
|
|
if (!clickCoords) return
|
|
|
|
|
|
|
|
const delta =
|
|
|
|
((clickCoords.x - e.clientX) ** 2 + (clickCoords.y - e.clientY) ** 2) **
|
|
|
|
0.5
|
|
|
|
|
|
|
|
if (delta > 5 && !didDragInStream) {
|
|
|
|
setDidDragInStream(true)
|
|
|
|
}
|
2023-06-22 16:43:33 +10:00
|
|
|
}
|
2023-03-06 20:13:34 +11:00
|
|
|
|
|
|
|
return (
|
2023-08-06 21:29:26 -04:00
|
|
|
<div id="stream" className={className}>
|
2023-06-22 16:43:33 +10:00
|
|
|
<video
|
|
|
|
ref={videoRef}
|
|
|
|
muted
|
|
|
|
autoPlay
|
|
|
|
controls={false}
|
|
|
|
onMouseDown={handleMouseDown}
|
|
|
|
onMouseUp={handleMouseUp}
|
2023-07-20 14:08:32 -04:00
|
|
|
onContextMenu={(e) => e.preventDefault()}
|
|
|
|
onContextMenuCapture={(e) => e.preventDefault()}
|
2023-08-21 10:52:41 -04:00
|
|
|
onWheel={handleScroll}
|
2023-08-10 16:22:45 -04:00
|
|
|
onPlay={() => setIsLoading(false)}
|
2023-09-06 01:32:53 -04:00
|
|
|
onMouseMoveCapture={handleMouseMove}
|
2023-10-11 13:36:54 +11:00
|
|
|
className={`w-full cursor-pointer h-full ${isExecuting && 'blur-md'}`}
|
2023-10-03 15:11:44 -07:00
|
|
|
disablePictureInPicture
|
2023-09-08 17:50:37 +10:00
|
|
|
style={{ transitionDuration: '200ms', transitionProperty: 'filter' }}
|
2023-06-22 16:43:33 +10:00
|
|
|
/>
|
2023-08-10 16:22:45 -04:00
|
|
|
{isLoading && (
|
|
|
|
<div className="text-center absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
2023-11-24 08:59:24 +11:00
|
|
|
<Loading>
|
|
|
|
<span data-testid="loading-stream">Loading stream...</span>
|
|
|
|
</Loading>
|
2023-08-10 16:22:45 -04:00
|
|
|
</div>
|
|
|
|
)}
|
2023-03-06 20:13:34 +11:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|