summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src')
-rw-r--r--packages/app/src/components/session/session-context-tab.tsx9
-rw-r--r--packages/app/src/pages/session/composer/session-question-dock.tsx4
-rw-r--r--packages/app/src/pages/session/file-tabs.tsx88
-rw-r--r--packages/app/src/pages/session/message-timeline.tsx9
-rw-r--r--packages/app/src/pages/session/review-tab.tsx4
5 files changed, 59 insertions, 55 deletions
diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx
index 162e016c6..1ea97c395 100644
--- a/packages/app/src/components/session/session-context-tab.tsx
+++ b/packages/app/src/components/session/session-context-tab.tsx
@@ -11,6 +11,7 @@ import { Accordion } from "@opencode-ai/ui/accordion"
import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header"
import { Code } from "@opencode-ai/ui/code"
import { Markdown } from "@opencode-ai/ui/markdown"
+import { ScrollView } from "@opencode-ai/ui/scroll-view"
import type { Message, Part, UserMessage } from "@opencode-ai/sdk/v2/client"
import { useLanguage } from "@/context/language"
import { getSessionContextMetrics } from "./session-context-metrics"
@@ -268,9 +269,9 @@ export function SessionContextTab() {
})
return (
- <div
- class="@container h-full overflow-y-auto no-scrollbar pb-10"
- ref={(el) => {
+ <ScrollView
+ class="@container h-full pb-10"
+ viewportRef={(el) => {
scroll = el
restoreScroll()
}}
@@ -336,6 +337,6 @@ export function SessionContextTab() {
</Accordion>
</div>
</div>
- </div>
+ </ScrollView>
)
}
diff --git a/packages/app/src/pages/session/composer/session-question-dock.tsx b/packages/app/src/pages/session/composer/session-question-dock.tsx
index 1ccac937c..fd2ced3dc 100644
--- a/packages/app/src/pages/session/composer/session-question-dock.tsx
+++ b/packages/app/src/pages/session/composer/session-question-dock.tsx
@@ -62,7 +62,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
const measure = () => {
if (!root) return
- const scroller = document.querySelector(".session-scroller")
+ const scroller = document.querySelector(".scroll-view__viewport")
const head = scroller instanceof HTMLElement ? scroller.firstElementChild : undefined
const top =
head instanceof HTMLElement && head.classList.contains("sticky") ? head.getBoundingClientRect().bottom : 0
@@ -95,7 +95,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
window.addEventListener("resize", update)
const dock = root?.closest('[data-component="session-prompt-dock"]')
- const scroller = document.querySelector(".session-scroller")
+ const scroller = document.querySelector(".scroll-view__viewport")
const observer = new ResizeObserver(update)
if (dock instanceof HTMLElement) observer.observe(dock)
if (scroller instanceof HTMLElement) observer.observe(scroller)
diff --git a/packages/app/src/pages/session/file-tabs.tsx b/packages/app/src/pages/session/file-tabs.tsx
index ebc1f5922..032756cab 100644
--- a/packages/app/src/pages/session/file-tabs.tsx
+++ b/packages/app/src/pages/session/file-tabs.tsx
@@ -9,6 +9,7 @@ import { showToast } from "@opencode-ai/ui/toast"
import { LineComment as LineCommentView, LineCommentEditor } from "@opencode-ai/ui/line-comment"
import { Mark } from "@opencode-ai/ui/logo"
import { Tabs } from "@opencode-ai/ui/tabs"
+import { ScrollView } from "@opencode-ai/ui/scroll-view"
import { useLayout } from "@/context/layout"
import { selectionFromLines, useFile, type FileSelection, type SelectedLineRange } from "@/context/file"
import { useComments } from "@/context/comments"
@@ -509,51 +510,52 @@ export function FileTabContent(props: { tab: string }) {
)
return (
- <Tabs.Content
- value={props.tab}
- class="mt-3 relative"
- ref={(el: HTMLDivElement) => {
- scroll = el
- restoreScroll()
- }}
- onScroll={handleScroll}
- >
- <Switch>
- <Match when={state()?.loaded && isImage()}>
- <div class="px-6 py-4 pb-40">
- <img
- src={imageDataUrl()}
- alt={path()}
- class="max-w-full"
- onLoad={() => requestAnimationFrame(restoreScroll)}
- />
- </div>
- </Match>
- <Match when={state()?.loaded && isSvg()}>
- <div class="flex flex-col gap-4 px-6 py-4">
- {renderCode(svgContent() ?? "", "")}
- <Show when={svgPreviewUrl()}>
- <div class="flex justify-center pb-40">
- <img src={svgPreviewUrl()} alt={path()} class="max-w-full max-h-96" />
+ <Tabs.Content value={props.tab} class="mt-3 relative h-full">
+ <ScrollView
+ class="h-full"
+ viewportRef={(el: HTMLDivElement) => {
+ scroll = el
+ restoreScroll()
+ }}
+ onScroll={handleScroll as any}
+ >
+ <Switch>
+ <Match when={state()?.loaded && isImage()}>
+ <div class="px-6 py-4 pb-40">
+ <img
+ src={imageDataUrl()}
+ alt={path()}
+ class="max-w-full"
+ onLoad={() => requestAnimationFrame(restoreScroll)}
+ />
+ </div>
+ </Match>
+ <Match when={state()?.loaded && isSvg()}>
+ <div class="flex flex-col gap-4 px-6 py-4">
+ {renderCode(svgContent() ?? "", "")}
+ <Show when={svgPreviewUrl()}>
+ <div class="flex justify-center pb-40">
+ <img src={svgPreviewUrl()} alt={path()} class="max-w-full max-h-96" />
+ </div>
+ </Show>
+ </div>
+ </Match>
+ <Match when={state()?.loaded && isBinary()}>
+ <div class="h-full px-6 pb-42 flex flex-col items-center justify-center text-center gap-6">
+ <Mark class="w-14 opacity-10" />
+ <div class="flex flex-col gap-2 max-w-md">
+ <div class="text-14-semibold text-text-strong truncate">{path()?.split("/").pop()}</div>
+ <div class="text-14-regular text-text-weak">{language.t("session.files.binaryContent")}</div>
</div>
- </Show>
- </div>
- </Match>
- <Match when={state()?.loaded && isBinary()}>
- <div class="h-full px-6 pb-42 flex flex-col items-center justify-center text-center gap-6">
- <Mark class="w-14 opacity-10" />
- <div class="flex flex-col gap-2 max-w-md">
- <div class="text-14-semibold text-text-strong truncate">{path()?.split("/").pop()}</div>
- <div class="text-14-regular text-text-weak">{language.t("session.files.binaryContent")}</div>
</div>
- </div>
- </Match>
- <Match when={state()?.loaded}>{renderCode(contents(), "pb-40")}</Match>
- <Match when={state()?.loading}>
- <div class="px-6 py-4 text-text-weak">{language.t("common.loading")}...</div>
- </Match>
- <Match when={state()?.error}>{(err) => <div class="px-6 py-4 text-text-weak">{err()}</div>}</Match>
- </Switch>
+ </Match>
+ <Match when={state()?.loaded}>{renderCode(contents(), "pb-40")}</Match>
+ <Match when={state()?.loading}>
+ <div class="px-6 py-4 text-text-weak">{language.t("common.loading")}...</div>
+ </Match>
+ <Match when={state()?.error}>{(err) => <div class="px-6 py-4 text-text-weak">{err()}</div>}</Match>
+ </Switch>
+ </ScrollView>
</Tabs.Content>
)
}
diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx
index 6ac89a3a7..b13ccb474 100644
--- a/packages/app/src/pages/session/message-timeline.tsx
+++ b/packages/app/src/pages/session/message-timeline.tsx
@@ -8,6 +8,7 @@ import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
import { Dialog } from "@opencode-ai/ui/dialog"
import { InlineInput } from "@opencode-ai/ui/inline-input"
import { SessionTurn } from "@opencode-ai/ui/session-turn"
+import { ScrollView } from "@opencode-ai/ui/scroll-view"
import type { UserMessage } from "@opencode-ai/sdk/v2"
import { showToast } from "@opencode-ai/ui/toast"
import { shouldMarkBoundaryGesture, normalizeWheelDelta } from "@/pages/session/message-gesture"
@@ -322,8 +323,8 @@ export function MessageTimeline(props: {
<Icon name="arrow-down-to-line" />
</button>
</div>
- <div
- ref={props.setScrollRef}
+ <ScrollView
+ viewportRef={props.setScrollRef}
onWheel={(e) => {
const root = e.currentTarget
const delta = normalizeWheelDelta({
@@ -367,7 +368,7 @@ export function MessageTimeline(props: {
if (props.isDesktop) props.onScrollSpyScroll()
}}
onClick={props.onAutoScrollInteraction}
- class="relative min-w-0 w-full h-full overflow-y-auto session-scroller"
+ class="relative min-w-0 w-full h-full"
style={{
"--session-title-height": showHeader() ? "40px" : "0px",
"--sticky-accordion-top": showHeader() ? "48px" : "0px",
@@ -548,7 +549,7 @@ export function MessageTimeline(props: {
)}
</For>
</div>
- </div>
+ </ScrollView>
</div>
</Show>
)
diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx
index 3a9f63949..9349e9937 100644
--- a/packages/app/src/pages/session/review-tab.tsx
+++ b/packages/app/src/pages/session/review-tab.tsx
@@ -143,9 +143,9 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
open={props.view().review.open()}
onOpenChange={props.view().review.setOpen}
classes={{
- root: props.classes?.root ?? "pb-6",
+ root: props.classes?.root ?? "pb-6 pr-3",
header: props.classes?.header ?? "px-3",
- container: props.classes?.container ?? "px-3",
+ container: props.classes?.container ?? "pl-3",
}}
diffs={props.diffs()}
diffStyle={props.diffStyle}