mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-06-26 17:42:15 +00:00
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
This commit is contained in:
parent
e6876aabd5
commit
38f7e9c2c4
@ -5,6 +5,7 @@ import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
|||||||
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
|
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
|
||||||
import { service } from "@ember/service";
|
import { service } from "@ember/service";
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import { or } from "truth-helpers";
|
||||||
import CookText from "discourse/components/cook-text";
|
import CookText from "discourse/components/cook-text";
|
||||||
import DButton from "discourse/components/d-button";
|
import DButton from "discourse/components/d-button";
|
||||||
import DModal from "discourse/components/d-modal";
|
import DModal from "discourse/components/d-modal";
|
||||||
@ -41,6 +42,10 @@ export default class ModalDiffModal extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get diffResult() {
|
get diffResult() {
|
||||||
|
if (this.loading) {
|
||||||
|
return this.escapedSelectedText;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.diffStreamer.diff?.length > 0) {
|
if (this.diffStreamer.diff?.length > 0) {
|
||||||
return this.diffStreamer.diff;
|
return this.diffStreamer.diff;
|
||||||
}
|
}
|
||||||
@ -50,10 +55,22 @@ export default class ModalDiffModal extends Component {
|
|||||||
return this.escapedSelectedText;
|
return this.escapedSelectedText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get smoothStreamerResult() {
|
||||||
|
if (this.loading) {
|
||||||
|
return this.escapedSelectedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.smoothStreamer.renderedText;
|
||||||
|
}
|
||||||
|
|
||||||
get isStreaming() {
|
get isStreaming() {
|
||||||
// diffStreamer stops Streaming when it is finished with a chunk, looking at isDone is safe
|
// diffStreamer stops Streaming when it is finished with a chunk, looking at isDone is safe
|
||||||
// it starts off not done
|
// it starts off not done
|
||||||
return !this.diffStreamer.isDone || this.smoothStreamer.isStreaming;
|
if (this.args.model.showResultAsDiff) {
|
||||||
|
return !this.diffStreamer.isDone;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.smoothStreamer.isStreaming;
|
||||||
}
|
}
|
||||||
|
|
||||||
get primaryBtnLabel() {
|
get primaryBtnLabel() {
|
||||||
@ -154,11 +171,6 @@ export default class ModalDiffModal extends Component {
|
|||||||
{{willDestroy this.cleanup}}
|
{{willDestroy this.cleanup}}
|
||||||
class="text-preview"
|
class="text-preview"
|
||||||
>
|
>
|
||||||
{{#if this.loading}}
|
|
||||||
<div class="composer-ai-helper-modal__loading">
|
|
||||||
{{~@model.selectedText~}}
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
<div
|
<div
|
||||||
class={{concatClass
|
class={{concatClass
|
||||||
"composer-ai-helper-modal__suggestion"
|
"composer-ai-helper-modal__suggestion"
|
||||||
@ -166,30 +178,30 @@ export default class ModalDiffModal extends Component {
|
|||||||
(if this.isStreaming "streaming")
|
(if this.isStreaming "streaming")
|
||||||
(if @model.showResultAsDiff "inline-diff")
|
(if @model.showResultAsDiff "inline-diff")
|
||||||
(if this.diffStreamer.isThinking "thinking")
|
(if this.diffStreamer.isThinking "thinking")
|
||||||
|
(if this.loading "composer-ai-helper-modal__loading")
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{{~#if @model.showResultAsDiff~}}
|
{{~#if @model.showResultAsDiff~}}
|
||||||
<span class="diff-inner">{{htmlSafe this.diffResult}}</span>
|
<span class="diff-inner">{{htmlSafe this.diffResult}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if this.smoothStreamer.isStreaming}}
|
{{#if (or this.loading this.smoothStreamer.isStreaming)}}
|
||||||
<CookText
|
<CookText
|
||||||
@rawText={{this.smoothStreamer.renderedText}}
|
@rawText={{this.smoothStreamerResult}}
|
||||||
class="cooked"
|
class="cooked"
|
||||||
/>
|
/>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="composer-ai-helper-modal__old-value">
|
<div class="composer-ai-helper-modal__old-value">
|
||||||
{{@model.selectedText}}
|
{{~this.escapedSelectedText~}}
|
||||||
</div>
|
</div>
|
||||||
<div class="composer-ai-helper-modal__new-value">
|
<div class="composer-ai-helper-modal__new-value">
|
||||||
<CookText
|
<CookText
|
||||||
@rawText={{this.smoothStreamer.renderedText}}
|
@rawText={{this.smoothStreamerResult}}
|
||||||
class="cooked"
|
class="cooked"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
</:body>
|
</:body>
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ mark.highlight {
|
|||||||
animation-name: mark-blink;
|
animation-name: mark-blink;
|
||||||
}
|
}
|
||||||
|
|
||||||
.composer-ai-helper-modal__loading {
|
.composer-ai-helper-modal__loading.inline-diff {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
@use "lib/viewport";
|
@use "lib/viewport";
|
||||||
|
|
||||||
.composer-ai-helper-modal {
|
.composer-ai-helper-modal {
|
||||||
.text-preview,
|
|
||||||
.inline-diff {
|
.inline-diff {
|
||||||
font-family: var(--d-font-family--monospace);
|
font-family: var(--d-font-family--monospace);
|
||||||
font-variant-ligatures: none;
|
font-variant-ligatures: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-preview,
|
||||||
|
.inline-diff {
|
||||||
ins {
|
ins {
|
||||||
background-color: var(--success-low);
|
background-color: var(--success-low);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@ -55,13 +57,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__old-value {
|
&__old-value {
|
||||||
background-color: var(--danger-low);
|
white-space: pre-wrap;
|
||||||
|
border-left: 2px solid var(--danger);
|
||||||
|
padding-left: 1rem;
|
||||||
color: var(--danger);
|
color: var(--danger);
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__new-value {
|
&__new-value {
|
||||||
background-color: var(--success-low);
|
border-left: 2px solid var(--success);
|
||||||
|
padding-left: 1rem;
|
||||||
color: var(--success);
|
color: var(--success);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +82,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.ai-composer-helper-menu {
|
.ai-composer-helper-menu {
|
||||||
padding: 0.25rem;
|
|
||||||
max-width: 25rem;
|
max-width: 25rem;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
@ -701,7 +705,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.5em 1rem;
|
padding: 0.7rem 1rem;
|
||||||
|
|
||||||
&:focus,
|
&:focus,
|
||||||
&:hover {
|
&:hover {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user