mirror of
https://github.com/OpenBankProject/API-Explorer-II.git
synced 2026-02-06 18:56:58 +00:00
add 'typing' indicator to opey messages
This commit is contained in:
parent
0504ff206e
commit
b192085aa3
@ -28,7 +28,11 @@ export default {
|
||||
message: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -93,7 +97,16 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="message-container">
|
||||
<div class="content" v-html="renderMarkdown(message.content)"></div>
|
||||
<div v-if="!loading" class="content" v-html="renderMarkdown(message.content)"></div>
|
||||
<div v-else class="content">
|
||||
<div class="ticontainer">
|
||||
<div class="tiblock">
|
||||
<div class="tidot"></div>
|
||||
<div class="tidot"></div>
|
||||
<div class="tidot"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="message.error" class="error"><el-icon><Warning /></el-icon> {{ message.error }}</div>
|
||||
</div>
|
||||
@ -167,4 +180,46 @@ export default {
|
||||
margin-top: -10px;
|
||||
margin-bottom: -10px;
|
||||
}
|
||||
|
||||
/* for the loading indicator */
|
||||
.tiblock {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
.ticontainer .tidot {
|
||||
background-color: #90949c;
|
||||
}
|
||||
|
||||
.tidot {
|
||||
animation: mercuryTypingAnimation 1.5s infinite ease-in-out;
|
||||
border-radius: 2px;
|
||||
display: inline-block;
|
||||
height: 4px;
|
||||
margin-right: 2px;
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
@keyframes mercuryTypingAnimation{
|
||||
0%{
|
||||
-webkit-transform:translateY(0px)
|
||||
}
|
||||
28%{
|
||||
-webkit-transform:translateY(-5px)
|
||||
}
|
||||
44%{
|
||||
-webkit-transform:translateY(0px)
|
||||
}
|
||||
}
|
||||
|
||||
.tidot:nth-child(1) {
|
||||
animation-delay:200ms;
|
||||
}
|
||||
.tidot:nth-child(2){
|
||||
animation-delay:300ms;
|
||||
}
|
||||
.tidot:nth-child(3){
|
||||
animation-delay:400ms;
|
||||
}
|
||||
</style>
|
||||
@ -120,7 +120,7 @@ export default {
|
||||
</div>
|
||||
<div v-else class="messages-container" v-bind:class="{ disabled: !chat.userIsAuthenticated }">
|
||||
<el-scrollbar>
|
||||
<ChatMessage v-for="message in chat.messages" :key="message.id" :message="message" />
|
||||
<ChatMessage v-for="message in chat.messages" :key="message.id" :message="message" :loading="message.loading" />
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</el-main>
|
||||
|
||||
@ -50,6 +50,7 @@ export interface OpeyMessage {
|
||||
role: "assistant" | "user" | "tool";
|
||||
content: string;
|
||||
error?: string;
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
export interface UserMessage extends OpeyMessage {
|
||||
|
||||
@ -44,7 +44,7 @@ export const useChat = defineStore('chat', {
|
||||
role: 'assistant',
|
||||
id: '',
|
||||
} as AssistantMessage,
|
||||
status: 'ready' as 'ready' | 'streaming' | 'error' | 'loading',
|
||||
status: 'ready' as 'ready' | 'streaming' | 'error',
|
||||
userIsAuthenticated: false,
|
||||
threadId: '',
|
||||
}
|
||||
@ -172,10 +172,13 @@ export const useChat = defineStore('chat', {
|
||||
content: '',
|
||||
role: 'assistant',
|
||||
id: uuidv4(),
|
||||
toolCalls: []
|
||||
toolCalls: [],
|
||||
loading: true,
|
||||
}
|
||||
this.addMessage(this.currentAssistantMessage)
|
||||
|
||||
// Set the status to 'loading' before we fetch the stream
|
||||
|
||||
// Handle stream
|
||||
try {
|
||||
const response = await fetch('/api/opey/stream', {
|
||||
@ -213,6 +216,7 @@ export const useChat = defineStore('chat', {
|
||||
},
|
||||
|
||||
async _processOpeyStream(stream: ReadableStream<Uint8Array>): Promise<void> {
|
||||
this.status = 'streaming'
|
||||
const reader = stream.getReader();
|
||||
let decoder = new TextDecoder();
|
||||
|
||||
@ -234,7 +238,7 @@ export const useChat = defineStore('chat', {
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ') && line !== 'data: [DONE]') {
|
||||
try {
|
||||
|
||||
|
||||
let data;
|
||||
const jsonStr = line.substring(6); // Remove 'data: '
|
||||
try {
|
||||
@ -292,6 +296,7 @@ export const useChat = defineStore('chat', {
|
||||
}
|
||||
|
||||
if (data.type === 'token' && data.content) {
|
||||
this.currentAssistantMessage.loading = false;
|
||||
// Append content to the current assistant message
|
||||
this.currentAssistantMessage.content += data.content;
|
||||
// Force Vue to detect the change
|
||||
@ -310,6 +315,7 @@ export const useChat = defineStore('chat', {
|
||||
role: 'assistant',
|
||||
content: '',
|
||||
toolCalls: [],
|
||||
loading: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user