mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
Add StreamingIndicator component and replace static streaming indicator in ChatArea
This commit is contained in:
parent
854aa2a98d
commit
2de8c683ac
2 changed files with 255 additions and 12 deletions
|
|
@ -3,6 +3,7 @@
|
|||
import { Services } from "Services/Services";
|
||||
import type { StreamingMarkdownService } from "Services/StreamingMarkdownService";
|
||||
import ChatAreaThought from "./ChatAreaThought.svelte";
|
||||
import StreamingIndicator from "./StreamingIndicator.svelte";
|
||||
|
||||
export let messages: Array<{id: string, content: string, isUser: boolean, isStreaming: boolean}> = [];
|
||||
export let chatContainer: HTMLDivElement;
|
||||
|
|
@ -98,7 +99,7 @@
|
|||
<!-- Streaming message: use action for initialization -->
|
||||
{#if message.isStreaming}
|
||||
<div use:streamingAction={message.id} class="streaming-content"></div>
|
||||
<span class="streaming-indicator">● ● ●</span>
|
||||
<StreamingIndicator/>
|
||||
<ChatAreaThought/>
|
||||
{:else}
|
||||
<!-- Static message: use traditional rendering -->
|
||||
|
|
@ -168,15 +169,4 @@
|
|||
min-height: 1em; /* Ensure the element exists for binding */
|
||||
}
|
||||
|
||||
.streaming-indicator {
|
||||
display: inline-block;
|
||||
color: var(--text-accent);
|
||||
animation: pulse 1.5s infinite;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 0.3; }
|
||||
50% { opacity: 1; }
|
||||
}
|
||||
</style>
|
||||
253
Components/StreamingIndicator.svelte
Normal file
253
Components/StreamingIndicator.svelte
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
<div class="container">
|
||||
<span class="📦"></span>
|
||||
<span class="📦"></span>
|
||||
<span class="📦"></span>
|
||||
<span class="📦"></span>
|
||||
<span class="📦"></span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--duration: 1.5s;
|
||||
--container-size: 100px;
|
||||
--box-size: 12px;
|
||||
--box-border-radius: 15%;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: var(--container-size);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.📦 {
|
||||
width: var(--box-size);
|
||||
height: var(--box-size);
|
||||
position: relative;
|
||||
display: block;
|
||||
transform-origin: -50% center;
|
||||
border-radius: var(--box-border-radius);
|
||||
}
|
||||
.📦:after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 85%, white 15%);
|
||||
border-radius: var(--box-border-radius);
|
||||
box-shadow: 0px 0px 8px 2px color-mix(in srgb, var(--interactive-accent) 40%, transparent 60%);
|
||||
}
|
||||
.📦:nth-child(1) {
|
||||
animation: slide var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(1):after {
|
||||
animation: color-change var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(2) {
|
||||
animation: flip-1 var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(2):after {
|
||||
animation: squidge-1 var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(3) {
|
||||
animation: flip-2 var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(3):after {
|
||||
animation: squidge-2 var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(4) {
|
||||
animation: flip-3 var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(4):after {
|
||||
animation: squidge-3 var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(5) {
|
||||
animation: flip-4 var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(5):after {
|
||||
animation: squidge-4 var(--duration) ease-in-out infinite alternate;
|
||||
}
|
||||
.📦:nth-child(2):after {
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 75%, white 25%);
|
||||
}
|
||||
.📦:nth-child(3):after {
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 80%, white 20%);
|
||||
}
|
||||
.📦:nth-child(4):after {
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 90%, white 10%);
|
||||
}
|
||||
.📦:nth-child(5):after {
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 95%, white 5%);
|
||||
}
|
||||
|
||||
@keyframes slide {
|
||||
0% {
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 70%, black 30%);
|
||||
transform: translatex(0vw);
|
||||
}
|
||||
100% {
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 95%, white 5%);
|
||||
transform: translatex(
|
||||
calc(var(--container-size) - (var(--box-size) * 1.25))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes color-change {
|
||||
0% {
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 70%, black 30%);
|
||||
}
|
||||
100% {
|
||||
background-color: color-mix(in srgb, var(--interactive-accent) 95%, white 5%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flip-1 {
|
||||
0%,
|
||||
15% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
35%,
|
||||
100% {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes squidge-1 {
|
||||
5% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(1) scaley(1);
|
||||
}
|
||||
15% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(1.3) scaley(0.7);
|
||||
}
|
||||
25%,
|
||||
20% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(0.8) scaley(1.4);
|
||||
}
|
||||
55%,
|
||||
100% {
|
||||
transform-origin: center top;
|
||||
transform: scalex(1) scaley(1);
|
||||
}
|
||||
40% {
|
||||
transform-origin: center top;
|
||||
transform: scalex(1.3) scaley(0.7);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flip-2 {
|
||||
0%,
|
||||
30% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
50%,
|
||||
100% {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes squidge-2 {
|
||||
20% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(1) scaley(1);
|
||||
}
|
||||
30% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(1.3) scaley(0.7);
|
||||
}
|
||||
40%,
|
||||
35% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(0.8) scaley(1.4);
|
||||
}
|
||||
70%,
|
||||
100% {
|
||||
transform-origin: center top;
|
||||
transform: scalex(1) scaley(1);
|
||||
}
|
||||
55% {
|
||||
transform-origin: center top;
|
||||
transform: scalex(1.3) scaley(0.7);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flip-3 {
|
||||
0%,
|
||||
45% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
65%,
|
||||
100% {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes squidge-3 {
|
||||
35% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(1) scaley(1);
|
||||
}
|
||||
45% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(1.3) scaley(0.7);
|
||||
}
|
||||
55%,
|
||||
50% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(0.8) scaley(1.4);
|
||||
}
|
||||
85%,
|
||||
100% {
|
||||
transform-origin: center top;
|
||||
transform: scalex(1) scaley(1);
|
||||
}
|
||||
70% {
|
||||
transform-origin: center top;
|
||||
transform: scalex(1.3) scaley(0.7);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flip-4 {
|
||||
0%,
|
||||
60% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
80%,
|
||||
100% {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes squidge-4 {
|
||||
50% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(1) scaley(1);
|
||||
}
|
||||
60% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(1.3) scaley(0.7);
|
||||
}
|
||||
70%,
|
||||
65% {
|
||||
transform-origin: center bottom;
|
||||
transform: scalex(0.8) scaley(1.4);
|
||||
}
|
||||
100%,
|
||||
100% {
|
||||
transform-origin: center top;
|
||||
transform: scalex(1) scaley(1);
|
||||
}
|
||||
85% {
|
||||
transform-origin: center top;
|
||||
transform: scalex(1.3) scaley(0.7);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in a new issue