mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-21 09:44:21 +01:00
wip: desktop work
This commit is contained in:
@@ -670,98 +670,6 @@ export default function Page() {
|
|||||||
<Message message={message} parts={parts()} />
|
<Message message={message} parts={parts()} />
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
{/* Response */}
|
|
||||||
<div class="w-full flex flex-col gap-2">
|
|
||||||
<Collapsible variant="ghost" open={expanded()} onOpenChange={setExpanded}>
|
|
||||||
<Collapsible.Trigger class="text-text-weak hover:text-text-strong">
|
|
||||||
<div class="flex items-center gap-1 self-stretch">
|
|
||||||
<h2 class="text-12-medium">
|
|
||||||
<Switch>
|
|
||||||
<Match when={expanded()}>Hide steps</Match>
|
|
||||||
<Match when={!expanded()}>Show steps</Match>
|
|
||||||
</Switch>
|
|
||||||
</h2>
|
|
||||||
<Collapsible.Arrow />
|
|
||||||
</div>
|
|
||||||
</Collapsible.Trigger>
|
|
||||||
<Collapsible.Content>
|
|
||||||
<div class="w-full flex flex-col items-start self-stretch gap-8">
|
|
||||||
<For each={assistantMessages()}>
|
|
||||||
{(assistantMessage) => {
|
|
||||||
const parts = createMemo(() => sync.data.part[assistantMessage.id])
|
|
||||||
return <Message message={assistantMessage} parts={parts()} />
|
|
||||||
}}
|
|
||||||
</For>
|
|
||||||
</div>
|
|
||||||
</Collapsible.Content>
|
|
||||||
</Collapsible>
|
|
||||||
<Show when={working() && !expanded()}>
|
|
||||||
{(_) => {
|
|
||||||
const lastMessageWithText = createMemo(() =>
|
|
||||||
assistantMessages().findLast((m) => {
|
|
||||||
const parts = sync.data.part[m.id]
|
|
||||||
return parts?.find((p) => p.type === "text")
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
const lastMessageWithReasoning = createMemo(() =>
|
|
||||||
assistantMessages().findLast((m) => {
|
|
||||||
const parts = sync.data.part[m.id]
|
|
||||||
return parts?.find((p) => p.type === "reasoning")
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
const lastMessageWithTool = createMemo(() =>
|
|
||||||
assistantMessages().findLast((m) => {
|
|
||||||
const parts = sync.data.part[m.id]
|
|
||||||
return parts?.find(
|
|
||||||
(p) => p.type === "tool" && p.state.status === "completed",
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
return (
|
|
||||||
<div class="w-full flex flex-col gap-2">
|
|
||||||
<Switch>
|
|
||||||
<Match when={lastMessageWithText()}>
|
|
||||||
{(last) => {
|
|
||||||
const lastTextPart = createMemo(() =>
|
|
||||||
sync.data.part[last().id].findLast((p) => p.type === "text"),
|
|
||||||
)
|
|
||||||
return (
|
|
||||||
<Part message={last()} part={lastTextPart()!} hideDetails />
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</Match>
|
|
||||||
<Match when={lastMessageWithReasoning()}>
|
|
||||||
{(last) => {
|
|
||||||
const lastReasoningPart = createMemo(() =>
|
|
||||||
sync.data.part[last().id].findLast(
|
|
||||||
(p) => p.type === "reasoning",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
return (
|
|
||||||
<Part
|
|
||||||
message={last()}
|
|
||||||
part={lastReasoningPart()!}
|
|
||||||
hideDetails
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</Match>
|
|
||||||
</Switch>
|
|
||||||
<Show when={lastMessageWithTool()}>
|
|
||||||
{(last) => {
|
|
||||||
const lastToolPart = createMemo(() =>
|
|
||||||
sync.data.part[last().id].findLast(
|
|
||||||
(p) => p.type === "tool" && p.state.status === "completed",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
return <Part message={last()} part={lastToolPart()!} hideDetails />
|
|
||||||
}}
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
{/* Summary */}
|
{/* Summary */}
|
||||||
<Show when={!working()}>
|
<Show when={!working()}>
|
||||||
<div class="w-full flex flex-col gap-6 items-start self-stretch">
|
<div class="w-full flex flex-col gap-6 items-start self-stretch">
|
||||||
@@ -817,6 +725,48 @@ export default function Page() {
|
|||||||
</Accordion>
|
</Accordion>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
</Show>
|
||||||
|
{/* Response */}
|
||||||
|
<div class="w-full">
|
||||||
|
<Switch>
|
||||||
|
<Match when={working()}>
|
||||||
|
<div class="w-full flex flex-col-reverse items-start self-stretch gap-6 max-h-30 overflow-y-auto no-scrollbar pointer-events-none mask-alpha mask-y-from-66% mask-y-from-background-base mask-y-to-transparent">
|
||||||
|
<For each={assistantMessages()?.toReversed()}>
|
||||||
|
{(assistantMessage) => {
|
||||||
|
const parts = createMemo(() => sync.data.part[assistantMessage.id])
|
||||||
|
return <Message message={assistantMessage} parts={parts()} />
|
||||||
|
}}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</Match>
|
||||||
|
<Match when={!working()}>
|
||||||
|
<Collapsible variant="ghost" open={expanded()} onOpenChange={setExpanded}>
|
||||||
|
<Collapsible.Trigger class="text-text-weak hover:text-text-strong">
|
||||||
|
<div class="flex items-center gap-1 self-stretch">
|
||||||
|
<div class="text-12-medium">
|
||||||
|
<Switch>
|
||||||
|
<Match when={expanded()}>Hide steps</Match>
|
||||||
|
<Match when={!expanded()}>Show steps</Match>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
<Collapsible.Arrow />
|
||||||
|
</div>
|
||||||
|
</Collapsible.Trigger>
|
||||||
|
<Collapsible.Content>
|
||||||
|
<div class="w-full flex flex-col-reverse items-start self-stretch gap-8">
|
||||||
|
<For each={assistantMessages()}>
|
||||||
|
{(assistantMessage) => {
|
||||||
|
const parts = createMemo(
|
||||||
|
() => sync.data.part[assistantMessage.id],
|
||||||
|
)
|
||||||
|
return <Message message={assistantMessage} parts={parts()} />
|
||||||
|
}}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</Collapsible.Content>
|
||||||
|
</Collapsible>
|
||||||
|
</Match>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -54,18 +54,20 @@ export function Diff<T>(props: DiffProps<T>) {
|
|||||||
// When ready to render, simply call .render with old/new file, optional
|
// When ready to render, simply call .render with old/new file, optional
|
||||||
// annotations and a container element to hold the diff
|
// annotations and a container element to hold the diff
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
|
// @ts-expect-error
|
||||||
const instance = new FileDiff<T>({
|
const instance = new FileDiff<T>({
|
||||||
theme: "pierre-light",
|
// theme: "pierre-light",
|
||||||
|
// theme: "pierre-light",
|
||||||
// Or can also provide a 'themes' prop, which allows the code to adapt
|
// Or can also provide a 'themes' prop, which allows the code to adapt
|
||||||
// to your OS light or dark theme
|
// to your OS light or dark theme
|
||||||
// themes: { dark: 'pierre-night', light: 'pierre-light' },
|
themes: { dark: "pierre-dark", light: "pierre-light" },
|
||||||
// When using the 'themes' prop, 'themeType' allows you to force 'dark'
|
// When using the 'themes' prop, 'themeType' allows you to force 'dark'
|
||||||
// or 'light' theme, or inherit from the OS ('system') theme.
|
// or 'light' theme, or inherit from the OS ('system') theme.
|
||||||
themeType: "system",
|
themeType: "system",
|
||||||
// Disable the line numbers for your diffs, generally not recommended
|
// Disable the line numbers for your diffs, generally not recommended
|
||||||
disableLineNumbers: false,
|
disableLineNumbers: false,
|
||||||
// Whether code should 'wrap' with long lines or 'scroll'.
|
// Whether code should 'wrap' with long lines or 'scroll'.
|
||||||
overflow: "scroll",
|
overflow: "wrap",
|
||||||
// Normally you shouldn't need this prop, but if you don't provide a
|
// Normally you shouldn't need this prop, but if you don't provide a
|
||||||
// valid filename or your file doesn't have an extension you may want to
|
// valid filename or your file doesn't have an extension you may want to
|
||||||
// override the automatic detection. You can specify that language here:
|
// override the automatic detection. You can specify that language here:
|
||||||
|
|||||||
@@ -48,6 +48,71 @@
|
|||||||
border-width: 0;
|
border-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.scroller {
|
||||||
|
/* --fade-height: 1.5rem; */
|
||||||
|
/**/
|
||||||
|
/* --mask-top: linear-gradient(to bottom, transparent, black var(--fade-height)); */
|
||||||
|
/* --mask-bottom: linear-gradient(to top, transparent, black var(--fade-height)); */
|
||||||
|
/**/
|
||||||
|
/* mask-image: var(--mask-top), var(--mask-bottom); */
|
||||||
|
/* mask-repeat: no-repeat; */
|
||||||
|
/* mask-size: 100% var(--fade-height); */
|
||||||
|
|
||||||
|
animation: scroll-fade linear;
|
||||||
|
animation-timeline: scroll(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Define the keyframes for the mask.
|
||||||
|
These percentages now map to scroll positions:
|
||||||
|
0% = Scrolled to the top
|
||||||
|
100% = Scrolled to the bottom
|
||||||
|
*/
|
||||||
|
@keyframes scroll-fade {
|
||||||
|
/* At the very top (0% scroll) */
|
||||||
|
0% {
|
||||||
|
mask-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
black 90%,
|
||||||
|
/* Opaque, but start fade to bottom */ transparent 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A small amount scrolled (e.g., 5%)
|
||||||
|
This is where the top fade should be fully visible.
|
||||||
|
*/
|
||||||
|
5% {
|
||||||
|
mask-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent 0%,
|
||||||
|
black 10%,
|
||||||
|
/* Fade-in top */ black 90%,
|
||||||
|
/* Fade-out bottom */ transparent 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nearing the bottom (e.g., 95%)
|
||||||
|
The bottom fade should start disappearing.
|
||||||
|
*/
|
||||||
|
95% {
|
||||||
|
mask-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent 0%,
|
||||||
|
black 10%,
|
||||||
|
/* Fade-in top */ black 90%,
|
||||||
|
/* Fade-out bottom */ transparent 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* At the very bottom (100% scroll) */
|
||||||
|
100% {
|
||||||
|
mask-image: linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent 0%,
|
||||||
|
black 10% /* Opaque, but start fade from top */
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.truncate-start {
|
.truncate-start {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
Reference in New Issue
Block a user