Skip to content

Commit e48532e

Browse files
Add imagePrompt to display default image hint (opea-project#777)
Signed-off-by: Yue, Wenjiao <wenjiao.yue@intel.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent be8e283 commit e48532e

File tree

7 files changed

+207
-126
lines changed

7 files changed

+207
-126
lines changed

VisualQnA/ui/svelte/package.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
},
1414
"devDependencies": {
1515
"@fortawesome/free-solid-svg-icons": "6.2.0",
16-
"@playwright/test": "^1.45.2",
16+
"@playwright/test": "^1.33.0",
1717
"@sveltejs/adapter-auto": "1.0.0-next.75",
18-
"@sveltejs/kit": "^1.30.4",
18+
"@sveltejs/adapter-static": "^3.0.0",
19+
"@sveltejs/kit": "^2.0.0",
1920
"@tailwindcss/typography": "0.5.7",
2021
"@types/debug": "4.1.7",
22+
"@types/node": "^20.12.13",
2123
"@typescript-eslint/eslint-plugin": "^5.27.0",
2224
"@typescript-eslint/parser": "^5.27.0",
2325
"autoprefixer": "^10.4.7",
@@ -27,21 +29,20 @@
2729
"eslint": "^8.16.0",
2830
"eslint-config-prettier": "^8.3.0",
2931
"eslint-plugin-neverthrow": "1.1.4",
30-
"eslint-plugin-svelte3": "^4.0.0",
3132
"postcss": "^8.4.31",
3233
"postcss-load-config": "^4.0.1",
3334
"postcss-preset-env": "^8.3.2",
3435
"prettier": "^2.8.8",
3536
"prettier-plugin-svelte": "^2.7.0",
3637
"prettier-plugin-tailwindcss": "^0.3.0",
37-
"svelte": "^3.59.1",
38-
"svelte-check": "^2.7.1",
38+
"svelte": "^4.0.0",
39+
"svelte-check": "^3.0.0",
3940
"svelte-fa": "3.0.3",
40-
"svelte-preprocess": "^4.10.7",
41+
"svelte-preprocess": "^6.0.2",
4142
"tailwindcss": "^3.1.5",
4243
"tslib": "^2.3.1",
43-
"typescript": "^4.7.4",
44-
"vite": "^4.5.2"
44+
"typescript": "^5.0.0",
45+
"vite": "^5.0.0"
4546
},
4647
"type": "module",
4748
"dependencies": {
@@ -51,6 +52,7 @@
5152
"flowbite-svelte-icons": "^1.4.0",
5253
"fuse.js": "^6.6.2",
5354
"lodash": "^4.17.21",
55+
"playwright": "^1.44.0",
5456
"ramda": "^0.29.0",
5557
"sse.js": "^0.6.1",
5658
"svelte-notifications": "^0.9.98",

VisualQnA/ui/svelte/src/lib/assets/imageData/images.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
2525
export let msg: Message;
2626
export let time: string = "";
27-
console.log("msg", msg);
27+
export const imgSrc: string = "";
2828
</script>
2929

3030
<div
@@ -42,10 +42,12 @@
4242
>
4343
<MessageAvatar role={msg.role} />
4444
</div>
45-
<div class="group relative items-center">
46-
<div>
45+
<div class="group relative flex items-start">
46+
<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+
4749
<p
48-
class="xl:max-w-[65vw] max-w-[60vw] items-center whitespace-pre-line break-keep text-[0.8rem] leading-5 sm:max-w-[50rem]"
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]"
4951
>
5052
{@html msg.content}
5153
</p>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<!--
2+
Copyright (C) 2024 Intel Corporation
3+
SPDX-License-Identifier: Apache-2.0
4+
-->
5+
6+
<script>
7+
import { createEventDispatcher } from "svelte";
8+
import extreme_ironing from '$lib/assets/imageData/extreme_ironing.jpg';
9+
import waterview from '$lib/assets/imageData/waterview.jpg';
10+
import { base64ImageStore } from "$lib/shared/stores/common/Store";
11+
12+
let dispatch = createEventDispatcher();
13+
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+
];
28+
29+
let currentIndex = 0;
30+
31+
function nextImage() {
32+
currentIndex = (currentIndex + 1) % images.length;
33+
}
34+
35+
function prevImage() {
36+
currentIndex = (currentIndex - 1 + images.length) % images.length;
37+
}
38+
39+
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+
}
47+
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+
}
58+
</script>
59+
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>
70+
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>
82+
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>
91+
</div>
92+
93+
<style>
94+
.relative img {
95+
object-fit: cover;
96+
}
97+
</style>

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,3 @@
106106
<img src={imageUrl} alt="Uploaded Image" class="m-2 mx-auto block" />
107107
{/if}
108108
</Dropzone>
109-
110-
{#if value.length !== 0}
111-
<p class="bg-white p-2 text-center">{showFiles(value)}</p>
112-
{/if}

VisualQnA/ui/svelte/src/lib/shared/constant/Interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type Map<T> = T extends MessageType.Text | MessageType.SingleAudio
3535
: { imgSrc: string; imgId: string }[];
3636

3737
export interface Message {
38+
imgSrc: string | null | undefined;
3839
role: MessageRole;
3940
type: MessageType;
4041
content: Map<Message["type"]>;

0 commit comments

Comments
 (0)