Spaces:
Running
Running
Commit ·
b10d53b
1
Parent(s): aaf2031
commit updated code 26082025-01133
Browse files- public/favicon.ico +0 -0
- public/index.html +1 -1
- src/components/ChatApp.jsx +4 -2
- src/components/PipelineLoader.css +53 -0
- src/components/PipelineLoader.jsx +34 -0
public/favicon.ico
CHANGED
|
|
|
|
public/index.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
| 7 |
<meta name="theme-color" content="#000000" />
|
| 8 |
<meta
|
| 9 |
name="description"
|
| 10 |
-
content="
|
| 11 |
/>
|
| 12 |
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
| 13 |
<!--
|
|
|
|
| 7 |
<meta name="theme-color" content="#000000" />
|
| 8 |
<meta
|
| 9 |
name="description"
|
| 10 |
+
content="ChatMate is a friendly and conversational AI assistant"
|
| 11 |
/>
|
| 12 |
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
| 13 |
<!--
|
src/components/ChatApp.jsx
CHANGED
|
@@ -3,6 +3,7 @@ import React, { useState, useRef, useEffect } from 'react';
|
|
| 3 |
import MessageBubble from './MessageBubble';
|
| 4 |
import { Button , Typography, Box} from '@mui/material';
|
| 5 |
import { ChatBubbleOutline } from '@mui/icons-material';
|
|
|
|
| 6 |
export default function ChatApp() {
|
| 7 |
const [message, setMessage] = useState('');
|
| 8 |
const [history, setHistory] = useState([]);
|
|
@@ -121,11 +122,12 @@ setHistory(h => [...h, { role: 'assistant', content, time }]);
|
|
| 121 |
<MessageBubble key={i} {...msg} />
|
| 122 |
))}
|
| 123 |
|
| 124 |
-
|
| 125 |
<div className="typing-indicator">
|
| 126 |
<span className="dot"></span><span className="dot"></span><span className="dot"></span>
|
| 127 |
</div>
|
| 128 |
-
)}
|
|
|
|
| 129 |
|
| 130 |
<div ref={chatEndRef} />
|
| 131 |
</div>
|
|
|
|
| 3 |
import MessageBubble from './MessageBubble';
|
| 4 |
import { Button , Typography, Box} from '@mui/material';
|
| 5 |
import { ChatBubbleOutline } from '@mui/icons-material';
|
| 6 |
+
import PipelineLoader from './PipelineLoader';
|
| 7 |
export default function ChatApp() {
|
| 8 |
const [message, setMessage] = useState('');
|
| 9 |
const [history, setHistory] = useState([]);
|
|
|
|
| 122 |
<MessageBubble key={i} {...msg} />
|
| 123 |
))}
|
| 124 |
|
| 125 |
+
{/* {loading && (
|
| 126 |
<div className="typing-indicator">
|
| 127 |
<span className="dot"></span><span className="dot"></span><span className="dot"></span>
|
| 128 |
</div>
|
| 129 |
+
)} */}
|
| 130 |
+
{loading && <PipelineLoader />}
|
| 131 |
|
| 132 |
<div ref={chatEndRef} />
|
| 133 |
</div>
|
src/components/PipelineLoader.css
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.pipeline-loader {
|
| 2 |
+
display: flex;
|
| 3 |
+
align-items: center;
|
| 4 |
+
font-family: "Outfit", sans-serif;
|
| 5 |
+
font-size: 15px;
|
| 6 |
+
font-weight: 500;
|
| 7 |
+
color: #333;
|
| 8 |
+
}
|
| 9 |
+
|
| 10 |
+
.label {
|
| 11 |
+
margin-bottom: 6px;
|
| 12 |
+
transition: opacity 0.5s ease-in-out;
|
| 13 |
+
color: #fff;
|
| 14 |
+
display: inline-block;
|
| 15 |
+
vertical-align: middle;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
.fade {
|
| 19 |
+
opacity: 1;
|
| 20 |
+
animation: fadeIn 0.5s ease-in-out;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
@keyframes fadeIn {
|
| 24 |
+
from { opacity: 0; }
|
| 25 |
+
to { opacity: 1; }
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
/* Progress bar */
|
| 29 |
+
.flow {
|
| 30 |
+
width: 220px;
|
| 31 |
+
height: 6px;
|
| 32 |
+
background: #e9ecef;
|
| 33 |
+
border-radius: 6px;
|
| 34 |
+
position: relative;
|
| 35 |
+
overflow: hidden;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
.flow::before {
|
| 39 |
+
content: "";
|
| 40 |
+
position: absolute;
|
| 41 |
+
left: -40%;
|
| 42 |
+
width: 40%;
|
| 43 |
+
height: 100%;
|
| 44 |
+
background: linear-gradient(90deg, #4dabf7, #74c0fc, #4dabf7);
|
| 45 |
+
border-radius: 6px;
|
| 46 |
+
animation: moveFlow 1.5s linear infinite;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
@keyframes moveFlow {
|
| 50 |
+
0% { left: -40%; }
|
| 51 |
+
50% { left: 60%; }
|
| 52 |
+
100% { left: 110%; }
|
| 53 |
+
}
|
src/components/PipelineLoader.jsx
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React, { useEffect, useState } from "react";
|
| 2 |
+
import "./PipelineLoader.css";
|
| 3 |
+
|
| 4 |
+
const steps = [
|
| 5 |
+
"📡 Retrieving ",
|
| 6 |
+
"🧠 Analyzing ",
|
| 7 |
+
"🤖 Processing "
|
| 8 |
+
];
|
| 9 |
+
|
| 10 |
+
const PipelineLoader = () => {
|
| 11 |
+
const [stepIndex, setStepIndex] = useState(0);
|
| 12 |
+
|
| 13 |
+
useEffect(() => {
|
| 14 |
+
if (stepIndex < steps.length - 1) {
|
| 15 |
+
const timer = setTimeout(() => {
|
| 16 |
+
setStepIndex(stepIndex + 1);
|
| 17 |
+
}, 5000); // show each step for 2s
|
| 18 |
+
return () => clearTimeout(timer);
|
| 19 |
+
}
|
| 20 |
+
}, [stepIndex]);
|
| 21 |
+
|
| 22 |
+
return (
|
| 23 |
+
<div className="pipeline-loader">
|
| 24 |
+
|
| 25 |
+
{/* <div className="flow"></div> */}
|
| 26 |
+
<div className="typing-indicator">
|
| 27 |
+
<span className="label fade">{steps[stepIndex]}</span>
|
| 28 |
+
<span className="dot"></span><span className="dot"></span><span className="dot"></span>
|
| 29 |
+
</div>
|
| 30 |
+
</div>
|
| 31 |
+
);
|
| 32 |
+
};
|
| 33 |
+
|
| 34 |
+
export default PipelineLoader;
|