Skip to content

Add image preview support in desktop file viewer #149

@shuv1337

Description

@shuv1337

Problem/Context

When opening image files in the desktop file viewer tabs, the raw base64 string is displayed as text in the code viewer instead of rendering the actual image. The API already returns image files with base64 encoding and proper mime types, but the file viewer doesn't handle this case.

Currently in packages/desktop/src/pages/session.tsx:814-827, all file content is passed directly to the code syntax highlighter:

<Match when={file()}>
  {(f) => (
    <Dynamic
      component={codeComponent}
      file={{
        name: f().path,
        contents: f().content?.content ?? "",
        cacheKey: checksum(f().content?.content ?? ""),
      }}
      overflow="scroll"
      class="pb-40"
    />
  )}
</Match>

The FileContent type already includes the necessary fields for image detection:

  • encoding?: "base64" - present when file is binary
  • mimeType?: string - contains the MIME type (e.g., image/png)

Acceptance Criteria

  • Image files (png, jpg, jpeg, gif, webp, svg) display as rendered images instead of base64 text
  • Images are properly scaled/contained within the viewer area
  • Images are scrollable if larger than the viewport
  • Non-image binary files continue to show appropriate messaging (or base64)
  • Text/code files continue to use the existing syntax highlighting

Implementation Details

Technical Approach

  1. Add a conditional check before rendering file content:

    • Check if f().content?.encoding === "base64"
    • Check if f().content?.mimeType?.startsWith("image/")
  2. For images, render an <img> element with a data URL:

    <img 
      src={`data:${f().content?.mimeType};base64,${f().content?.content}`} 
      alt={f().path}
    />
  3. Add appropriate styling for image container (centering, max dimensions, overflow scroll)

Code References

File Purpose
packages/desktop/src/pages/session.tsx:800-832 File viewer tabs - where change is needed
packages/opencode/src/file/index.ts:235-273 Backend file reading - shows base64 encoding logic
packages/sdk/js/src/v2/gen/types.gen.ts:1846-1866 FileContent type definition with encoding and mimeType
packages/ui/src/components/message-part.tsx:127-161 Existing image rendering pattern for attachments
packages/desktop/src/components/prompt-input.tsx Image attachment handling (accepted types)

Reference Implementation

The codebase already handles image rendering in message attachments (packages/ui/src/components/message-part.tsx):

<Show when={file.mime.startsWith("image/") && file.url}>
  <img data-slot="user-message-attachment-image" src={file.url} alt={file.filename ?? "attachment"} />
</Show>

A similar pattern using data URLs for base64 images:

// Standard pattern for rendering base64 images
<img src={`data:${mimeType};base64,${base64Content}`} />

Tasks

  • Add image detection logic in file viewer (encoding === "base64" and mimeType.startsWith("image/"))
  • Create image preview component/element with data URL src
  • Add CSS styling for image container (centering, contain sizing, scroll behavior)
  • Test with various image formats (png, jpg, gif, webp, svg)
  • Ensure text/code files still render correctly with syntax highlighting

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions