Feature: Implemented thumbnail.png saving and load. Projects on homepage will have images (#5133)

* feature: implemented saving thumbnail.png to have project thumbnails in the home page

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* Trigger CI

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* bump

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* bump

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* bump

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* bump

* A snapshot a day keeps the bugs away! 📷🐛 (OS: namespace-profile-ubuntu-8-cores)

* bump

* Fix the failing test by increasing window height (related to toast covering now-larger project tiles)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
This commit is contained in:
Kevin Nadro
2025-02-01 06:40:02 -05:00
committed by GitHub
parent b962b5fcb3
commit 229433126d
13 changed files with 70 additions and 20 deletions

View File

@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useHotKeyListener } from './hooks/useHotKeyListener'
import { Stream } from './components/Stream'
import { AppHeader } from './components/AppHeader'
@ -24,6 +24,10 @@ import { UnitsMenu } from 'components/UnitsMenu'
import { CameraProjectionToggle } from 'components/CameraProjectionToggle'
import { useCreateFileLinkQuery } from 'hooks/useCreateFileLinkQueryWatcher'
import { maybeWriteToDisk } from 'lib/telemetry'
import { takeScreenshotOfVideoStreamCanvas } from 'lib/screenshot'
import { writeProjectThumbnailFile } from 'lib/desktop'
import { useRouteLoaderData } from 'react-router-dom'
import { useEngineCommands } from 'components/EngineCommands'
import { commandBarActor } from 'machines/commandBarMachine'
import { useToken } from 'machines/appMachine'
maybeWriteToDisk()
@ -55,6 +59,12 @@ export function App() {
const projectName = project?.name || null
const projectPath = project?.path || null
const [commands] = useEngineCommands()
const [capturedCanvas, setCapturedCanvas] = useState(false)
const loaderData = useRouteLoaderData(PATHS.FILE) as IndexLoaderData
const lastCommandType = commands[commands.length - 1]?.type
useEffect(() => {
onProjectOpen({ name: projectName, path: projectPath }, file || null)
}, [projectName, projectPath])
@ -92,6 +102,28 @@ export function App() {
useEngineConnectionSubscriptions()
// Generate thumbnail.png when loading the app
useEffect(() => {
if (!capturedCanvas && 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])
return (
<div className="relative h-full flex flex-col" ref={ref}>
<AppHeader