summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJustas Raudonius <[email protected]>2026-01-06 18:28:03 +0200
committerGitHub <[email protected]>2026-01-06 10:28:03 -0600
commit6092f8792edab800dbde6fdfb494100fa3a923d5 (patch)
tree384c9bcc1fef485f0a5f9cef7c3cba0c5b8ffb15
parent4142e1bcf6db049c1f5820ef964624b485eff51f (diff)
downloadopencode-6092f8792edab800dbde6fdfb494100fa3a923d5.tar.gz
opencode-6092f8792edab800dbde6fdfb494100fa3a923d5.zip
feat(app): add view button to open files from review sidebar (#7095)
-rw-r--r--packages/app/src/pages/session.tsx12
-rw-r--r--packages/ui/src/components/icon.tsx1
-rw-r--r--packages/ui/src/components/session-review.css24
-rw-r--r--packages/ui/src/components/session-review.tsx13
4 files changed, 50 insertions, 0 deletions
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index 7221ebe86..853d3a894 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -58,6 +58,7 @@ interface SessionReviewTabProps {
view: () => ReturnType<ReturnType<typeof useLayout>["view"]>
diffStyle: DiffStyle
onDiffStyleChange?: (style: DiffStyle) => void
+ onViewFile?: (file: string) => void
classes?: {
root?: string
header?: string
@@ -137,6 +138,7 @@ function SessionReviewTab(props: SessionReviewTabProps) {
diffs={props.diffs()}
diffStyle={props.diffStyle}
onDiffStyleChange={props.onDiffStyleChange}
+ onViewFile={props.onViewFile}
/>
)
}
@@ -818,6 +820,11 @@ export default function Page() {
diffs={diffs}
view={view}
diffStyle="unified"
+ onViewFile={(path) => {
+ const value = file.tab(path)
+ tabs().open(value)
+ file.load(path)
+ }}
classes={{
root: "pb-[calc(var(--prompt-height,8rem)+32px)]",
header: "px-4",
@@ -1028,6 +1035,11 @@ export default function Page() {
view={view}
diffStyle={layout.review.diffStyle()}
onDiffStyleChange={layout.review.setDiffStyle}
+ onViewFile={(path) => {
+ const value = file.tab(path)
+ tabs().open(value)
+ file.load(path)
+ }}
/>
</div>
</Tabs.Content>
diff --git a/packages/ui/src/components/icon.tsx b/packages/ui/src/components/icon.tsx
index 17aa1bbd5..25d4b4f36 100644
--- a/packages/ui/src/components/icon.tsx
+++ b/packages/ui/src/components/icon.tsx
@@ -23,6 +23,7 @@ const icons = {
"code-lines": `<path d="M2.08325 3.75H11.2499M14.5833 3.75H17.9166M2.08325 10L7.08325 10M10.4166 10L17.9166 10M2.08325 16.25L8.74992 16.25M12.0833 16.25L17.9166 16.25" stroke="currentColor" stroke-linecap="square" stroke-linejoin="round"/>`,
"circle-ban-sign": `<path d="M15.3675 4.63087L4.55742 15.441M17.9163 9.9987C17.9163 14.371 14.3719 17.9154 9.99967 17.9154C7.81355 17.9154 5.83438 17.0293 4.40175 15.5966C2.96911 14.164 2.08301 12.1848 2.08301 9.9987C2.08301 5.62644 5.62742 2.08203 9.99967 2.08203C12.1858 2.08203 14.165 2.96813 15.5976 4.40077C17.0302 5.8334 17.9163 7.81257 17.9163 9.9987Z" stroke="currentColor" stroke-linecap="round"/>`,
"edit-small-2": `<path d="M17.0834 17.0833V17.5833H17.5834V17.0833H17.0834ZM2.91675 17.0833H2.41675V17.5833H2.91675V17.0833ZM2.91675 2.91659V2.41659H2.41675V2.91659H2.91675ZM9.58341 3.41659H10.0834V2.41659H9.58341V2.91659V3.41659ZM17.5834 10.4166V9.91659H16.5834V10.4166H17.0834H17.5834ZM10.4167 7.08325L10.0632 6.7297L9.91675 6.87615V7.08325H10.4167ZM10.4167 9.58325H9.91675V10.0833H10.4167V9.58325ZM12.9167 9.58325V10.0833H13.1239L13.2703 9.93681L12.9167 9.58325ZM15.4167 2.08325L15.7703 1.7297L15.4167 1.37615L15.0632 1.7297L15.4167 2.08325ZM17.9167 4.58325L18.2703 4.93681L18.6239 4.58325L18.2703 4.2297L17.9167 4.58325ZM17.0834 17.0833V16.5833H2.91675V17.0833V17.5833H17.0834V17.0833ZM2.91675 17.0833H3.41675V2.91659H2.91675H2.41675V17.0833H2.91675ZM2.91675 2.91659V3.41659H9.58341V2.91659V2.41659H2.91675V2.91659ZM17.0834 10.4166H16.5834V17.0833H17.0834H17.5834V10.4166H17.0834ZM10.4167 7.08325H9.91675V9.58325H10.4167H10.9167V7.08325H10.4167ZM10.4167 9.58325V10.0833H12.9167V9.58325V9.08325H10.4167V9.58325ZM10.4167 7.08325L10.7703 7.43681L15.7703 2.43681L15.4167 2.08325L15.0632 1.7297L10.0632 6.7297L10.4167 7.08325ZM15.4167 2.08325L15.0632 2.43681L17.5632 4.93681L17.9167 4.58325L18.2703 4.2297L15.7703 1.7297L15.4167 2.08325ZM17.9167 4.58325L17.5632 4.2297L12.5632 9.2297L12.9167 9.58325L13.2703 9.93681L18.2703 4.93681L17.9167 4.58325Z" fill="currentColor"/>`,
+ eye: `<path d="M10 4.58325C5.83333 4.58325 2.5 9.99992 2.5 9.99992C2.5 9.99992 5.83333 15.4166 10 15.4166C14.1667 15.4166 17.5 9.99992 17.5 9.99992C17.5 9.99992 14.1667 4.58325 10 4.58325Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/><circle cx="10" cy="10" r="2.5" stroke="currentColor"/>`,
enter: `<path d="M5.83333 15.8334L2.5 12.5L5.83333 9.16671M3.33333 12.5H17.9167V4.58337H10" stroke="currentColor" stroke-linecap="square"/>`,
folder: `<path d="M2.08301 2.91675V16.2501H17.9163V5.41675H9.99967L8.33301 2.91675H2.08301Z" stroke="currentColor" stroke-linecap="round"/>`,
"magnifying-glass": `<path d="M15.8332 15.8337L13.0819 13.0824M14.6143 9.39088C14.6143 12.2759 12.2755 14.6148 9.39039 14.6148C6.50532 14.6148 4.1665 12.2759 4.1665 9.39088C4.1665 6.5058 6.50532 4.16699 9.39039 4.16699C12.2755 4.16699 14.6143 6.5058 14.6143 9.39088Z" stroke="currentColor" stroke-linecap="square"/>`,
diff --git a/packages/ui/src/components/session-review.css b/packages/ui/src/components/session-review.css
index e16c0eeb6..eb6ddb441 100644
--- a/packages/ui/src/components/session-review.css
+++ b/packages/ui/src/components/session-review.css
@@ -106,6 +106,30 @@
flex-shrink: 0;
}
+ [data-slot="session-review-view-button"] {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 2px;
+ margin-left: 8px;
+ border: none;
+ background: transparent;
+ color: var(--text-base);
+ cursor: pointer;
+ border-radius: 4px;
+ opacity: 0;
+ transition: opacity 0.15s ease;
+
+ &:hover {
+ color: var(--text-strong);
+ background: var(--surface-base);
+ }
+ }
+
+ [data-slot="accordion-trigger"]:hover [data-slot="session-review-view-button"] {
+ opacity: 1;
+ }
+
[data-slot="session-review-trigger-actions"] {
flex-shrink: 0;
display: flex;
diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx
index e11df6c9f..be5181a98 100644
--- a/packages/ui/src/components/session-review.tsx
+++ b/packages/ui/src/components/session-review.tsx
@@ -28,6 +28,7 @@ export interface SessionReviewProps {
classes?: { root?: string; header?: string; container?: string }
actions?: JSX.Element
diffs: (FileDiff & { preloaded?: PreloadMultiFileDiffResult<any> })[]
+ onViewFile?: (file: string) => void
}
export const SessionReview = (props: SessionReviewProps) => {
@@ -107,6 +108,18 @@ export const SessionReview = (props: SessionReviewProps) => {
<span data-slot="session-review-directory">{getDirectory(diff.file)}&lrm;</span>
</Show>
<span data-slot="session-review-filename">{getFilename(diff.file)}</span>
+ <Show when={props.onViewFile}>
+ <button
+ data-slot="session-review-view-button"
+ type="button"
+ onClick={(e) => {
+ e.stopPropagation()
+ props.onViewFile?.(diff.file)
+ }}
+ >
+ <Icon name="eye" size="small" />
+ </button>
+ </Show>
</div>
</div>
<div data-slot="session-review-trigger-actions">