Add a more visible retry button on failure to generate (#530)
Browse files* Add a more visible retry button on failure to generate
* clean up props
* lint
* simplify
* color
* fix linting
---------
Co-authored-by: Victor Mustar <[email protected]>
src/lib/components/RetryBtn.svelte
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import CarbonRotate360 from "~icons/carbon/rotate-360";
|
3 |
+
|
4 |
+
export let classNames = "";
|
5 |
+
</script>
|
6 |
+
|
7 |
+
<button
|
8 |
+
type="button"
|
9 |
+
on:click
|
10 |
+
class="btn flex h-8 rounded-lg border bg-white px-3 py-1 text-gray-500 shadow-sm transition-all hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600 {classNames}"
|
11 |
+
>
|
12 |
+
<CarbonRotate360 class="mr-2 text-xs " /> Retry
|
13 |
+
</button>
|
src/lib/components/StopGeneratingBtn.svelte
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
<button
|
8 |
type="button"
|
9 |
on:click
|
10 |
-
class="btn flex h-
|
11 |
>
|
12 |
-
<CarbonStopFilledAlt class="-ml-1 mr-1 h-[1.25rem] w-[1.1875rem] text-gray-
|
13 |
</button>
|
|
|
7 |
<button
|
8 |
type="button"
|
9 |
on:click
|
10 |
+
class="btn flex h-8 rounded-lg border bg-white px-3 py-1 shadow-sm transition-all hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:hover:bg-gray-600 {classNames}"
|
11 |
>
|
12 |
+
<CarbonStopFilledAlt class="-ml-1 mr-1 h-[1.25rem] w-[1.1875rem] text-gray-300" /> Stop generating
|
13 |
</button>
|
src/lib/components/WebSearchToggle.svelte
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
</script>
|
8 |
|
9 |
<div
|
10 |
-
class="flex h-
|
11 |
on:click={toggle}
|
12 |
on:keypress={toggle}
|
13 |
aria-checked={$webSearchParameters.useSearch}
|
|
|
7 |
</script>
|
8 |
|
9 |
<div
|
10 |
+
class="flex h-8 cursor-pointer select-none items-center gap-2 rounded-lg border bg-white p-1.5 shadow-sm hover:shadow-none dark:border-gray-800 dark:bg-gray-900"
|
11 |
on:click={toggle}
|
12 |
on:keypress={toggle}
|
13 |
aria-checked={$webSearchParameters.useSearch}
|
src/lib/components/chat/ChatInput.svelte
CHANGED
@@ -46,6 +46,7 @@
|
|
46 |
tabindex="0"
|
47 |
rows="1"
|
48 |
class="scrollbar-custom absolute top-0 m-0 h-full w-full resize-none scroll-p-3 overflow-x-hidden overflow-y-scroll border-0 bg-transparent p-3 outline-none focus:ring-0 focus-visible:ring-0"
|
|
|
49 |
bind:value
|
50 |
bind:this={textareaElement}
|
51 |
{disabled}
|
|
|
46 |
tabindex="0"
|
47 |
rows="1"
|
48 |
class="scrollbar-custom absolute top-0 m-0 h-full w-full resize-none scroll-p-3 overflow-x-hidden overflow-y-scroll border-0 bg-transparent p-3 outline-none focus:ring-0 focus-visible:ring-0"
|
49 |
+
class:text-gray-400={disabled}
|
50 |
bind:value
|
51 |
bind:this={textareaElement}
|
52 |
{disabled}
|
src/lib/components/chat/ChatWindow.svelte
CHANGED
@@ -17,6 +17,7 @@
|
|
17 |
import type { WebSearchUpdate } from "$lib/types/MessageUpdate";
|
18 |
import { page } from "$app/stores";
|
19 |
import DisclaimerModal from "../DisclaimerModal.svelte";
|
|
|
20 |
|
21 |
export let messages: Message[] = [];
|
22 |
export let loading = false;
|
@@ -45,6 +46,8 @@
|
|
45 |
dispatch("message", message);
|
46 |
message = "";
|
47 |
};
|
|
|
|
|
48 |
</script>
|
49 |
|
50 |
<div class="relative min-h-0 min-w-0">
|
@@ -84,14 +87,21 @@
|
|
84 |
<div
|
85 |
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"
|
86 |
>
|
87 |
-
<div class="flex w-full pb-3
|
88 |
{#if settings?.searchEnabled}
|
89 |
<WebSearchToggle />
|
90 |
{/if}
|
91 |
{#if loading}
|
92 |
-
<StopGeneratingBtn
|
93 |
-
|
94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
/>
|
96 |
{/if}
|
97 |
</div>
|
@@ -101,19 +111,23 @@
|
|
101 |
{isReadOnly ? 'opacity-30' : ''}"
|
102 |
>
|
103 |
<div class="flex w-full flex-1 border-none bg-transparent">
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
|
|
|
|
|
|
|
|
117 |
|
118 |
{#if loading}
|
119 |
<button
|
|
|
17 |
import type { WebSearchUpdate } from "$lib/types/MessageUpdate";
|
18 |
import { page } from "$app/stores";
|
19 |
import DisclaimerModal from "../DisclaimerModal.svelte";
|
20 |
+
import RetryBtn from "../RetryBtn.svelte";
|
21 |
|
22 |
export let messages: Message[] = [];
|
23 |
export let loading = false;
|
|
|
46 |
dispatch("message", message);
|
47 |
message = "";
|
48 |
};
|
49 |
+
|
50 |
+
$: lastIsError = messages[messages.length - 1]?.from === "user" && !loading;
|
51 |
</script>
|
52 |
|
53 |
<div class="relative min-h-0 min-w-0">
|
|
|
87 |
<div
|
88 |
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"
|
89 |
>
|
90 |
+
<div class="flex w-full pb-3">
|
91 |
{#if settings?.searchEnabled}
|
92 |
<WebSearchToggle />
|
93 |
{/if}
|
94 |
{#if loading}
|
95 |
+
<StopGeneratingBtn classNames="ml-auto" on:click={() => dispatch("stop")} />
|
96 |
+
{/if}
|
97 |
+
{#if lastIsError}
|
98 |
+
<RetryBtn
|
99 |
+
classNames="ml-auto"
|
100 |
+
on:click={() =>
|
101 |
+
dispatch("retry", {
|
102 |
+
id: messages[messages.length - 1].id,
|
103 |
+
content: messages[messages.length - 1].content,
|
104 |
+
})}
|
105 |
/>
|
106 |
{/if}
|
107 |
</div>
|
|
|
111 |
{isReadOnly ? 'opacity-30' : ''}"
|
112 |
>
|
113 |
<div class="flex w-full flex-1 border-none bg-transparent">
|
114 |
+
{#if lastIsError}
|
115 |
+
<ChatInput value="Sorry, something went wrong. Please try again." disabled={true} />
|
116 |
+
{:else}
|
117 |
+
<ChatInput
|
118 |
+
placeholder="Ask anything"
|
119 |
+
bind:value={message}
|
120 |
+
on:submit={handleSubmit}
|
121 |
+
on:keypress={(ev) => {
|
122 |
+
if ($page.data.loginRequired) {
|
123 |
+
ev.preventDefault();
|
124 |
+
loginModalOpen = true;
|
125 |
+
}
|
126 |
+
}}
|
127 |
+
maxRows={4}
|
128 |
+
disabled={isReadOnly || lastIsError}
|
129 |
+
/>
|
130 |
+
{/if}
|
131 |
|
132 |
{#if loading}
|
133 |
<button
|