From 5f597e79c89760cb49f65557c683ea74c74722e9 Mon Sep 17 00:00:00 2001 From: chezsmithy Date: Fri, 4 Jul 2025 14:47:22 -0700 Subject: [PATCH 1/3] refactor: :recycle: Refactor to use a single animated ellipsis component --- gui/src/components/AnimatedEllipsis.tsx | 24 +++++++++++ gui/src/components/index.ts | 20 +-------- .../Lump/LumpToolbar/GeneratingIndicator.tsx | 2 +- .../belowMainInput/ContextItemsPeek.tsx | 2 +- .../belowMainInput/ThinkingBlockPeek.tsx | 41 +++++-------------- .../IndexingProgressTitleText.tsx | 2 +- 6 files changed, 38 insertions(+), 53 deletions(-) create mode 100644 gui/src/components/AnimatedEllipsis.tsx diff --git a/gui/src/components/AnimatedEllipsis.tsx b/gui/src/components/AnimatedEllipsis.tsx new file mode 100644 index 00000000000..918ca17c879 --- /dev/null +++ b/gui/src/components/AnimatedEllipsis.tsx @@ -0,0 +1,24 @@ +import styled, { keyframes } from "styled-components"; + +const ellipsisAnimation = keyframes` + 0% { width: 0; } + 33% { width: 0.33em; } + 66% { width: 0.66em; } + 100% { width: 1em; } +`; + +export const AnimatedEllipsis = styled.span` + display: inline-block; + width: 1em; /* Fixed width to match the maximum animation width */ + + &::after { + content: "..."; + display: inline-block; + overflow: hidden; + vertical-align: bottom; + animation: ${ellipsisAnimation} 2s infinite; + width: 0; + } +`; + +export default AnimatedEllipsis; diff --git a/gui/src/components/index.ts b/gui/src/components/index.ts index 0b56a8d3507..6320a2c3e32 100644 --- a/gui/src/components/index.ts +++ b/gui/src/components/index.ts @@ -1,4 +1,4 @@ -import styled, { keyframes } from "styled-components"; +import styled from "styled-components"; import { varWithFallback } from "../styles/theme"; export const defaultBorderRadius = "0.5rem"; @@ -199,21 +199,3 @@ export const CloseButton = styled.button` justify-content: center; cursor: pointer; `; - -const ellipsisAnimation = keyframes` - 0% { width: 0; } - 33% { width: 0.33em; } - 66% { width: 0.66em; } - 100% { width: 1em; } -`; - -export const AnimatedEllipsis = styled.span` - &::after { - content: "..."; - display: inline-block; - overflow: hidden; - vertical-align: bottom; - animation: ${ellipsisAnimation} 2s infinite; - width: 0; - } -`; diff --git a/gui/src/components/mainInput/Lump/LumpToolbar/GeneratingIndicator.tsx b/gui/src/components/mainInput/Lump/LumpToolbar/GeneratingIndicator.tsx index 0f95a4e4050..620c2aacb12 100644 --- a/gui/src/components/mainInput/Lump/LumpToolbar/GeneratingIndicator.tsx +++ b/gui/src/components/mainInput/Lump/LumpToolbar/GeneratingIndicator.tsx @@ -1,4 +1,4 @@ -import { AnimatedEllipsis } from "../../.."; +import { AnimatedEllipsis } from "../../../AnimatedEllipsis"; export function GeneratingIndicator({ text = "Generating", diff --git a/gui/src/components/mainInput/belowMainInput/ContextItemsPeek.tsx b/gui/src/components/mainInput/belowMainInput/ContextItemsPeek.tsx index 8ba560ad620..d28e2b78e7c 100644 --- a/gui/src/components/mainInput/belowMainInput/ContextItemsPeek.tsx +++ b/gui/src/components/mainInput/belowMainInput/ContextItemsPeek.tsx @@ -3,13 +3,13 @@ import { ContextItemWithId } from "core"; import { ctxItemToRifWithContents } from "core/commands/util"; import { getUriPathBasename } from "core/util/uri"; import { ComponentType, useContext, useMemo } from "react"; -import { AnimatedEllipsis } from "../.."; import { IdeMessengerContext, IIdeMessenger, } from "../../../context/IdeMessenger"; import { useAppSelector } from "../../../redux/hooks"; import { selectIsGatheringContext } from "../../../redux/slices/sessionSlice"; +import { AnimatedEllipsis } from "../../AnimatedEllipsis"; import FileIcon from "../../FileIcon"; import SafeImg from "../../SafeImg"; import ToggleDiv from "../../ToggleDiv"; diff --git a/gui/src/components/mainInput/belowMainInput/ThinkingBlockPeek.tsx b/gui/src/components/mainInput/belowMainInput/ThinkingBlockPeek.tsx index 90f9fe885a5..ba423bbc480 100644 --- a/gui/src/components/mainInput/belowMainInput/ThinkingBlockPeek.tsx +++ b/gui/src/components/mainInput/belowMainInput/ThinkingBlockPeek.tsx @@ -4,8 +4,10 @@ import { ChevronUpIcon } from "@heroicons/react/24/solid"; import { ChatHistoryItem } from "core"; import { useEffect, useState } from "react"; import styled from "styled-components"; + import { defaultBorderRadius, lightGray, vscBackground } from "../.."; import { getFontSize } from "../../../util"; +import { AnimatedEllipsis } from "../../AnimatedEllipsis"; import StyledMarkdownPreview from "../../StyledMarkdownPreview"; const SpoilerButton = styled.div` @@ -36,34 +38,11 @@ const ButtonContent = styled.div` gap: 6px; `; -export const ThinkingText = styled.span` - position: relative; - padding-right: 12px; - - &:after { - content: "..."; - position: absolute; - animation: ellipsis 1s steps(4, end) infinite; - width: 0px; - display: inline-block; - overflow: hidden; - } +const ThinkingTextContainer = styled.span` + display: inline-block; + min-width: fit-content; - @keyframes ellipsis { - 0%, - 100% { - width: 0px; - } - 33% { - width: 8px; - } - 66% { - width: 16px; - } - 90% { - width: 24px; - } - } + padding-right: 1em; /* Reserve space for the ellipsis animation */ `; const MarkdownWrapper = styled.div` @@ -120,12 +99,13 @@ function ThinkingBlockPeek({ className="flex items-center justify-start pl-2 text-xs text-gray-300" data-testid="thinking-block-peek" > - setOpen((prev) => !prev)}> + setOpen(!open)}> {inProgress ? ( - + {redactedThinking ? "Redacted Thinking" : "Thinking"} - + + ) : redactedThinking ? ( "Redacted Thinking" ) : ( @@ -141,7 +121,6 @@ function ThinkingBlockPeek({ -
Date: Thu, 31 Jul 2025 13:25:22 -0700 Subject: [PATCH 2/3] fix: :label: Fixed typescript errors --- gui/src/components/StepContainer/ConversationSummary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/src/components/StepContainer/ConversationSummary.tsx b/gui/src/components/StepContainer/ConversationSummary.tsx index 6980ba5f751..173f78d0f54 100644 --- a/gui/src/components/StepContainer/ConversationSummary.tsx +++ b/gui/src/components/StepContainer/ConversationSummary.tsx @@ -2,7 +2,7 @@ import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/solid"; import { TrashIcon } from "@heroicons/react/24/outline"; import { ChatHistoryItem } from "core"; import { useState } from "react"; -import { AnimatedEllipsis } from "../"; +import { AnimatedEllipsis } from "../AnimatedEllipsis" import { useAppSelector } from "../../redux/hooks"; import StyledMarkdownPreview from "../StyledMarkdownPreview"; import { useDeleteCompaction } from "../../util/compactConversation"; From 68fd28fece115f70d463217d47f692e2972d5d5a Mon Sep 17 00:00:00 2001 From: chezsmithy Date: Thu, 31 Jul 2025 13:41:27 -0700 Subject: [PATCH 3/3] fix: :art: Prettier --- gui/src/components/StepContainer/ConversationSummary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/src/components/StepContainer/ConversationSummary.tsx b/gui/src/components/StepContainer/ConversationSummary.tsx index 173f78d0f54..5260da58fef 100644 --- a/gui/src/components/StepContainer/ConversationSummary.tsx +++ b/gui/src/components/StepContainer/ConversationSummary.tsx @@ -2,7 +2,7 @@ import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/solid"; import { TrashIcon } from "@heroicons/react/24/outline"; import { ChatHistoryItem } from "core"; import { useState } from "react"; -import { AnimatedEllipsis } from "../AnimatedEllipsis" +import { AnimatedEllipsis } from "../AnimatedEllipsis"; import { useAppSelector } from "../../redux/hooks"; import StyledMarkdownPreview from "../StyledMarkdownPreview"; import { useDeleteCompaction } from "../../util/compactConversation";