fix(app): remove diff rendering from file-specific tabs (#38662)
This commit is contained in:
@@ -2329,9 +2329,6 @@ export default function Page() {
|
|||||||
reviewHasFocusableContent={() => hasReview() || reviewV2State.sidebarOpened()}
|
reviewHasFocusableContent={() => hasReview() || reviewV2State.sidebarOpened()}
|
||||||
reviewCount={reviewCount}
|
reviewCount={reviewCount}
|
||||||
reviewPanel={reviewPanelV2}
|
reviewPanel={reviewPanelV2}
|
||||||
diffVersion={vcsQuery.dataUpdatedAt}
|
|
||||||
loadDiff={loadReviewDiff}
|
|
||||||
expandUnchanged={reviewV2State.expandMode() === "expand"}
|
|
||||||
reviewSidebarToggle={(disabled) => (
|
reviewSidebarToggle={(disabled) => (
|
||||||
<SessionReviewV2SidebarToggle
|
<SessionReviewV2SidebarToggle
|
||||||
opened={reviewV2State.sidebarOpened()}
|
opened={reviewV2State.sidebarOpened()}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { createEffect, createMemo, createResource, createSignal, Match, on, onCleanup, Show, Switch } from "solid-js"
|
import { createEffect, createMemo, createSignal, Match, on, onCleanup, Show, Switch } from "solid-js"
|
||||||
import { createStore } from "solid-js/store"
|
import { createStore } from "solid-js/store"
|
||||||
import { Dynamic } from "solid-js/web"
|
import { Dynamic } from "solid-js/web"
|
||||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||||
@@ -8,7 +8,6 @@ import { cloneSelectedLineRange, previewSelectedLines } from "@opencode-ai/sessi
|
|||||||
import { createLineCommentController } from "@opencode-ai/session-ui/line-comment-annotations"
|
import { createLineCommentController } from "@opencode-ai/session-ui/line-comment-annotations"
|
||||||
import { createLineCommentControllerV2 } from "@opencode-ai/session-ui/v2/line-comment-annotations-v2"
|
import { createLineCommentControllerV2 } from "@opencode-ai/session-ui/v2/line-comment-annotations-v2"
|
||||||
import { sampledChecksum } from "@opencode-ai/core/util/encode"
|
import { sampledChecksum } from "@opencode-ai/core/util/encode"
|
||||||
import { normalize, text } from "@opencode-ai/session-ui/session-diff"
|
|
||||||
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
||||||
import { IconButton } from "@opencode-ai/ui/icon-button"
|
import { IconButton } from "@opencode-ai/ui/icon-button"
|
||||||
import { LineCommentV2OverflowIcon } from "@opencode-ai/ui/v2/line-comment-v2"
|
import { LineCommentV2OverflowIcon } from "@opencode-ai/ui/v2/line-comment-v2"
|
||||||
@@ -19,20 +18,14 @@ import { showToast } from "@/utils/toast"
|
|||||||
import { selectionFromLines, useFile, type FileSelection, type SelectedLineRange } from "@/context/file"
|
import { selectionFromLines, useFile, type FileSelection, type SelectedLineRange } from "@/context/file"
|
||||||
import { useComments } from "@/context/comments"
|
import { useComments } from "@/context/comments"
|
||||||
import { useLanguage } from "@/context/language"
|
import { useLanguage } from "@/context/language"
|
||||||
import { useLayout } from "@/context/layout"
|
|
||||||
import { usePrompt } from "@/context/prompt"
|
import { usePrompt } from "@/context/prompt"
|
||||||
import { useSettings } from "@/context/settings"
|
import { useSettings } from "@/context/settings"
|
||||||
import { getSessionHandoff } from "@/pages/session/handoff"
|
import { getSessionHandoff } from "@/pages/session/handoff"
|
||||||
import { useSessionLayout } from "@/pages/session/session-layout"
|
import { useSessionLayout } from "@/pages/session/session-layout"
|
||||||
import { createSessionTabs } from "@/pages/session/helpers"
|
import { createSessionTabs } from "@/pages/session/helpers"
|
||||||
import { reviewDiffNeedsLoad, type RenderDiff } from "@/pages/session/v2/review-diff-kinds"
|
|
||||||
|
|
||||||
type SessionFileViewProps = {
|
type SessionFileViewProps = {
|
||||||
tab: string
|
tab: string
|
||||||
diff?: RenderDiff
|
|
||||||
diffVersion?: number
|
|
||||||
loadDiff?: (path: string, version?: number) => Promise<RenderDiff | undefined>
|
|
||||||
expandUnchanged?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectionSide = (range: SelectedLineRange) => range.endSide ?? range.side ?? "additions"
|
const selectionSide = (range: SelectedLineRange) => range.endSide ?? range.side ?? "additions"
|
||||||
@@ -222,25 +215,10 @@ export function FileTabContent(props: { tab: string }) {
|
|||||||
|
|
||||||
export function SessionFileView(props: SessionFileViewProps) {
|
export function SessionFileView(props: SessionFileViewProps) {
|
||||||
const settings = useSettings()
|
const settings = useSettings()
|
||||||
const detailSource = createMemo(() => {
|
|
||||||
if (!props.diff || !props.loadDiff || !reviewDiffNeedsLoad(props.diff)) return
|
|
||||||
return { diff: props.diff, load: props.loadDiff, version: props.diffVersion }
|
|
||||||
})
|
|
||||||
const [loadedDiff] = createResource(detailSource, async ({ diff, load, version }) => {
|
|
||||||
const value = await load(diff.file, version)
|
|
||||||
if (value?.file !== diff.file) return
|
|
||||||
return { source: diff, version, value }
|
|
||||||
})
|
|
||||||
const diff = createMemo(() => {
|
|
||||||
const source = props.diff
|
|
||||||
if (!source) return
|
|
||||||
const loaded = loadedDiff()
|
|
||||||
return normalize(loaded?.source === source && loaded.version === props.diffVersion ? loaded.value : source)
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Show when={settings.general.newLayoutDesigns()} fallback={<SessionFileViewV1 tab={props.tab} />}>
|
<Show when={settings.general.newLayoutDesigns()} fallback={<SessionFileViewV1 tab={props.tab} />}>
|
||||||
<SessionFileViewV2 tab={props.tab} diff={diff()} expandUnchanged={props.expandUnchanged} />
|
<SessionFileViewV2 tab={props.tab} />
|
||||||
</Show>
|
</Show>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -530,12 +508,11 @@ function SessionFileViewV1(props: { tab: string }) {
|
|||||||
return content()
|
return content()
|
||||||
}
|
}
|
||||||
|
|
||||||
function SessionFileViewV2(props: { tab: string; diff?: ReturnType<typeof normalize>; expandUnchanged?: boolean }) {
|
function SessionFileViewV2(props: { tab: string }) {
|
||||||
const file = useFile()
|
const file = useFile()
|
||||||
const comments = useComments()
|
const comments = useComments()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
const prompt = usePrompt()
|
const prompt = usePrompt()
|
||||||
const layout = useLayout()
|
|
||||||
const fileComponent = useFileComponent()
|
const fileComponent = useFileComponent()
|
||||||
const { sessionKey, tabs, view } = useSessionLayout()
|
const { sessionKey, tabs, view } = useSessionLayout()
|
||||||
const activeFileTab = createSessionTabs({
|
const activeFileTab = createSessionTabs({
|
||||||
@@ -581,9 +558,7 @@ function SessionFileViewV2(props: { tab: string; diff?: ReturnType<typeof normal
|
|||||||
const buildPreview = (filePath: string, lines: SelectedLineRange) => {
|
const buildPreview = (filePath: string, lines: SelectedLineRange) => {
|
||||||
const source =
|
const source =
|
||||||
filePath === path()
|
filePath === path()
|
||||||
? props.diff
|
? contents()
|
||||||
? text(props.diff, selectionSide(lines))
|
|
||||||
: contents()
|
|
||||||
: file.get(filePath)?.content?.content
|
: file.get(filePath)?.content?.content
|
||||||
if (!source) return undefined
|
if (!source) return undefined
|
||||||
return selectionPreview(source, selectionFromLines(lines))
|
return selectionPreview(source, selectionFromLines(lines))
|
||||||
@@ -761,21 +736,12 @@ function SessionFileViewV2(props: { tab: string; diff?: ReturnType<typeof normal
|
|||||||
<div class="relative overflow-hidden pb-40">
|
<div class="relative overflow-hidden pb-40">
|
||||||
<Dynamic
|
<Dynamic
|
||||||
component={fileComponent}
|
component={fileComponent}
|
||||||
{...(props.diff
|
mode="text"
|
||||||
? {
|
file={{
|
||||||
mode: "diff" as const,
|
name: path() ?? "",
|
||||||
fileDiff: props.diff.fileDiff,
|
contents: source,
|
||||||
diffStyle: layout.review.diffStyle(),
|
cacheKey: cacheKey(),
|
||||||
expandUnchanged: props.expandUnchanged,
|
}}
|
||||||
}
|
|
||||||
: {
|
|
||||||
mode: "text" as const,
|
|
||||||
file: {
|
|
||||||
name: path() ?? "",
|
|
||||||
contents: source,
|
|
||||||
cacheKey: cacheKey(),
|
|
||||||
},
|
|
||||||
})}
|
|
||||||
enableLineSelection
|
enableLineSelection
|
||||||
enableGutterUtility
|
enableGutterUtility
|
||||||
selectedLines={activeSelection()}
|
selectedLines={activeSelection()}
|
||||||
@@ -801,11 +767,10 @@ function SessionFileViewV2(props: { tab: string; diff?: ReturnType<typeof normal
|
|||||||
commentsUi.onLineNumberSelectionEnd(range)
|
commentsUi.onLineNumberSelectionEnd(range)
|
||||||
}}
|
}}
|
||||||
search={search}
|
search={search}
|
||||||
class="select-text [--opencode-diffs-bg:var(--v2-background-bg-base)]"
|
class="select-text"
|
||||||
media={{
|
media={{
|
||||||
mode: "auto",
|
mode: "auto",
|
||||||
path: path(),
|
path: path(),
|
||||||
deleted: props.diff?.status === "deleted",
|
|
||||||
current: state()?.content,
|
current: state()?.content,
|
||||||
onLoad: scrollSync.queueRestore,
|
onLoad: scrollSync.queueRestore,
|
||||||
onError: (args: { kind: "image" | "audio" | "svg" }) => {
|
onError: (args: { kind: "image" | "audio" | "svg" }) => {
|
||||||
@@ -824,7 +789,6 @@ function SessionFileViewV2(props: { tab: string; diff?: ReturnType<typeof normal
|
|||||||
<div class="mt-3 relative h-full min-h-0">
|
<div class="mt-3 relative h-full min-h-0">
|
||||||
<ScrollView class="h-full" viewportRef={scrollSync.setViewport} onScroll={scrollSync.handleScroll as any}>
|
<ScrollView class="h-full" viewportRef={scrollSync.setViewport} onScroll={scrollSync.handleScroll as any}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Match when={props.diff}>{renderFile(contents())}</Match>
|
|
||||||
<Match when={state()?.loaded}>{renderFile(contents())}</Match>
|
<Match when={state()?.loaded}>{renderFile(contents())}</Match>
|
||||||
<Match when={state()?.loading}>
|
<Match when={state()?.loading}>
|
||||||
<div class="px-6 py-4 text-text-weak">{language.t("common.loading")}...</div>
|
<div class="px-6 py-4 text-text-weak">{language.t("common.loading")}...</div>
|
||||||
|
|||||||
@@ -71,9 +71,6 @@ export function SessionSidePanel(props: {
|
|||||||
reviewHasFocusableContent: () => boolean
|
reviewHasFocusableContent: () => boolean
|
||||||
reviewCount: () => number
|
reviewCount: () => number
|
||||||
reviewPanel: () => JSX.Element
|
reviewPanel: () => JSX.Element
|
||||||
diffVersion?: number
|
|
||||||
loadDiff?: (path: string, version?: number) => Promise<RenderDiff | undefined>
|
|
||||||
expandUnchanged?: boolean
|
|
||||||
reviewSidebarToggle?: (disabled: boolean) => JSX.Element
|
reviewSidebarToggle?: (disabled: boolean) => JSX.Element
|
||||||
fileBrowserState?: SessionFileBrowserState
|
fileBrowserState?: SessionFileBrowserState
|
||||||
activeDiff?: string
|
activeDiff?: string
|
||||||
@@ -91,11 +88,6 @@ export function SessionSidePanel(props: {
|
|||||||
const sdk = useSDK()
|
const sdk = useSDK()
|
||||||
const { sessionKey, tabs, view, params } = useSessionLayout()
|
const { sessionKey, tabs, view, params } = useSessionLayout()
|
||||||
const projectDirectory = createMemo(() => sdk().directory)
|
const projectDirectory = createMemo(() => sdk().directory)
|
||||||
const diffForTab = (tab: string) => {
|
|
||||||
const path = file.pathFromTab(tab)
|
|
||||||
if (!path) return
|
|
||||||
return props.diffs().find((diff): diff is RenderDiff => renderDiff(diff) && diff.file === path)
|
|
||||||
}
|
|
||||||
|
|
||||||
const isDesktop = createMediaQuery("(min-width: 768px)")
|
const isDesktop = createMediaQuery("(min-width: 768px)")
|
||||||
const shown = settings.visibility.fileTree
|
const shown = settings.visibility.fileTree
|
||||||
@@ -747,10 +739,6 @@ export function SessionSidePanel(props: {
|
|||||||
active={file.pathFromTab(browserTab() ?? activeFileTab() ?? "")}
|
active={file.pathFromTab(browserTab() ?? activeFileTab() ?? "")}
|
||||||
kinds={kinds()}
|
kinds={kinds()}
|
||||||
state={props.fileBrowserState!}
|
state={props.fileBrowserState!}
|
||||||
diff={diffForTab(browserTab() ?? activeFileTab() ?? "")}
|
|
||||||
diffVersion={props.diffVersion}
|
|
||||||
loadDiff={props.loadDiff}
|
|
||||||
expandUnchanged={props.expandUnchanged}
|
|
||||||
onSelect={(path) => previewTab(file.tab(path))}
|
onSelect={(path) => previewTab(file.tab(path))}
|
||||||
onSelectPermanent={(path) => openTab(file.tab(path))}
|
onSelectPermanent={(path) => openTab(file.tab(path))}
|
||||||
filterRef={(element) => (fileFilter = element)}
|
filterRef={(element) => (fileFilter = element)}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import { useSDK } from "@/context/sdk"
|
|||||||
import { displayName } from "@/pages/layout/helpers"
|
import { displayName } from "@/pages/layout/helpers"
|
||||||
import { useSessionLayout } from "@/pages/session/session-layout"
|
import { useSessionLayout } from "@/pages/session/session-layout"
|
||||||
import { SessionFileView } from "@/pages/session/file-tabs"
|
import { SessionFileView } from "@/pages/session/file-tabs"
|
||||||
import type { RenderDiff } from "@/pages/session/v2/review-diff-kinds"
|
|
||||||
import { applyFileListKeyDown, SessionFileListV2 } from "@/pages/session/v2/session-file-list-v2"
|
import { applyFileListKeyDown, SessionFileListV2 } from "@/pages/session/v2/session-file-list-v2"
|
||||||
import { pathKey } from "@/utils/path-key"
|
import { pathKey } from "@/utils/path-key"
|
||||||
|
|
||||||
@@ -31,10 +30,6 @@ export function SessionFileBrowserTab(props: {
|
|||||||
active?: string
|
active?: string
|
||||||
kinds: ReadonlyMap<string, Kind>
|
kinds: ReadonlyMap<string, Kind>
|
||||||
state: SessionFileBrowserState
|
state: SessionFileBrowserState
|
||||||
diff?: RenderDiff
|
|
||||||
diffVersion?: number
|
|
||||||
loadDiff?: (path: string, version?: number) => Promise<RenderDiff | undefined>
|
|
||||||
expandUnchanged?: boolean
|
|
||||||
onSelect: (path: string) => void
|
onSelect: (path: string) => void
|
||||||
onSelectPermanent: (path: string) => void
|
onSelectPermanent: (path: string) => void
|
||||||
filterRef?: (element: HTMLInputElement) => void
|
filterRef?: (element: HTMLInputElement) => void
|
||||||
@@ -177,15 +172,7 @@ export function SessionFileBrowserTab(props: {
|
|||||||
>
|
>
|
||||||
<div class="min-h-0 flex-1">
|
<div class="min-h-0 flex-1">
|
||||||
<Show when={props.tab} keyed>
|
<Show when={props.tab} keyed>
|
||||||
{(tab) => (
|
{(tab) => <SessionFileView tab={tab} />}
|
||||||
<SessionFileView
|
|
||||||
tab={tab}
|
|
||||||
diff={props.diff}
|
|
||||||
diffVersion={props.diffVersion}
|
|
||||||
loadDiff={props.loadDiff}
|
|
||||||
expandUnchanged={props.expandUnchanged}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Show>
|
</Show>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
|||||||
Reference in New Issue
Block a user