diff --git a/packages/desktop/src/pages/index.tsx b/packages/desktop/src/pages/index.tsx index ac6b6f9c..341da2d9 100644 --- a/packages/desktop/src/pages/index.tsx +++ b/packages/desktop/src/pages/index.tsx @@ -670,98 +670,6 @@ export default function Page() { - {/* Response */} -
- - -
-

- - Hide steps - Show steps - -

- -
-
- -
- - {(assistantMessage) => { - const parts = createMemo(() => sync.data.part[assistantMessage.id]) - return - }} - -
-
-
- - {(_) => { - 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 ( -
- - - {(last) => { - const lastTextPart = createMemo(() => - sync.data.part[last().id].findLast((p) => p.type === "text"), - ) - return ( - - ) - }} - - - {(last) => { - const lastReasoningPart = createMemo(() => - sync.data.part[last().id].findLast( - (p) => p.type === "reasoning", - ), - ) - return ( - - ) - }} - - - - {(last) => { - const lastToolPart = createMemo(() => - sync.data.part[last().id].findLast( - (p) => p.type === "tool" && p.state.status === "completed", - ), - ) - return - }} - -
- ) - }} -
-
{/* Summary */}
@@ -817,6 +725,48 @@ export default function Page() {
+ {/* Response */} +
+ + +
+ + {(assistantMessage) => { + const parts = createMemo(() => sync.data.part[assistantMessage.id]) + return + }} + +
+
+ + + +
+
+ + Hide steps + Show steps + +
+ +
+
+ +
+ + {(assistantMessage) => { + const parts = createMemo( + () => sync.data.part[assistantMessage.id], + ) + return + }} + +
+
+
+
+
+
) }} diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx index 3eeab6d6..731b1bfe 100644 --- a/packages/ui/src/components/diff.tsx +++ b/packages/ui/src/components/diff.tsx @@ -54,18 +54,20 @@ export function Diff(props: DiffProps) { // When ready to render, simply call .render with old/new file, optional // annotations and a container element to hold the diff createEffect(() => { + // @ts-expect-error const instance = new FileDiff({ - theme: "pierre-light", + // theme: "pierre-light", + // theme: "pierre-light", // Or can also provide a 'themes' prop, which allows the code to adapt // 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' // or 'light' theme, or inherit from the OS ('system') theme. themeType: "system", // Disable the line numbers for your diffs, generally not recommended disableLineNumbers: false, // 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 // valid filename or your file doesn't have an extension you may want to // override the automatic detection. You can specify that language here: diff --git a/packages/ui/src/styles/utilities.css b/packages/ui/src/styles/utilities.css index 99b7760a..9c6b73f9 100644 --- a/packages/ui/src/styles/utilities.css +++ b/packages/ui/src/styles/utilities.css @@ -48,6 +48,71 @@ 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 { text-overflow: ellipsis; overflow: hidden;