Spaces:
Build error
Build error
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
|