summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components
diff options
context:
space:
mode:
authorDaniel Polito <[email protected]>2026-02-06 18:01:40 -0300
committerGitHub <[email protected]>2026-02-06 15:01:40 -0600
commit71930621fdfeb8f3d2b3baf956cd690cd699101a (patch)
treecc0efcf10e88751215ddaaa401f7677070a86f0d /packages/ui/src/components
parent288a49165138cbe8071d7f65bdc37a1d627d4d2e (diff)
downloadopencode-71930621fdfeb8f3d2b3baf956cd690cd699101a.tar.gz
opencode-71930621fdfeb8f3d2b3baf956cd690cd699101a.zip
feat(desktop): Session Review Images (#12360)
Diffstat (limited to 'packages/ui/src/components')
-rw-r--r--packages/ui/src/components/session-review.css4
-rw-r--r--packages/ui/src/components/session-review.tsx78
2 files changed, 58 insertions, 24 deletions
diff --git a/packages/ui/src/components/session-review.css b/packages/ui/src/components/session-review.css
index df6df4649..30bfe3b71 100644
--- a/packages/ui/src/components/session-review.css
+++ b/packages/ui/src/components/session-review.css
@@ -166,6 +166,10 @@
color: var(--icon-diff-delete-base);
}
+ [data-slot="session-review-change"][data-type="modified"] {
+ color: var(--icon-diff-modified-base);
+ }
+
[data-slot="session-review-file-container"] {
padding: 0;
}
diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx
index 70d9fe802..fe2475548 100644
--- a/packages/ui/src/components/session-review.tsx
+++ b/packages/ui/src/components/session-review.tsx
@@ -332,8 +332,9 @@ export const SessionReview = (props: SessionReviewProps) => {
const beforeText = () => (typeof diff.before === "string" ? diff.before : "")
const afterText = () => (typeof diff.after === "string" ? diff.after : "")
- const isAdded = () => beforeText().length === 0 && afterText().length > 0
- const isDeleted = () => afterText().length === 0 && beforeText().length > 0
+ const isAdded = () => diff.status === "added" || (beforeText().length === 0 && afterText().length > 0)
+ const isDeleted = () =>
+ diff.status === "deleted" || (afterText().length === 0 && beforeText().length > 0)
const isImage = () => isImageFile(diff.file)
const isAudio = () => isAudioFile(diff.file)
@@ -422,6 +423,7 @@ export const SessionReview = (props: SessionReviewProps) => {
if (!isImage()) return
if (imageSrc()) return
if (imageStatus() !== "idle") return
+ if (isDeleted()) return
const reader = props.readFile
if (!reader) return
@@ -546,6 +548,11 @@ export const SessionReview = (props: SessionReviewProps) => {
{i18n.t("ui.sessionReview.change.removed")}
</span>
</Match>
+ <Match when={isImage()}>
+ <span data-slot="session-review-change" data-type="modified">
+ {i18n.t("ui.sessionReview.change.modified")}
+ </span>
+ </Match>
<Match when={true}>
<DiffChanges changes={diff} />
</Match>
@@ -564,28 +571,51 @@ export const SessionReview = (props: SessionReviewProps) => {
scheduleAnchors()
}}
>
- <Dynamic
- component={diffComponent}
- preloadedDiff={diff.preloaded}
- diffStyle={diffStyle()}
- onRendered={() => {
- props.onDiffRendered?.()
- scheduleAnchors()
- }}
- enableLineSelection={props.onLineComment != null}
- onLineSelected={handleLineSelected}
- onLineSelectionEnd={handleLineSelectionEnd}
- selectedLines={selectedLines()}
- commentedLines={commentedLines()}
- before={{
- name: diff.file!,
- contents: typeof diff.before === "string" ? diff.before : "",
- }}
- after={{
- name: diff.file!,
- contents: typeof diff.after === "string" ? diff.after : "",
- }}
- />
+ <Switch>
+ <Match when={isImage() && imageSrc()}>
+ <div data-slot="session-review-image-container">
+ <img data-slot="session-review-image" src={imageSrc()} alt={diff.file} />
+ </div>
+ </Match>
+ <Match when={isImage() && isDeleted()}>
+ <div data-slot="session-review-image-container" data-removed>
+ <span data-slot="session-review-image-placeholder">
+ {i18n.t("ui.sessionReview.change.removed")}
+ </span>
+ </div>
+ </Match>
+ <Match when={isImage() && !imageSrc()}>
+ <div data-slot="session-review-image-container">
+ <span data-slot="session-review-image-placeholder">
+ {imageStatus() === "loading" ? "Loading..." : "Image"}
+ </span>
+ </div>
+ </Match>
+ <Match when={!isImage()}>
+ <Dynamic
+ component={diffComponent}
+ preloadedDiff={diff.preloaded}
+ diffStyle={diffStyle()}
+ onRendered={() => {
+ props.onDiffRendered?.()
+ scheduleAnchors()
+ }}
+ enableLineSelection={props.onLineComment != null}
+ onLineSelected={handleLineSelected}
+ onLineSelectionEnd={handleLineSelectionEnd}
+ selectedLines={selectedLines()}
+ commentedLines={commentedLines()}
+ before={{
+ name: diff.file!,
+ contents: typeof diff.before === "string" ? diff.before : "",
+ }}
+ after={{
+ name: diff.file!,
+ contents: typeof diff.after === "string" ? diff.after : "",
+ }}
+ />
+ </Match>
+ </Switch>
<For each={comments()}>
{(comment) => (