feat(studio): Support image renders in fileset preview#770
feat(studio): Support image renders in fileset preview#770steramae-nvidia wants to merge 2 commits into
Conversation
Signed-off-by: Sean Teramae <steramae@nvidia.com>
|
This change is part of the following stack: Change managed by git-spice. |
📝 WalkthroughWalkthroughImage files are now detected through a shared extension registry and displayed with authenticated image previews. Related tests cover extension detection, rendering, download errors, and object URL cleanup. File icons receive shrink-resistant styling, and the telemetry resource link gains a hash href. ChangesImage preview flow
File explorer icon sizing
Telemetry resource link
Suggested labels: Sequence Diagram(s)sequenceDiagram
participant FilesetFilePreviewContent
participant FilesetImagePreview
participant useFilesDownloadFile
participant BrowserImage
FilesetFilePreviewContent->>FilesetImagePreview: render image preview props
FilesetImagePreview->>useFilesDownloadFile: request file with object URL selection
useFilesDownloadFile-->>FilesetImagePreview: image URL or error
FilesetImagePreview->>BrowserImage: render image URL
BrowserImage-->>FilesetImagePreview: load event
FilesetImagePreview->>BrowserImage: revoke object URL
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@web/packages/studio/src/components/FilesetFilePreviewPanel/FilesetImagePreview.tsx`:
- Around line 22-46: Update the ImagePreview component to add an effect cleanup
that calls the existing revokeImageUrl helper when the component unmounts, while
preserving the current load/error cleanup behavior. Add a test covering
unmounting before the image loads and verify that URL.revokeObjectURL is called.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 1a159ee4-7117-4a1f-bf05-cf349c615ca8
📒 Files selected for processing (10)
web/packages/studio/src/api/datasets/constants.tsweb/packages/studio/src/components/FilesetFilePreviewPanel/FilesetFilePreviewContent/index.test.tsxweb/packages/studio/src/components/FilesetFilePreviewPanel/FilesetFilePreviewContent/index.tsxweb/packages/studio/src/components/FilesetFilePreviewPanel/FilesetImagePreview.test.tsxweb/packages/studio/src/components/FilesetFilePreviewPanel/FilesetImagePreview.tsxweb/packages/studio/src/components/FilesetFilePreviewPanel/components/FilesetFilePreviewHeader/index.tsxweb/packages/studio/src/components/filesets/FilesetFileExplorer/useFilesetFileExplorerRows.tsxweb/packages/studio/src/routes/WorkspaceDashboardRoute/ResourcesSection.tsxweb/packages/studio/src/util/binaryFile.test.tsweb/packages/studio/src/util/binaryFile.ts
| const ImagePreview: FC<ImagePreviewProps> = ({ imageUrl, filePath }) => { | ||
| const [imageLoadError, setImageLoadError] = useState(false); | ||
|
|
||
| const revokeImageUrl = () => URL.revokeObjectURL(imageUrl); | ||
|
|
||
| if (imageLoadError) { | ||
| return ( | ||
| <Flex align="center" justify="center" className="h-full"> | ||
| <Text className="text-danger-base">Error: Image could not be displayed.</Text> | ||
| </Flex> | ||
| ); | ||
| } | ||
|
|
||
| return ( | ||
| <Flex className="h-full items-center justify-center overflow-auto rounded-lg border border-base bg-surface-raised p-4"> | ||
| <img | ||
| src={imageUrl} | ||
| alt={getFileName(filePath)} | ||
| className="max-h-full max-w-full object-contain" | ||
| onLoad={revokeImageUrl} | ||
| onError={() => { | ||
| revokeImageUrl(); | ||
| setImageLoadError(true); | ||
| }} | ||
| /> |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Revoke the object URL when the preview unmounts.
Cleanup currently runs only on load/error. If the user changes files while the image is loading, the component unmounts and the blob URL remains allocated. Add an effect cleanup using the same idempotent revoke helper, and cover the unmount-before-load case in a test.
Proposed cleanup
-import { useState, type FC } from 'react';
+import { useCallback, useEffect, useState, type FC } from 'react';
const [imageLoadError, setImageLoadError] = useState(false);
- const revokeImageUrl = () => URL.revokeObjectURL(imageUrl);
+ const revokeImageUrl = useCallback(() => URL.revokeObjectURL(imageUrl), [imageUrl]);
+
+ useEffect(() => {
+ return () => revokeImageUrl();
+ }, [revokeImageUrl]);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const ImagePreview: FC<ImagePreviewProps> = ({ imageUrl, filePath }) => { | |
| const [imageLoadError, setImageLoadError] = useState(false); | |
| const revokeImageUrl = () => URL.revokeObjectURL(imageUrl); | |
| if (imageLoadError) { | |
| return ( | |
| <Flex align="center" justify="center" className="h-full"> | |
| <Text className="text-danger-base">Error: Image could not be displayed.</Text> | |
| </Flex> | |
| ); | |
| } | |
| return ( | |
| <Flex className="h-full items-center justify-center overflow-auto rounded-lg border border-base bg-surface-raised p-4"> | |
| <img | |
| src={imageUrl} | |
| alt={getFileName(filePath)} | |
| className="max-h-full max-w-full object-contain" | |
| onLoad={revokeImageUrl} | |
| onError={() => { | |
| revokeImageUrl(); | |
| setImageLoadError(true); | |
| }} | |
| /> | |
| import { useCallback, useEffect, useState, type FC } from 'react'; | |
| const ImagePreview: FC<ImagePreviewProps> = ({ imageUrl, filePath }) => { | |
| const [imageLoadError, setImageLoadError] = useState(false); | |
| const revokeImageUrl = useCallback(() => URL.revokeObjectURL(imageUrl), [imageUrl]); | |
| useEffect(() => { | |
| return () => revokeImageUrl(); | |
| }, [revokeImageUrl]); | |
| if (imageLoadError) { | |
| return ( | |
| <Flex align="center" justify="center" className="h-full"> | |
| <Text className="text-danger-base">Error: Image could not be displayed.</Text> | |
| </Flex> | |
| ); | |
| } | |
| return ( | |
| <Flex className="h-full items-center justify-center overflow-auto rounded-lg border border-base bg-surface-raised p-4"> | |
| <img | |
| src={imageUrl} | |
| alt={getFileName(filePath)} | |
| className="max-h-full max-w-full object-contain" | |
| onLoad={revokeImageUrl} | |
| onError={() => { | |
| revokeImageUrl(); | |
| setImageLoadError(true); | |
| }} | |
| /> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@web/packages/studio/src/components/FilesetFilePreviewPanel/FilesetImagePreview.tsx`
around lines 22 - 46, Update the ImagePreview component to add an effect cleanup
that calls the existing revokeImageUrl helper when the component unmounts, while
preserving the current load/error cleanup behavior. Add a test covering
unmounting before the image loads and verify that URL.revokeObjectURL is called.
|
Signed-off-by: Sean Teramae steramae@nvidia.com
Summary by CodeRabbit
New Features
Bug Fixes
Tests