Skip to content

Commit abafd5d

Browse files
Update UI of the three demos: faqGen, VisualQnA, and DocSum. (opea-project#1528)
Signed-off-by: WenjiaoYue <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 970b869 commit abafd5d

File tree

11 files changed

+179
-91
lines changed

11 files changed

+179
-91
lines changed

DocSum/ui/gradio/docsum_ui_gradio.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,8 @@ def render(self):
296296
audio_ui.render()
297297
with gr.TabItem("Upload Video"):
298298
video_ui.render()
299-
with gr.TabItem("Enter URL"):
300-
url_ui.render()
299+
# with gr.TabItem("Enter URL"):
300+
# url_ui.render()
301301

302302
return self.demo
303303

FaqGen/ui/svelte/src/lib/shared/Network.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export async function fetchTextStream(query: string | Blob, params: string, file
5252
}
5353
const reader = postResponse.body.getReader();
5454
const decoder = new TextDecoder("utf-8");
55+
5556
let done, value;
5657

5758
let buffer = ""; // Initialize a buffer
@@ -61,6 +62,7 @@ export async function fetchTextStream(query: string | Blob, params: string, file
6162

6263
// Decode chunk and append to buffer
6364
const chunk = decoder.decode(value, { stream: true });
65+
6466
buffer += chunk;
6567

6668
// Use regex to clean and extract data
@@ -72,6 +74,21 @@ export async function fetchTextStream(query: string | Blob, params: string, file
7274
})
7375
.filter((line) => line); // Remove empty lines
7476

77+
const validJsonChunks = cleanedChunks.filter((item) => {
78+
if (item === "[DONE]") {
79+
return true;
80+
}
81+
try {
82+
JSON.parse(item);
83+
return true;
84+
} catch (e) {
85+
return false;
86+
}
87+
});
88+
89+
cleanedChunks.length = 0;
90+
cleanedChunks.push(...validJsonChunks);
91+
7592
for (const cleanedChunk of cleanedChunks) {
7693
// Further clean to ensure all unnecessary parts are removed
7794
yield cleanedChunk.replace(/^b'|['"]$/g, ""); // Again clean 'b' and other single or double quotes

FaqGen/ui/svelte/src/routes/+page.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
urlSuffix: string,
3737
params: string
3838
) => {
39+
messages = "";
3940
// Fetch the stream
4041
const eventStream = await fetchTextStream(
4142
query,

VisualQnA/ui/svelte/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@tailwindcss/typography": "0.5.7",
2424
"@types/debug": "4.1.7",
2525
"@types/node": "^20.12.13",
26+
"@types/pica": "^9.0.5",
2627
"@typescript-eslint/eslint-plugin": "^5.27.0",
2728
"@typescript-eslint/parser": "^5.27.0",
2829
"autoprefixer": "^10.4.16",
@@ -51,6 +52,7 @@
5152
"flowbite-svelte-icons": "^1.4.0",
5253
"fuse.js": "^6.6.2",
5354
"lodash": "^4.17.21",
55+
"pica": "^9.0.1",
5456
"playwright": "^1.44.0",
5557
"ramda": "^0.29.0",
5658
"sse.js": "^0.6.1",
-61.1 KB
Binary file not shown.
303 KB
Loading
-93.3 KB
Binary file not shown.
230 KB
Loading

VisualQnA/ui/svelte/src/lib/modules/chat/ChatMessage.svelte

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@
3131
class={msg.role === 0
3232
? "flex w-full gap-3"
3333
: "flex w-full items-center gap-3"}
34-
data-testid={msg.role === 0
35-
? "display-answer"
36-
: "display-question"}
34+
data-testid={msg.role === 0 ? "display-answer" : "display-question"}
3735
>
3836
<div
3937
class={msg.role === 0
@@ -44,10 +42,15 @@
4442
</div>
4543
<div class="group relative flex items-start">
4644
<div class="flex flex-col items-start">
47-
<img src={msg.imgSrc} alt="Uploaded Image" class="m-2 max-w-28 max-h-28" />
48-
45+
{#if msg.imgSrc}
46+
<img
47+
src={msg.imgSrc}
48+
alt="Uploaded Image"
49+
class="max-w-28 m-2 max-h-28"
50+
/>
51+
{/if}
4952
<p
50-
class="xl:max-w-[65vw] max-w-[60vw] items-start whitespace-pre-line break-keep text-[0.8rem] leading-5 sm:max-w-[50rem]"
53+
class="max-w-[60vw] items-start whitespace-pre-line break-keep text-[0.8rem] leading-5 sm:max-w-[50rem] xl:max-w-[65vw]"
5154
>
5255
{@html msg.content}
5356
</p>

VisualQnA/ui/svelte/src/lib/modules/upload/imagePrompt.svelte

Lines changed: 78 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,93 +5,98 @@
55

66
<script>
77
import { createEventDispatcher } from "svelte";
8-
import extreme_ironing from '$lib/assets/imageData/extreme_ironing.jpg';
9-
import waterview from '$lib/assets/imageData/waterview.jpg';
8+
import extreme_ironing from "$lib/assets/imageData/extreme_ironing.png";
9+
import waterview from "$lib/assets/imageData/waterview.png";
1010
import { base64ImageStore } from "$lib/shared/stores/common/Store";
1111
12-
let dispatch = createEventDispatcher();
12+
let dispatch = createEventDispatcher();
1313
14-
let images = [
15-
{
16-
id: 1,
17-
alt: 'Waterview',
18-
imgurl: waterview,
19-
prompt: 'What are the things I should be cautious about when I visit here?'
20-
},
21-
{
22-
id: 0,
23-
alt: 'Extreme Ironing',
24-
imgurl: extreme_ironing,
25-
prompt: 'What is unusual about this image?'
26-
}
27-
];
14+
let images = [
15+
{
16+
id: 1,
17+
alt: "Waterview",
18+
imgurl: waterview,
19+
prompt:
20+
"What are the things I should be cautious about when I visit here?",
21+
},
22+
{
23+
id: 0,
24+
alt: "Extreme Ironing",
25+
imgurl: extreme_ironing,
26+
prompt: "What is unusual about this image?",
27+
},
28+
];
2829
29-
let currentIndex = 0;
30+
let currentIndex = 0;
3031
31-
function nextImage() {
32-
currentIndex = (currentIndex + 1) % images.length;
33-
}
32+
function nextImage() {
33+
currentIndex = (currentIndex + 1) % images.length;
34+
}
3435
35-
function prevImage() {
36-
currentIndex = (currentIndex - 1 + images.length) % images.length;
37-
}
36+
function prevImage() {
37+
currentIndex = (currentIndex - 1 + images.length) % images.length;
38+
}
3839
40+
async function handleImageClick() {
41+
const imgUrl = images[currentIndex].imgurl;
3942
40-
async function handleImageClick() {
41-
const imgUrl = images[currentIndex].imgurl;
42-
const base64Data = await convertImageToBase64(imgUrl);
43-
const currentPrompt = images[currentIndex].prompt;
44-
dispatch("imagePrompt", { content: currentPrompt });
45-
base64ImageStore.set(base64Data);
46-
}
43+
const base64Data = await convertImageToBase64(imgUrl);
4744
48-
async function convertImageToBase64(url) {
49-
const response = await fetch(url);
50-
const blob = await response.blob();
51-
return new Promise((resolve, reject) => {
52-
const reader = new FileReader();
53-
reader.onloadend = () => resolve(reader.result);
54-
reader.onerror = reject;
55-
reader.readAsDataURL(blob);
56-
});
57-
}
45+
base64ImageStore.set(base64Data);
46+
47+
const currentPrompt = images[currentIndex].prompt;
48+
dispatch("imagePrompt", { content: currentPrompt });
49+
}
50+
51+
async function convertImageToBase64(url) {
52+
const response = await fetch(url);
53+
const blob = await response.blob();
54+
return new Promise((resolve, reject) => {
55+
const reader = new FileReader();
56+
reader.onloadend = () => resolve(reader.result);
57+
reader.onerror = reject;
58+
reader.readAsDataURL(blob);
59+
});
60+
}
5861
</script>
5962

60-
<div class="flex w-full flex-col gap-3 rounded-xl bg-white p-5 my-2">
61-
<p>Example</p>
62-
<div class="relative w-full max-w-4xl mx-auto">
63-
<button
64-
class="absolute left-0 top-1/2 transform -translate-y-1/2 z-10 w-8 h-8 rounded-full sm:w-10 sm:h-10 bg-white/30 dark:bg-gray-800/30 group-hover:bg-white/50 dark:group-hover:bg-gray-800/60 group-focus:ring-4 group-focus:ring-white dark:group-focus:ring-gray-800/70 group-focus:outline-none"
65-
on:click={prevImage}
66-
aria-label="Previous image"
67-
>
68-
&#10094;
69-
</button>
63+
<div class="my-2 flex w-full flex-col gap-3 rounded-xl bg-white p-5">
64+
<p>Example</p>
65+
<div class="relative mx-auto w-full max-w-4xl">
66+
<button
67+
class="absolute left-0 top-1/2 z-10 h-8 w-8 -translate-y-1/2 transform rounded-full bg-white/30 group-hover:bg-white/50 group-focus:outline-none group-focus:ring-4 group-focus:ring-white dark:bg-gray-800/30 dark:group-hover:bg-gray-800/60 dark:group-focus:ring-gray-800/70 sm:h-10 sm:w-10"
68+
on:click={prevImage}
69+
aria-label="Previous image"
70+
>
71+
&#10094;
72+
</button>
7073

71-
<div class="relative">
72-
<img
73-
src={images[currentIndex].imgurl}
74-
alt={images[currentIndex].alt}
75-
class="carousel-image w-full h-auto cursor-pointer"
76-
on:click={handleImageClick}
77-
/>
78-
<div class="absolute bottom-0 left-0 bg-opacity-55 bg-black text-white p-3 w-full">
79-
<p>{images[currentIndex].prompt}</p>
80-
</div>
81-
</div>
74+
<div class="relative">
75+
<img
76+
src={images[currentIndex].imgurl}
77+
alt={images[currentIndex].alt}
78+
class="carousel-image h-auto w-full cursor-pointer"
79+
on:click={handleImageClick}
80+
/>
81+
<div
82+
class="absolute bottom-0 left-0 w-full bg-black bg-opacity-55 p-3 text-white"
83+
>
84+
<p>{images[currentIndex].prompt}</p>
85+
</div>
86+
</div>
8287

83-
<button
84-
class="absolute right-0 top-1/2 transform -translate-y-1/2 z-10 w-8 h-8 rounded-full sm:w-10 sm:h-10 bg-white/30 dark:bg-gray-800/30 group-hover:bg-white/50 dark:group-hover:bg-gray-800/60 group-focus:ring-4 group-focus:ring-white dark:group-focus:ring-gray-800/70 group-focus:outline-none"
85-
on:click={nextImage}
86-
aria-label="Next image"
87-
>
88-
&#10095;
89-
</button>
90-
</div>
88+
<button
89+
class="absolute right-0 top-1/2 z-10 h-8 w-8 -translate-y-1/2 transform rounded-full bg-white/30 group-hover:bg-white/50 group-focus:outline-none group-focus:ring-4 group-focus:ring-white dark:bg-gray-800/30 dark:group-hover:bg-gray-800/60 dark:group-focus:ring-gray-800/70 sm:h-10 sm:w-10"
90+
on:click={nextImage}
91+
aria-label="Next image"
92+
>
93+
&#10095;
94+
</button>
95+
</div>
9196
</div>
9297

9398
<style>
94-
.relative img {
95-
object-fit: cover;
96-
}
99+
.relative img {
100+
object-fit: cover;
101+
}
97102
</style>

0 commit comments

Comments
 (0)