|
2 | 2 | import InputComponent from './Input.svelte';
|
3 | 3 | import QuickSettingsDrawer from './QuickSettingsDrawer.svelte';
|
4 | 4 | import { Notice } from 'obsidian';
|
5 |
| - import { afterUpdate } from 'svelte'; |
6 | 5 | import DotAnimation from '../base/DotAnimation.svelte';
|
7 | 6 | import MessageContainer from './MessageContainer.svelte';
|
8 | 7 | import { t } from 'svelte-i18n';
|
9 |
| - import { |
10 |
| - papaState, |
11 |
| - chatHistory, |
12 |
| - isChatInSidebar, |
13 |
| - chatInput, |
14 |
| - isEditing, |
15 |
| - isEditingAssistantMessage, |
16 |
| - type ChatMessage, |
17 |
| - runContent, |
18 |
| - runState, |
19 |
| - data, |
20 |
| - } from '../../store'; |
| 8 | + import { papaState, chatHistory, chatInput, isEditing, isEditingAssistantMessage, type ChatMessage, runContent, runState, data } from '../../store'; |
21 | 9 | import {
|
22 | 10 | onClick,
|
23 | 11 | onMouseOver,
|
|
41 | 29 | }
|
42 | 30 | let contentNode: HTMLElement;
|
43 | 31 |
|
44 |
| - afterUpdate(() => { |
45 |
| - if (contentNode && $runState === 'generating' && $runContent) renderMarkdown(contentNode, $runContent); |
46 |
| - }); |
| 32 | + $: if (contentNode && ($runState === 'generating' || $runState === 'stopped') && $runContent) { |
| 33 | + renderMarkdown(contentNode, $runContent); |
| 34 | + } |
47 | 35 |
|
48 | 36 | $: if ($runState === 'retrieving' && $runContent == '0') {
|
49 | 37 | new Notice($t('notice.no_notes_retrieved'));
|
|
71 | 59 |
|
72 | 60 | <!-- svelte-ignore a11y-click-events-have-key-events -->
|
73 | 61 | <!-- svelte-ignore a11y-no-static-element-interactions -->
|
| 62 | +<!-- svelte-ignore a11y-mouse-events-have-key-events --> |
74 | 63 | <div class="--background-modifier-border flex h-full flex-col gap-1">
|
75 | 64 | <QuickSettingsDrawer />
|
76 | 65 | <div
|
77 | 66 | bind:this={chatWindow}
|
78 | 67 | on:scroll={() => (isAutoScrolling = chatWindow.scrollTop + chatWindow.clientHeight + 1 >= chatWindow.scrollHeight)}
|
79 |
| - class="chat-window w-full flex-grow select-text overflow-y-scroll rounded-md border border-solid border-[--background-modifier-border] {$isChatInSidebar |
80 |
| - ? 'bg-[--background-secondary]' |
81 |
| - : 'bg-[--background-primary]'}" |
| 68 | + class="chat-window w-full flex-grow select-text overflow-y-scroll rounded-md border border-solid border-[--background-modifier-border] bg-[--background-primary]" |
82 | 69 | >
|
83 | 70 | {#each $chatHistory as message (message.id)}
|
84 | 71 | <MessageContainer role={message.role}>
|
85 | 72 | {#if message.role === 'User'}
|
86 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
87 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
88 |
| - <!-- svelte-ignore a11y-mouse-events-have-key-events --> |
89 | 73 | <span bind:this={editElem} on:mouseover={onMouseOver} on:click={onClick} use:renderMarkdown={message.content} />
|
90 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
91 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
92 | 74 | <div class="flex {$data.isChatComfy ? 'justify-end' : ''} gap-1 opacity-0 group-hover:opacity-100">
|
93 | 75 | {#if $isEditing && editMessageId === message.id}
|
94 | 76 | <span aria-label={$t('chat.copy')} class={iconStyle} on:click|preventDefault={cancelEditing} use:icon={'x-circle'} />
|
95 | 77 | {:else}
|
96 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
97 | 78 | <span
|
98 | 79 | aria-label={$t('chat.edit')}
|
99 | 80 | class={iconStyle}
|
|
103 | 84 | {/if}
|
104 | 85 | </div>
|
105 | 86 | {:else}
|
106 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
107 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
108 |
| - <!-- svelte-ignore a11y-mouse-events-have-key-events --> |
109 | 87 | <span on:mouseover={onMouseOver} use:renderMarkdown={message.content} on:click={onClick} bind:this={initialAssistantMessageSpan} />
|
110 | 88 | <div class="flex gap-1 opacity-0 group-hover:opacity-100">
|
111 | 89 | {#if !$isEditingAssistantMessage}
|
112 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
113 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
114 | 90 | <span aria-label={$t('chat.copy')} class={iconStyle} on:click={() => toClipboard(message.content)} use:icon={'copy'} />
|
115 | 91 | {#if $chatHistory.indexOf(message) !== 0}
|
116 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
117 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
118 | 92 | <span
|
119 | 93 | aria-label={$t('chat.regenerate')}
|
120 | 94 | class={iconStyle}
|
|
123 | 97 | />
|
124 | 98 | {/if}
|
125 | 99 | {#if $chatHistory.length === 1}
|
126 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
127 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
128 | 100 | <span
|
129 | 101 | aria-label={$t('chat.change_assistant_prompt')}
|
130 | 102 | class={iconStyle}
|
|
133 | 105 | />
|
134 | 106 | {/if}
|
135 | 107 | {:else}
|
136 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
137 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
138 | 108 | <span
|
139 | 109 | aria-label={$t('chat.cancel_edit')}
|
140 | 110 | class={iconStyle}
|
141 | 111 | on:click|preventDefault={() => cancelEditingInitialAssistantMessage(initialAssistantMessageSpan)}
|
142 | 112 | use:icon={'x-circle'}
|
143 | 113 | />
|
144 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
145 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
146 | 114 | <span
|
147 | 115 | aria-label={$t('chat.reset_assistant_prompt')}
|
148 | 116 | class={iconStyle}
|
|
162 | 130 | <p>{$t('chat.retrieving')}<DotAnimation /></p>
|
163 | 131 | {:else if $runState === 'reducing'}
|
164 | 132 | <p>{$t('chat.reducing', { values: { num: $runContent } })}<DotAnimation /></p>
|
165 |
| - {:else if $runState === 'generating' && $runContent} |
166 |
| - <!-- svelte-ignore a11y-click-events-have-key-events --> |
167 |
| - <!-- svelte-ignore a11y-no-static-element-interactions --> |
168 |
| - <!-- svelte-ignore a11y-mouse-events-have-key-events --> |
| 133 | + {:else if $runState === 'generating'} |
169 | 134 | <span bind:this={contentNode} style="background: transparent;" />
|
170 | 135 | {/if}
|
171 | 136 | </MessageContainer>
|
| 137 | + {:else if $papaState === 'idle' && $runState === 'stopped'} |
| 138 | + <MessageContainer role="Assistant"> |
| 139 | + <span bind:this={contentNode} style="background: transparent;" /> |
| 140 | + <p>{$t('chat.stopped')}</p> |
| 141 | + <span |
| 142 | + aria-label={$t('chat.regenerate')} |
| 143 | + class={iconStyle + ' opacity-0 group-hover:opacity-100'} |
| 144 | + on:click|preventDefault={() => redoGeneration()} |
| 145 | + use:icon={'refresh-cw'} |
| 146 | + /> |
| 147 | + </MessageContainer> |
172 | 148 | {/if}
|
173 | 149 | </div>
|
174 | 150 | <InputComponent bind:textarea />
|
|
0 commit comments