Don't zoom to fit on resume; make indicator better
This commit is contained in:
@ -22,6 +22,8 @@ import {
|
|||||||
} from 'lib/toolbar'
|
} from 'lib/toolbar'
|
||||||
import { isDesktop } from 'lib/isDesktop'
|
import { isDesktop } from 'lib/isDesktop'
|
||||||
import { openExternalBrowserIfDesktop } from 'lib/openWindow'
|
import { openExternalBrowserIfDesktop } from 'lib/openWindow'
|
||||||
|
import { EngineConnectionStateType } from 'lang/std/engineConnection'
|
||||||
|
import useEngineStreamContext, { EngineStreamState, EngineStreamTransition } from 'hooks/useEngineStreamContext'
|
||||||
|
|
||||||
export function Toolbar({
|
export function Toolbar({
|
||||||
className = '',
|
className = '',
|
||||||
@ -48,7 +50,7 @@ export function Toolbar({
|
|||||||
}, [engineCommandManager.artifactGraph, context.selectionRanges])
|
}, [engineCommandManager.artifactGraph, context.selectionRanges])
|
||||||
|
|
||||||
const toolbarButtonsRef = useRef<HTMLUListElement>(null)
|
const toolbarButtonsRef = useRef<HTMLUListElement>(null)
|
||||||
const { overallState } = useNetworkContext()
|
const { overallState, immediateState } = useNetworkContext()
|
||||||
const { isExecuting } = useKclContext()
|
const { isExecuting } = useKclContext()
|
||||||
const { isStreamReady } = useAppState()
|
const { isStreamReady } = useAppState()
|
||||||
|
|
||||||
@ -56,6 +58,7 @@ export function Toolbar({
|
|||||||
(overallState !== NetworkHealthState.Ok &&
|
(overallState !== NetworkHealthState.Ok &&
|
||||||
overallState !== NetworkHealthState.Weak) ||
|
overallState !== NetworkHealthState.Weak) ||
|
||||||
isExecuting ||
|
isExecuting ||
|
||||||
|
immediateState.type !== EngineConnectionStateType.ConnectionEstablished ||
|
||||||
!isStreamReady
|
!isStreamReady
|
||||||
|
|
||||||
const currentMode =
|
const currentMode =
|
||||||
|
|||||||
@ -34,6 +34,7 @@ export const EngineStream = () => {
|
|||||||
const {
|
const {
|
||||||
state: modelingMachineState,
|
state: modelingMachineState,
|
||||||
send: modelingMachineActorSend,
|
send: modelingMachineActorSend,
|
||||||
|
context: modelingMachineActorContext,
|
||||||
} = useModelingContext()
|
} = useModelingContext()
|
||||||
|
|
||||||
const engineStreamActor = useEngineStreamContext.useActorRef()
|
const engineStreamActor = useEngineStreamContext.useActorRef()
|
||||||
@ -156,19 +157,28 @@ export const EngineStream = () => {
|
|||||||
}, [streamIdleMode])
|
}, [streamIdleMode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let frameId = undefined
|
||||||
const frameLoop = () => {
|
const frameLoop = () => {
|
||||||
if (timeoutStart.current) {
|
// Do not pause if the user is in the middle of an operation
|
||||||
|
if (!modelingMachineState.matches('idle')) {
|
||||||
|
// In fact, stop the timeout, because we don't want to trigger the
|
||||||
|
// pause when we exit the operation.
|
||||||
|
timeoutStart.current = null
|
||||||
|
} else if (timeoutStart.current) {
|
||||||
const elapsed = Date.now() - timeoutStart.current
|
const elapsed = Date.now() - timeoutStart.current
|
||||||
if (elapsed >= IDLE_TIME_MS) {
|
if (elapsed >= IDLE_TIME_MS) {
|
||||||
timeoutStart.current = null
|
timeoutStart.current = null
|
||||||
engineStreamActor.send({ type: EngineStreamTransition.Pause })
|
engineStreamActor.send({ type: EngineStreamTransition.Pause })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
frameId = window.requestAnimationFrame(frameLoop)
|
||||||
window.requestAnimationFrame(frameLoop)
|
|
||||||
}
|
}
|
||||||
frameLoop()
|
frameId = window.requestAnimationFrame(frameLoop)
|
||||||
}, [])
|
|
||||||
|
return () => {
|
||||||
|
window.cancelAnimationFrame(frameId)
|
||||||
|
}
|
||||||
|
}, [modelingMachineState])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!streamIdleMode) return
|
if (!streamIdleMode) return
|
||||||
@ -199,6 +209,11 @@ export const EngineStream = () => {
|
|||||||
timeoutStart.current = Date.now()
|
timeoutStart.current = Date.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It's possible after a reconnect, the user doesn't move their mouse at
|
||||||
|
// all, meaning the timer is not reset to run. We need to set it every
|
||||||
|
// time our effect dependencies change then.
|
||||||
|
timeoutStart.current = Date.now()
|
||||||
|
|
||||||
window.document.addEventListener('keydown', onAnyInput)
|
window.document.addEventListener('keydown', onAnyInput)
|
||||||
window.document.addEventListener('keyup', onAnyInput)
|
window.document.addEventListener('keyup', onAnyInput)
|
||||||
window.document.addEventListener('mousemove', onAnyInput)
|
window.document.addEventListener('mousemove', onAnyInput)
|
||||||
|
|||||||
@ -1,15 +1,26 @@
|
|||||||
|
import { useEffect, useState } from 'react'
|
||||||
import { useEngineCommands } from './EngineCommands'
|
import { useEngineCommands } from './EngineCommands'
|
||||||
import { CustomIcon } from './CustomIcon'
|
import { CustomIcon } from './CustomIcon'
|
||||||
import useEngineStreamContext, { EngineStreamState } from 'hooks/useEngineStreamContext'
|
import useEngineStreamContext, { EngineStreamState } from 'hooks/useEngineStreamContext'
|
||||||
|
|
||||||
export const ModelStateIndicator = () => {
|
export const ModelStateIndicator = () => {
|
||||||
const [commands] = useEngineCommands()
|
const [commands] = useEngineCommands()
|
||||||
|
const [isDone, setIsDone] = useState<boolean>(false)
|
||||||
|
|
||||||
const engineStreamActor = useEngineStreamContext.useActorRef()
|
const engineStreamActor = useEngineStreamContext.useActorRef()
|
||||||
const engineStreamState = engineStreamActor.getSnapshot()
|
const engineStreamState = engineStreamActor.getSnapshot()
|
||||||
|
|
||||||
const lastCommandType = commands[commands.length - 1]?.type
|
const lastCommandType = commands[commands.length - 1]?.type
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (lastCommandType === 'set_default_system_properties') {
|
||||||
|
setIsDone(false)
|
||||||
|
}
|
||||||
|
if (lastCommandType === 'execution-done') {
|
||||||
|
setIsDone(true)
|
||||||
|
}
|
||||||
|
}, [lastCommandType])
|
||||||
|
|
||||||
let className = 'w-6 h-6 '
|
let className = 'w-6 h-6 '
|
||||||
let icon = <div className={className}></div>
|
let icon = <div className={className}></div>
|
||||||
let dataTestId = 'model-state-indicator'
|
let dataTestId = 'model-state-indicator'
|
||||||
@ -32,7 +43,7 @@ export const ModelStateIndicator = () => {
|
|||||||
name="parallel"
|
name="parallel"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
} else if (lastCommandType === 'execution-done') {
|
} else if (isDone) {
|
||||||
className +=
|
className +=
|
||||||
'text-secondary'
|
'text-secondary'
|
||||||
icon = (
|
icon = (
|
||||||
|
|||||||
@ -47,7 +47,7 @@ const engineStreamMachine = setup({
|
|||||||
input: {} as EngineStreamContext,
|
input: {} as EngineStreamContext,
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
[EngineStreamTransition.Play]({ context }) {
|
[EngineStreamTransition.Play]({ context }, params: { zoomToFit: boolean }) {
|
||||||
const canvas = context.canvasRef.current
|
const canvas = context.canvasRef.current
|
||||||
if (!canvas) return false
|
if (!canvas) return false
|
||||||
|
|
||||||
@ -61,13 +61,13 @@ const engineStreamMachine = setup({
|
|||||||
canvas.style.display = "none"
|
canvas.style.display = "none"
|
||||||
|
|
||||||
video.srcObject = mediaStream
|
video.srcObject = mediaStream
|
||||||
void video.play().catch((e) => {
|
void sceneInfra.camControls.restoreCameraPosition()
|
||||||
|
.then(() => video.play())
|
||||||
|
.catch((e) => {
|
||||||
console.warn('Video playing was prevented', e, video)
|
console.warn('Video playing was prevented', e, video)
|
||||||
}).then(() => {
|
|
||||||
kclManager.executeCode(true).then(() => {
|
|
||||||
return sceneInfra.camControls.restoreCameraPosition()
|
|
||||||
}).catch(trap)
|
|
||||||
})
|
})
|
||||||
|
.then(() => kclManager.executeCode(params.zoomToFit))
|
||||||
|
.catch(trap)
|
||||||
},
|
},
|
||||||
[EngineStreamTransition.Pause]({ context }) {
|
[EngineStreamTransition.Pause]({ context }) {
|
||||||
const video = context.videoRef.current
|
const video = context.videoRef.current
|
||||||
@ -181,7 +181,7 @@ const engineStreamMachine = setup({
|
|||||||
},
|
},
|
||||||
[EngineStreamTransition.Play]: {
|
[EngineStreamTransition.Play]: {
|
||||||
target: EngineStreamState.Playing,
|
target: EngineStreamState.Playing,
|
||||||
actions: [ { type: EngineStreamTransition.Play } ]
|
actions: [ { type: EngineStreamTransition.Play, params: { zoomToFit: true }} ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -214,7 +214,7 @@ const engineStreamMachine = setup({
|
|||||||
},
|
},
|
||||||
[EngineStreamTransition.Play]: {
|
[EngineStreamTransition.Play]: {
|
||||||
target: EngineStreamState.Playing,
|
target: EngineStreamState.Playing,
|
||||||
actions: [ { type: EngineStreamTransition.Play } ]
|
actions: [ { type: EngineStreamTransition.Play, params: { zoomToFit: false }} ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user