Skip to content

Commit a0c7b9b

Browse files
Update ChatWindows with Filedropzone and hover effect
1 parent 54eb1b8 commit a0c7b9b

File tree

1 file changed

+93
-65
lines changed

1 file changed

+93
-65
lines changed

src/lib/components/chat/ChatWindow.svelte

Lines changed: 93 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import WebSearchToggle from "../WebSearchToggle.svelte";
1616
import type { WebSearchMessage } from "$lib/types/WebSearch";
1717
import LoginModal from "../LoginModal.svelte";
18+
import FileDropzone from "../FileDropzone.svelte";
1819
1920
export let messages: Message[] = [];
2021
export let loading = false;
@@ -44,6 +45,24 @@
4445
dispatch("message", message);
4546
message = "";
4647
};
48+
49+
let lastTarget: EventTarget | null = null;
50+
let onDrag = false;
51+
52+
const onDragEnter = (e: DragEvent) => {
53+
lastTarget = e.target;
54+
onDrag = true;
55+
};
56+
57+
const onDragLeave = (e: DragEvent) => {
58+
if (e.target === lastTarget) {
59+
onDrag = false;
60+
}
61+
};
62+
63+
const onDragOver = (e: DragEvent) => {
64+
e.preventDefault();
65+
};
4766
</script>
4867

4968
<div class="relative min-h-0 min-w-0">
@@ -69,78 +88,87 @@
6988
/>
7089
<div
7190
class="dark:via-gray-80 pointer-events-none absolute inset-x-0 bottom-0 z-0 mx-auto flex w-full max-w-3xl flex-col items-center justify-center bg-gradient-to-t from-white via-white/80 to-white/0 px-3.5 py-4 dark:border-gray-800 dark:from-gray-900 dark:to-gray-900/0 max-md:border-t max-md:bg-white max-md:dark:bg-gray-900 sm:px-5 md:py-8 xl:max-w-4xl [&>*]:pointer-events-auto"
91+
on:dragover={onDragOver}
92+
on:dragenter={onDragEnter}
93+
on:dragleave={onDragLeave}
7294
>
73-
<div class="flex w-full pb-3 max-md:justify-between">
74-
{#if settings?.searchEnabled}
75-
<WebSearchToggle />
76-
{/if}
77-
{#if loading}
78-
<StopGeneratingBtn
79-
classNames={settings?.searchEnabled ? "md:-translate-x-1/2 md:mx-auto" : "mx-auto"}
80-
on:click={() => dispatch("stop")}
81-
/>
82-
{/if}
83-
</div>
84-
<form
85-
on:submit|preventDefault={handleSubmit}
86-
class="relative flex w-full max-w-4xl flex-1 items-center rounded-xl border bg-gray-100 focus-within:border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:focus-within:border-gray-500
87-
{isReadOnly ? 'opacity-30' : ''}"
88-
>
89-
<div class="flex w-full flex-1 border-none bg-transparent">
90-
<ChatInput
91-
placeholder="Ask anything"
92-
bind:value={message}
93-
on:submit={handleSubmit}
94-
on:keypress={() => {
95-
if (loginRequired) loginModalOpen = true;
96-
}}
97-
maxRows={4}
98-
disabled={isReadOnly}
99-
/>
100-
95+
{#if onDrag}
96+
<FileDropzone bind:value={message} bind:onDrag />
97+
{:else}
98+
<div class="flex w-full pb-3 max-md:justify-between">
99+
{#if settings?.searchEnabled}
100+
<WebSearchToggle />
101+
{/if}
101102
{#if loading}
102-
<button
103-
class="btn mx-1 my-1 inline-block h-[2.4rem] self-end rounded-lg bg-transparent p-1 px-[0.7rem] text-gray-400 disabled:opacity-60 enabled:hover:text-gray-700 dark:disabled:opacity-40 enabled:dark:hover:text-gray-100 md:hidden"
103+
<StopGeneratingBtn
104+
classNames={settings?.searchEnabled ? "md:-translate-x-1/2 md:mx-auto" : "mx-auto"}
104105
on:click={() => dispatch("stop")}
105-
>
106-
<CarbonStopFilledAlt />
107-
</button>
108-
<div
109-
class="mx-1 my-1 hidden h-[2.4rem] items-center p-1 px-[0.7rem] text-gray-400 disabled:opacity-60 enabled:hover:text-gray-700 dark:disabled:opacity-40 enabled:dark:hover:text-gray-100 md:flex"
110-
>
111-
<EosIconsLoading />
112-
</div>
113-
{:else}
106+
/>
107+
{/if}
108+
</div>
109+
<form
110+
on:submit|preventDefault={handleSubmit}
111+
class="relative flex w-full max-w-4xl flex-1 items-center rounded-xl border bg-gray-100 focus-within:border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:focus-within:border-gray-500
112+
{isReadOnly ? 'opacity-30' : ''}"
113+
>
114+
<div class="flex w-full flex-1 border-none bg-transparent">
115+
<ChatInput
116+
placeholder="Ask anything"
117+
bind:value={message}
118+
on:submit={handleSubmit}
119+
on:keypress={() => {
120+
if (loginRequired) loginModalOpen = true;
121+
}}
122+
maxRows={4}
123+
disabled={isReadOnly}
124+
/>
125+
126+
{#if loading}
127+
<button
128+
class="btn mx-1 my-1 inline-block h-[2.4rem] self-end rounded-lg bg-transparent p-1 px-[0.7rem] text-gray-400 enabled:hover:text-gray-700 disabled:opacity-60 enabled:dark:hover:text-gray-100 dark:disabled:opacity-40 md:hidden"
129+
on:click={() => dispatch("stop")}
130+
>
131+
<CarbonStopFilledAlt />
132+
</button>
133+
<div
134+
class="mx-1 my-1 hidden h-[2.4rem] items-center p-1 px-[0.7rem] text-gray-400 enabled:hover:text-gray-700 disabled:opacity-60 enabled:dark:hover:text-gray-100 dark:disabled:opacity-40 md:flex"
135+
>
136+
<EosIconsLoading />
137+
</div>
138+
{:else}
139+
<button
140+
class="btn mx-1 my-1 h-[2.4rem] self-end rounded-lg bg-transparent p-1 px-[0.7rem] text-gray-400 enabled:hover:text-gray-700 disabled:opacity-60 enabled:dark:hover:text-gray-100 dark:disabled:opacity-40"
141+
disabled={!message || isReadOnly}
142+
type="submit"
143+
>
144+
<CarbonSendAltFilled />
145+
</button>
146+
{/if}
147+
</div>
148+
</form>
149+
<div
150+
class="mt-2 flex justify-between self-stretch px-1 text-xs text-gray-400/90 max-sm:gap-2"
151+
>
152+
<p>
153+
Model: <a
154+
href={currentModel.modelUrl || "https://huggingface.co/" + currentModel.name}
155+
target="_blank"
156+
rel="noreferrer"
157+
class="hover:underline">{currentModel.displayName}</a
158+
> <span class="max-sm:hidden">·</span><br class="sm:hidden" /> Generated content may be inaccurate
159+
or false.
160+
</p>
161+
{#if messages.length}
114162
<button
115-
class="btn mx-1 my-1 h-[2.4rem] self-end rounded-lg bg-transparent p-1 px-[0.7rem] text-gray-400 disabled:opacity-60 enabled:hover:text-gray-700 dark:disabled:opacity-40 enabled:dark:hover:text-gray-100"
116-
disabled={!message || isReadOnly}
117-
type="submit"
163+
class="flex flex-none items-center hover:text-gray-400 hover:underline max-sm:rounded-lg max-sm:bg-gray-50 max-sm:px-2.5 dark:max-sm:bg-gray-800"
164+
type="button"
165+
on:click={() => dispatch("share")}
118166
>
119-
<CarbonSendAltFilled />
167+
<CarbonExport class="text-[.6rem] sm:mr-1.5 sm:text-primary-500" />
168+
<div class="max-sm:hidden">Share this conversation</div>
120169
</button>
121170
{/if}
122171
</div>
123-
</form>
124-
<div class="mt-2 flex justify-between self-stretch px-1 text-xs text-gray-400/90 max-sm:gap-2">
125-
<p>
126-
Model: <a
127-
href={currentModel.modelUrl || "https://huggingface.co/" + currentModel.name}
128-
target="_blank"
129-
rel="noreferrer"
130-
class="hover:underline">{currentModel.displayName}</a
131-
> <span class="max-sm:hidden">·</span><br class="sm:hidden" /> Generated content may be inaccurate
132-
or false.
133-
</p>
134-
{#if messages.length}
135-
<button
136-
class="flex flex-none items-center hover:text-gray-400 hover:underline max-sm:rounded-lg max-sm:bg-gray-50 max-sm:px-2.5 dark:max-sm:bg-gray-800"
137-
type="button"
138-
on:click={() => dispatch("share")}
139-
>
140-
<CarbonExport class="text-[.6rem] sm:mr-1.5 sm:text-primary-500" />
141-
<div class="max-sm:hidden">Share this conversation</div>
142-
</button>
143-
{/if}
144-
</div>
172+
{/if}
145173
</div>
146174
</div>

0 commit comments

Comments
 (0)