Skip to content

Commit 38f7e9c

Browse files
authored
UX: AI composer helper refinements (#1387)
This update includes a variety of small refinements to the AI composer helper: - prevent height jump when going from loading text placeholder → proofreading text streaming - update padding on AI helper options list to be more suitable with typical Discourse menu design - for composer helper results that are not `showResultAsDiff` (i.e. translation): - update before/after diff design to be more subtle - results should be in normal font (as the text is cooked and not raw markdown) - fix: smooth streaming animation stuck showing dot icon even after smooth streaming is done
1 parent e6876aa commit 38f7e9c

File tree

3 files changed

+54
-38
lines changed

3 files changed

+54
-38
lines changed

assets/javascripts/discourse/components/modal/diff-modal.gjs

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import didInsert from "@ember/render-modifiers/modifiers/did-insert";
55
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
66
import { service } from "@ember/service";
77
import { htmlSafe } from "@ember/template";
8+
import { or } from "truth-helpers";
89
import CookText from "discourse/components/cook-text";
910
import DButton from "discourse/components/d-button";
1011
import DModal from "discourse/components/d-modal";
@@ -41,6 +42,10 @@ export default class ModalDiffModal extends Component {
4142
}
4243

4344
get diffResult() {
45+
if (this.loading) {
46+
return this.escapedSelectedText;
47+
}
48+
4449
if (this.diffStreamer.diff?.length > 0) {
4550
return this.diffStreamer.diff;
4651
}
@@ -50,10 +55,22 @@ export default class ModalDiffModal extends Component {
5055
return this.escapedSelectedText;
5156
}
5257

58+
get smoothStreamerResult() {
59+
if (this.loading) {
60+
return this.escapedSelectedText;
61+
}
62+
63+
return this.smoothStreamer.renderedText;
64+
}
65+
5366
get isStreaming() {
5467
// diffStreamer stops Streaming when it is finished with a chunk, looking at isDone is safe
5568
// it starts off not done
56-
return !this.diffStreamer.isDone || this.smoothStreamer.isStreaming;
69+
if (this.args.model.showResultAsDiff) {
70+
return !this.diffStreamer.isDone;
71+
}
72+
73+
return this.smoothStreamer.isStreaming;
5774
}
5875

5976
get primaryBtnLabel() {
@@ -154,42 +171,37 @@ export default class ModalDiffModal extends Component {
154171
{{willDestroy this.cleanup}}
155172
class="text-preview"
156173
>
157-
{{#if this.loading}}
158-
<div class="composer-ai-helper-modal__loading">
159-
{{~@model.selectedText~}}
160-
</div>
161-
{{else}}
162-
<div
163-
class={{concatClass
164-
"composer-ai-helper-modal__suggestion"
165-
"streamable-content"
166-
(if this.isStreaming "streaming")
167-
(if @model.showResultAsDiff "inline-diff")
168-
(if this.diffStreamer.isThinking "thinking")
169-
}}
170-
>
171-
{{~#if @model.showResultAsDiff~}}
172-
<span class="diff-inner">{{htmlSafe this.diffResult}}</span>
174+
<div
175+
class={{concatClass
176+
"composer-ai-helper-modal__suggestion"
177+
"streamable-content"
178+
(if this.isStreaming "streaming")
179+
(if @model.showResultAsDiff "inline-diff")
180+
(if this.diffStreamer.isThinking "thinking")
181+
(if this.loading "composer-ai-helper-modal__loading")
182+
}}
183+
>
184+
{{~#if @model.showResultAsDiff~}}
185+
<span class="diff-inner">{{htmlSafe this.diffResult}}</span>
186+
{{else}}
187+
{{#if (or this.loading this.smoothStreamer.isStreaming)}}
188+
<CookText
189+
@rawText={{this.smoothStreamerResult}}
190+
class="cooked"
191+
/>
173192
{{else}}
174-
{{#if this.smoothStreamer.isStreaming}}
193+
<div class="composer-ai-helper-modal__old-value">
194+
{{~this.escapedSelectedText~}}
195+
</div>
196+
<div class="composer-ai-helper-modal__new-value">
175197
<CookText
176-
@rawText={{this.smoothStreamer.renderedText}}
198+
@rawText={{this.smoothStreamerResult}}
177199
class="cooked"
178200
/>
179-
{{else}}
180-
<div class="composer-ai-helper-modal__old-value">
181-
{{@model.selectedText}}
182-
</div>
183-
<div class="composer-ai-helper-modal__new-value">
184-
<CookText
185-
@rawText={{this.smoothStreamer.renderedText}}
186-
class="cooked"
187-
/>
188-
</div>
189-
{{/if}}
201+
</div>
190202
{{/if}}
191-
</div>
192-
{{/if}}
203+
{{/if}}
204+
</div>
193205
</div>
194206
</:body>
195207

assets/stylesheets/common/streaming.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ mark.highlight {
111111
animation-name: mark-blink;
112112
}
113113

114-
.composer-ai-helper-modal__loading {
114+
.composer-ai-helper-modal__loading.inline-diff {
115115
white-space: pre-wrap;
116116
}
117117

assets/stylesheets/modules/ai-helper/common/ai-helper.scss

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
@use "lib/viewport";
22

33
.composer-ai-helper-modal {
4-
.text-preview,
54
.inline-diff {
65
font-family: var(--d-font-family--monospace);
76
font-variant-ligatures: none;
7+
}
88

9+
.text-preview,
10+
.inline-diff {
911
ins {
1012
background-color: var(--success-low);
1113
text-decoration: none;
@@ -55,13 +57,16 @@
5557
}
5658

5759
&__old-value {
58-
background-color: var(--danger-low);
60+
white-space: pre-wrap;
61+
border-left: 2px solid var(--danger);
62+
padding-left: 1rem;
5963
color: var(--danger);
6064
margin-bottom: 1rem;
6165
}
6266

6367
&__new-value {
64-
background-color: var(--success-low);
68+
border-left: 2px solid var(--success);
69+
padding-left: 1rem;
6570
color: var(--success);
6671
}
6772

@@ -77,7 +82,6 @@
7782
}
7883

7984
.ai-composer-helper-menu {
80-
padding: 0.25rem;
8185
max-width: 25rem;
8286
list-style: none;
8387

@@ -701,7 +705,7 @@
701705
width: 100%;
702706
border-radius: 0;
703707
margin: 0;
704-
padding: 0.5em 1rem;
708+
padding: 0.7rem 1rem;
705709

706710
&:focus,
707711
&:hover {

0 commit comments

Comments
 (0)