From f4a9a304fca02d2e21b62c6a6c32a0ac3c0ce0b8 Mon Sep 17 00:00:00 2001 From: Mike Fortman Date: Fri, 24 Oct 2025 16:27:39 -0500 Subject: [PATCH] Update branding --- frontend/components/logo/dog-icon.tsx | 73 ++++- .../app/chat/components/assistant-message.tsx | 4 +- frontend/src/app/chat/page.tsx | 4 +- .../components/progress-bar.tsx | 2 +- .../ui/animated-processing-icon.tsx | 272 ++++++++++++++---- 5 files changed, 285 insertions(+), 70 deletions(-) diff --git a/frontend/components/logo/dog-icon.tsx b/frontend/components/logo/dog-icon.tsx index 03158f17..ca53eabb 100644 --- a/frontend/components/logo/dog-icon.tsx +++ b/frontend/components/logo/dog-icon.tsx @@ -3,20 +3,77 @@ interface DogIconProps extends React.SVGProps { } const DogIcon = ({ disabled = false, stroke, ...props }: DogIconProps) => { - const fillColor = disabled ? "#71717A" : (stroke || "#22A7AF"); + const fillColor = disabled ? "#71717A" : (stroke || "#773EFF"); + + // CSS for the stepped animation states + const animationCSS = ` + .state1 { animation: showState1 600ms infinite; } + .state2 { animation: showState2 600ms infinite; } + .state3 { animation: showState3 600ms infinite; } + .state4 { animation: showState4 600ms infinite; } + + @keyframes showState1 { + 0%, 24.99% { opacity: 1; } + 25%, 100% { opacity: 0; } + } + + @keyframes showState2 { + 0%, 24.99% { opacity: 0; } + 25%, 49.99% { opacity: 1; } + 50%, 100% { opacity: 0; } + } + + @keyframes showState3 { + 0%, 49.99% { opacity: 0; } + 50%, 74.99% { opacity: 1; } + 75%, 100% { opacity: 0; } + } + + @keyframes showState4 { + 0%, 74.99% { opacity: 0; } + 75%, 100% { opacity: 1; } + } + `; return ( disabled ? ( - + - + ) : ( - - - - - + + + + + + {/* State 1 - Add 14px left padding to align with state 3 */} + + + + + + + + {/* State 2 - Add 14px left padding to align with state 3 */} + + + + + + {/* State 3 - Already properly positioned */} + + + + + + + + {/* State 4 - Add 14px left padding to align with state 3 */} + + + + ) ) diff --git a/frontend/src/app/chat/components/assistant-message.tsx b/frontend/src/app/chat/components/assistant-message.tsx index 4c600517..2ed8c168 100644 --- a/frontend/src/app/chat/components/assistant-message.tsx +++ b/frontend/src/app/chat/components/assistant-message.tsx @@ -17,6 +17,7 @@ interface AssistantMessageProps { showForkButton?: boolean; onFork?: (e: React.MouseEvent) => void; isCompleted?: boolean; + isInactive?: boolean; animate?: boolean; delay?: number; } @@ -31,6 +32,7 @@ export function AssistantMessage({ showForkButton = false, onFork, isCompleted = false, + isInactive = false, animate = true, delay = 0.2, }: AssistantMessageProps) { @@ -47,7 +49,7 @@ export function AssistantMessage({
} diff --git a/frontend/src/app/chat/page.tsx b/frontend/src/app/chat/page.tsx index 5c7ac6d5..d55eae03 100644 --- a/frontend/src/app/chat/page.tsx +++ b/frontend/src/app/chat/page.tsx @@ -1209,7 +1209,7 @@ function ChatPage() { className="space-y-6 group" > = 2 @@ -1241,6 +1241,7 @@ function ChatPage() { showForkButton={endpoint === "chat"} onFork={(e) => handleForkConversation(index, e)} animate={false} + isInactive={index < messages.length - 1} /> )} @@ -1257,6 +1258,7 @@ function ChatPage() { onToggle={toggleFunctionCall} delay={0.4} isStreaming + isCompleted={false} /> )} diff --git a/frontend/src/app/new-onboarding/components/progress-bar.tsx b/frontend/src/app/new-onboarding/components/progress-bar.tsx index e54224c5..419a2ae4 100644 --- a/frontend/src/app/new-onboarding/components/progress-bar.tsx +++ b/frontend/src/app/new-onboarding/components/progress-bar.tsx @@ -14,7 +14,7 @@ export function ProgressBar({ currentStep, totalSteps }: ProgressBarProps) { className="h-full transition-all duration-300 ease-in-out" style={{ width: `${progressPercentage}%`, - background: 'linear-gradient(to right, #818CF8, #22A7AF)' + background: 'linear-gradient(to right, #773EFF, #22A7AF)' }} /> diff --git a/frontend/src/components/ui/animated-processing-icon.tsx b/frontend/src/components/ui/animated-processing-icon.tsx index 431202c1..3ae24caf 100644 --- a/frontend/src/components/ui/animated-processing-icon.tsx +++ b/frontend/src/components/ui/animated-processing-icon.tsx @@ -1,70 +1,224 @@ -import { cn } from "@/lib/utils"; -import { motion, easeInOut } from "framer-motion"; - -export const AnimatedProcessingIcon = ({ +const AnimatedProcessingIcon = ({ className, + props, }: { className?: string; + props?: React.SVGProps; }) => { - const createAnimationFrames = (delay: number) => ({ - opacity: [1, 1, 0.5, 0], // Opacity Steps - transition: { - delay, - duration: 1, - ease: easeInOut, - repeat: Infinity, - times: [0, 0.33, 0.66, 1], // Duration Percentages that Correspond to opacity Array - }, - }); + // CSS for the stepped animation states + const animationCSS = ` + .state-1 { opacity: 1; animation: showState1 1.5s infinite steps(1, end); } + .state-2 { opacity: 0; animation: showState2 1.5s infinite steps(1, end); } + .state-3 { opacity: 0; animation: showState3 1.5s infinite steps(1, end); } + .state-4 { opacity: 0; animation: showState4 1.5s infinite steps(1, end); } + .state-5 { opacity: 0; animation: showState5 1.5s infinite steps(1, end); } + .state-6 { opacity: 0; animation: showState6 1.5s infinite steps(1, end); } + + @keyframes showState1 { + 0%, 16.66% { opacity: 1; } + 16.67%, 100% { opacity: 0; } + } + + @keyframes showState2 { + 0%, 16.66% { opacity: 0; } + 16.67%, 33.33% { opacity: 1; } + 33.34%, 100% { opacity: 0; } + } + + @keyframes showState3 { + 0%, 33.33% { opacity: 0; } + 33.34%, 50% { opacity: 1; } + 50.01%, 100% { opacity: 0; } + } + + @keyframes showState4 { + 0%, 50% { opacity: 0; } + 50.01%, 66.66% { opacity: 1; } + 66.67%, 100% { opacity: 0; } + } + + @keyframes showState5 { + 0%, 66.66% { opacity: 0; } + 66.67%, 83.33% { opacity: 1; } + 83.34%, 100% { opacity: 0; } + } + + @keyframes showState6 { + 0%, 83.33% { opacity: 0; } + 83.34%, 100% { opacity: 1; } + } + `; return ( - - - - - - + {/* Inject animation styles into the SVG's shadow */} + + + {/* State 1 */} + + + + + {/* State 2 */} + + + + + + + + + + {/* State 3 */} + + + + + + + + + + + + + + + {/* State 4 */} + + + + + + + + + + + + + + + + + + + + + + {/* State 5 */} + + + + + + + + + + + + + + + + + {/* State 6 */} + + + + + + + + + + ); }; + +export default AnimatedProcessingIcon; \ No newline at end of file