Move executeCode out of routeLoaders, into shared space in Stream (#3332)

* Move executeCode out of routeLoaders, into shared space in Stream

* Update src/components/Stream.tsx

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>

* Remove unused dependency

* file switching useEffect should depend on engineConnection

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)

* Re-run CI

* Revert "A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu)"

This reverts commit d97e74a48b.

* Post-merge fix up

---------

Co-authored-by: Jonathan Tran <jonnytran@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Co-authored-by: Kurt Hutten Irev-Dev <k.hutten@protonmail.ch>
This commit is contained in:
Frank Noirot
2024-08-12 09:54:16 -04:00
committed by GitHub
parent 35c7183809
commit e29345fbf6
2 changed files with 49 additions and 20 deletions

View File

@ -15,6 +15,9 @@ import {
EngineConnectionStateType, EngineConnectionStateType,
DisconnectingType, DisconnectingType,
} from 'lang/std/engineConnection' } from 'lang/std/engineConnection'
import { useRouteLoaderData } from 'react-router-dom'
import { PATHS } from 'lib/paths'
import { IndexLoaderData } from 'lib/types'
enum StreamState { enum StreamState {
Playing = 'playing', Playing = 'playing',
@ -32,6 +35,7 @@ export const Stream = () => {
const { mediaStream } = useAppStream() const { mediaStream } = useAppStream()
const { overallState, immediateState } = useNetworkContext() const { overallState, immediateState } = useNetworkContext()
const [streamState, setStreamState] = useState(StreamState.Unset) const [streamState, setStreamState] = useState(StreamState.Unset)
const { file } = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
const IDLE = settings.context.app.streamIdleMode.current const IDLE = settings.context.app.streamIdleMode.current
@ -39,6 +43,39 @@ export const Stream = () => {
overallState === NetworkHealthState.Ok || overallState === NetworkHealthState.Ok ||
overallState === NetworkHealthState.Weak overallState === NetworkHealthState.Weak
/**
* Execute code and show a "building scene message"
* in Stream.tsx in the meantime.
*
* I would like for this to live somewhere more central,
* but it seems to me that we need the video element ref
* to be able to play the video after the code has been
* executed. If we can find a way to do this from a more
* central place, we can move this code there.
*/
async function executeCodeAndPlayStream() {
kclManager.isFirstRender = true
kclManager.executeCode(true).then(() => {
videoRef.current?.play().catch((e) => {
console.warn('Video playing was prevented', e, videoRef.current)
})
kclManager.isFirstRender = false
setStreamState(StreamState.Playing)
})
}
/**
* Subscribe to execute code when the file changes
* but only if the scene is already ready.
* See onSceneReady for the initial scene setup.
*/
useEffect(() => {
if (engineCommandManager.engineConnection?.isReady() && file?.path) {
console.log('execute on file change')
executeCodeAndPlayStream()
}
}, [file?.path, engineCommandManager.engineConnection])
useEffect(() => { useEffect(() => {
if ( if (
immediateState.type === EngineConnectionStateType.Disconnecting && immediateState.type === EngineConnectionStateType.Disconnecting &&
@ -135,26 +172,19 @@ export const Stream = () => {
timeoutIdIdleB = setTimeout(teardown, IDLE_TIME_MS) timeoutIdIdleB = setTimeout(teardown, IDLE_TIME_MS)
} }
const onSceneReady = () => { /**
kclManager.isFirstRender = true * Add a listener to execute code and play the stream
setStreamState(StreamState.Playing) * on initial stream setup.
kclManager.executeCode(true).then(() => { */
videoRef.current?.play().catch((e) => {
console.warn('Video playing was prevented', e, videoRef.current)
})
kclManager.isFirstRender = false
})
}
engineCommandManager.addEventListener( engineCommandManager.addEventListener(
EngineCommandManagerEvents.SceneReady, EngineCommandManagerEvents.SceneReady,
onSceneReady executeCodeAndPlayStream
) )
return () => { return () => {
engineCommandManager.removeEventListener( engineCommandManager.removeEventListener(
EngineCommandManagerEvents.SceneReady, EngineCommandManagerEvents.SceneReady,
onSceneReady executeCodeAndPlayStream
) )
globalThis?.window?.document?.removeEventListener('paste', handlePaste, { globalThis?.window?.document?.removeEventListener('paste', handlePaste, {
capture: true, capture: true,
@ -185,16 +215,18 @@ export const Stream = () => {
} }
}, [IDLE, streamState]) }, [IDLE, streamState])
// HOT FIX: for https://github.com/KittyCAD/modeling-app/pull/3250 /**
// TODO review if there's a better way to play the stream again. * Play the vid
*/
useEffect(() => { useEffect(() => {
if (!kclManager.isFirstRender) if (!kclManager.isFirstRender) {
setTimeout(() => setTimeout(() =>
// execute in the next event loop // execute in the next event loop
videoRef.current?.play().catch((e) => { videoRef.current?.play().catch((e) => {
console.warn('Video playing was prevented', e, videoRef.current) console.warn('Video playing was prevented', e, videoRef.current)
}) })
) )
}
}, [kclManager.isFirstRender]) }, [kclManager.isFirstRender])
useEffect(() => { useEffect(() => {

View File

@ -12,7 +12,7 @@ import { loadAndValidateSettings } from './settings/settingsUtils'
import makeUrlPathRelative from './makeUrlPathRelative' import makeUrlPathRelative from './makeUrlPathRelative'
import { sep } from '@tauri-apps/api/path' import { sep } from '@tauri-apps/api/path'
import { readTextFile } from '@tauri-apps/plugin-fs' import { readTextFile } from '@tauri-apps/plugin-fs'
import { codeManager, kclManager } from 'lib/singletons' import { codeManager } from 'lib/singletons'
import { fileSystemManager } from 'lang/std/fileSystemManager' import { fileSystemManager } from 'lang/std/fileSystemManager'
import { import {
getProjectInfo, getProjectInfo,
@ -105,9 +105,6 @@ export const fileLoader: LoaderFunction = async ({
codeManager.updateCurrentFilePath(current_file_path) codeManager.updateCurrentFilePath(current_file_path)
codeManager.updateCodeStateEditor(code) codeManager.updateCodeStateEditor(code)
// We don't want to call await on execute code since we don't want to block the UI
kclManager.executeCode(true)
// Set the file system manager to the project path // Set the file system manager to the project path
// So that WASM gets an updated path for operations // So that WASM gets an updated path for operations
fileSystemManager.dir = project_path fileSystemManager.dir = project_path