Spaces:
Running
Running
| <script lang="ts"> | |
| import { onMount, afterUpdate } from "svelte"; | |
| import gsap from "gsap"; | |
| import type { ChatMessage } from "../../models/chat-data"; | |
| import MessageContent from "./MessageContent.svelte"; | |
| export let message: ChatMessage; | |
| let messageRef: HTMLDivElement; | |
| let hasAnimated = false; | |
| onMount(() => { | |
| if (messageRef && !hasAnimated) { | |
| const isUser = message.role === 'user'; | |
| const tl = gsap.timeline(); | |
| tl.fromTo(messageRef, | |
| { | |
| opacity: 0, | |
| y: isUser ? 5 : 10, | |
| x: isUser ? 8 : -8, | |
| scale: 0.98 | |
| }, | |
| { | |
| opacity: 1, | |
| y: 0, | |
| x: 0, | |
| scale: 1, | |
| duration: 0.35, | |
| ease: "power2.out" | |
| } | |
| ); | |
| if (!isUser) { | |
| tl.fromTo(messageRef.querySelector('.message-content'), | |
| { | |
| opacity: 0, | |
| borderLeftWidth: "0px" | |
| }, | |
| { | |
| opacity: 1, | |
| borderLeftWidth: "2px", | |
| duration: 0.3, | |
| ease: "power2.out" | |
| }, | |
| "-=0.2" | |
| ); | |
| } | |
| hasAnimated = true; | |
| } | |
| }); | |
| afterUpdate(() => { | |
| if (messageRef && !message.streaming && message.role === 'assistant' && hasAnimated) { | |
| const borderEl = messageRef.querySelector('.message-content') as HTMLElement; | |
| if (borderEl && !borderEl.dataset.completed) { | |
| borderEl.dataset.completed = "true"; | |
| gsap.to(borderEl, { | |
| borderLeftColor: "rgba(76, 175, 80, 0.4)", | |
| duration: 0.3, | |
| yoyo: true, | |
| repeat: 1, | |
| ease: "power2.inOut", | |
| onComplete: () => { | |
| gsap.set(borderEl, { borderLeftColor: "rgba(139, 115, 85, 0.08)" }); | |
| } | |
| }); | |
| } | |
| } | |
| }); | |
| </script> | |
| <div class="message {message.role}" bind:this={messageRef}> | |
| <div class="message-content"> | |
| <MessageContent {message} /> | |
| </div> | |
| </div> | |
| <style> | |
| .message { | |
| padding: 0.375rem 0.5rem; | |
| position: relative; | |
| } | |
| .message-content { | |
| position: relative; | |
| } | |
| .message.user { | |
| opacity: 0.9; | |
| } | |
| .message.user .message-content { | |
| padding-left: 0.5rem; | |
| border-left: 2px solid rgba(124, 152, 133, 0.3); | |
| } | |
| .message.assistant { | |
| opacity: 1; | |
| } | |
| .message.assistant .message-content { | |
| padding-left: 0.5rem; | |
| border-left: 2px solid rgba(139, 115, 85, 0.08); | |
| } | |
| </style> |