Fix: thumbnail.png would not be created in a few scenarios, the commandType wasn't populated in some workflows. (#6744)

* fix: moving screenshot logic to after KCL runtime. More robust

* fix: removing toast debugging

* fix: cleaning up the old logic
This commit is contained in:
Kevin Nadro
2025-05-07 12:47:35 -05:00
committed by GitHub
parent 2b3dfaf023
commit 998dbdc6ff
3 changed files with 35 additions and 31 deletions

View File

@ -6,12 +6,10 @@ import {
useLoaderData,
useLocation,
useNavigate,
useRouteLoaderData,
useSearchParams,
} from 'react-router-dom'
import { AppHeader } from '@src/components/AppHeader'
import { useEngineCommands } from '@src/components/EngineCommands'
import { EngineStream } from '@src/components/EngineStream'
import Gizmo from '@src/components/Gizmo'
import { LowerRightControls } from '@src/components/LowerRightControls'
@ -22,11 +20,9 @@ import { useAbsoluteFilePath } from '@src/hooks/useAbsoluteFilePath'
import { useCreateFileLinkQuery } from '@src/hooks/useCreateFileLinkQueryWatcher'
import { useEngineConnectionSubscriptions } from '@src/hooks/useEngineConnectionSubscriptions'
import { useHotKeyListener } from '@src/hooks/useHotKeyListener'
import { writeProjectThumbnailFile } from '@src/lib/desktop'
import useHotkeyWrapper from '@src/lib/hotkeyWrapper'
import { isDesktop } from '@src/lib/isDesktop'
import { PATHS } from '@src/lib/paths'
import { takeScreenshotOfVideoStreamCanvas } from '@src/lib/screenshot'
import {
billingActor,
sceneInfra,
@ -85,10 +81,6 @@ export function App() {
const projectName = project?.name || null
const projectPath = project?.path || null
const [commands] = useEngineCommands()
const loaderData = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
const lastCommandType = commands[commands.length - 1]?.type
// Run LSP file open hook when navigating between projects or files
useEffect(() => {
onProjectOpen({ name: projectName, path: projectPath }, file || null)
@ -127,28 +119,6 @@ export function App() {
useEngineConnectionSubscriptions()
// Generate thumbnail.png when loading the app
useEffect(() => {
if (isDesktop() && lastCommandType === 'execution-done') {
setTimeout(() => {
const projectDirectoryWithoutEndingSlash = loaderData?.project?.path
if (!projectDirectoryWithoutEndingSlash) {
return
}
const dataUrl: string = takeScreenshotOfVideoStreamCanvas()
// zoom to fit command does not wait, wait 500ms to see if zoom to fit finishes
writeProjectThumbnailFile(dataUrl, projectDirectoryWithoutEndingSlash)
.then(() => {})
.catch((e) => {
console.error(
`Failed to generate thumbnail for ${projectDirectoryWithoutEndingSlash}`
)
console.error(e)
})
}, 500)
}
}, [lastCommandType, loaderData?.project?.path])
useEffect(() => {
// Not too useful for regular flows but on modeling view refresh,
// fetch the token count. The regular flow is the count is initialized

View File

@ -36,6 +36,7 @@ import {
engineViewIsometricWithoutGeometryPresent,
} from '@src/lib/utils'
import { DEFAULT_DEFAULT_LENGTH_UNIT } from '@src/lib/constants'
import { createThumbnailPNGOnDesktop } from '@src/lib/screenshot'
export const EngineStream = (props: {
pool: string | null
@ -49,7 +50,7 @@ export const EngineStream = (props: {
const engineStreamState = useSelector(engineStreamActor, (state) => state)
const { file } = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
const { file, project } = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
const last = useRef<number>(Date.now())
const videoWrapperRef = useRef<HTMLDivElement>(null)
@ -122,6 +123,12 @@ export const EngineStream = (props: {
})
}
}
if (project && project.path) {
createThumbnailPNGOnDesktop({
projectDirectoryWithoutEndingSlash: project.path,
})
}
})
.catch(trap)
}

View File

@ -1,3 +1,6 @@
import { isDesktop } from '@src/lib/isDesktop'
import { writeProjectThumbnailFile } from '@src/lib/desktop'
export function takeScreenshotOfVideoStreamCanvas() {
const canvas = document.querySelector('[data-engine]')
const video = document.getElementById('video-stream')
@ -41,3 +44,27 @@ export default async function screenshot(): Promise<string> {
return takeScreenshotOfVideoStreamCanvas()
}
export function createThumbnailPNGOnDesktop({
projectDirectoryWithoutEndingSlash,
}: {
projectDirectoryWithoutEndingSlash: string
}) {
if (isDesktop()) {
setTimeout(() => {
if (!projectDirectoryWithoutEndingSlash) {
return
}
const dataUrl: string = takeScreenshotOfVideoStreamCanvas()
// zoom to fit command does not wait, wait 500ms to see if zoom to fit finishes
writeProjectThumbnailFile(dataUrl, projectDirectoryWithoutEndingSlash)
.then(() => {})
.catch((e) => {
console.error(
`Failed to generate thumbnail for ${projectDirectoryWithoutEndingSlash}`
)
console.error(e)
})
}, 500)
}
}