@@ -13,6 +13,7 @@ import { ajax } from "discourse/lib/ajax";
13
13
import { popupAjaxError } from " discourse/lib/ajax-error" ;
14
14
import { bind } from " discourse/lib/decorators" ;
15
15
import { i18n } from " discourse-i18n" ;
16
+ import DiffStreamer from " ../../lib/diff-streamer" ;
16
17
import SmoothStreamer from " ../../lib/smooth-streamer" ;
17
18
import AiIndicatorWave from " ../ai-indicator-wave" ;
18
19
@@ -21,7 +22,7 @@ export default class ModalDiffModal extends Component {
21
22
@service messageBus;
22
23
23
24
@tracked loading = false ;
24
- @tracked diff ;
25
+ @tracked diffStreamer = new DiffStreamer ( this . args . model . selectedText ) ;
25
26
@tracked suggestion = " " ;
26
27
@tracked
27
28
smoothStreamer = new SmoothStreamer (
@@ -34,6 +35,20 @@ export default class ModalDiffModal extends Component {
34
35
this .suggestChanges ();
35
36
}
36
37
38
+ get isStreaming () {
39
+ return this .diffStreamer .isStreaming || this .smoothStreamer .isStreaming ;
40
+ }
41
+
42
+ get primaryBtnLabel () {
43
+ return this .loading
44
+ ? i18n (" discourse_ai.ai_helper.context_menu.loading" )
45
+ : i18n (" discourse_ai.ai_helper.context_menu.confirm" );
46
+ }
47
+
48
+ get primaryBtnDisabled () {
49
+ return this .loading || this .isStreaming ;
50
+ }
51
+
37
52
@bind
38
53
subscribe () {
39
54
const channel = " /discourse-ai/ai-helper/stream_composer_suggestion" ;
@@ -48,35 +63,22 @@ export default class ModalDiffModal extends Component {
48
63
49
64
@action
50
65
async updateResult (result ) {
51
- if (result) {
52
- this .loading = false ;
53
- }
54
- await this .smoothStreamer .updateResult (result, " result" );
66
+ this .loading = false ;
55
67
56
- if (result .done ) {
57
- this .diff = result .diff ;
58
- }
59
-
60
- const mdTablePromptId = this .currentUser ? .ai_helper_prompts .find (
61
- (prompt ) => prompt .name === " markdown_table"
62
- ).id ;
63
-
64
- // Markdown table prompt looks better with
65
- // before/after results than diff
66
- // despite having `type: diff`
67
- if (this .args .model .mode === mdTablePromptId) {
68
- this .diff = null ;
68
+ if (this .args .model .showResultAsDiff ) {
69
+ this .diffStreamer .updateResult (result, " result" );
70
+ } else {
71
+ this .smoothStreamer .updateResult (result, " result" );
69
72
}
70
73
}
71
74
72
75
@action
73
76
async suggestChanges () {
74
77
this .smoothStreamer .resetStreaming ();
75
- this .diff = null ;
76
- this .suggestion = " " ;
77
- this .loading = true ;
78
+ this .diffStreamer .reset ();
78
79
79
80
try {
81
+ this .loading = true ;
80
82
return await ajax (" /discourse-ai/ai-helper/stream_suggestion" , {
81
83
method: " POST" ,
82
84
data: {
@@ -89,8 +91,6 @@ export default class ModalDiffModal extends Component {
89
91
});
90
92
} catch (e) {
91
93
popupAjaxError (e);
92
- } finally {
93
- this .loading = false ;
94
94
}
95
95
}
96
96
@@ -104,6 +104,13 @@ export default class ModalDiffModal extends Component {
104
104
this .suggestion
105
105
);
106
106
}
107
+
108
+ if (this .args .model .showResultAsDiff && this .diffStreamer .suggestion ) {
109
+ this .args .model .toolbarEvent .replaceText (
110
+ this .args .model .selectedText ,
111
+ this .diffStreamer .suggestion
112
+ );
113
+ }
107
114
}
108
115
109
116
<template >
@@ -123,17 +130,18 @@ export default class ModalDiffModal extends Component {
123
130
class ={{concatClass
124
131
" composer-ai-helper-modal__suggestion"
125
132
" streamable-content"
126
- ( if this . smoothStreamer.isStreaming " streaming" " " )
133
+ ( if this . isStreaming " streaming" )
134
+ ( if @ model.showResultAsDiff " inline-diff" )
127
135
}}
128
136
>
129
- {{#if this . smoothStreamer.isStreaming }}
130
- <CookText
131
- @ rawText ={{this .smoothStreamer.renderedText }}
132
- class =" cooked"
133
- />
137
+ {{#if @ model.showResultAsDiff }}
138
+ {{htmlSafe this . diffStreamer.diff}}
134
139
{{else }}
135
- {{#if this . diff }}
136
- {{htmlSafe this . diff}}
140
+ {{#if this . smoothStreamer.isStreaming }}
141
+ <CookText
142
+ @ rawText ={{this .smoothStreamer.renderedText }}
143
+ class =" cooked"
144
+ />
137
145
{{else }}
138
146
<div class =" composer-ai-helper-modal__old-value" >
139
147
{{@ model.selectedText }}
@@ -152,32 +160,27 @@ export default class ModalDiffModal extends Component {
152
160
</: body >
153
161
154
162
<: footer >
155
- {{#if this . loading }}
156
- <DButton
157
- class =" btn-primary"
158
- @ label =" discourse_ai.ai_helper.context_menu.loading"
159
- @ disabled ={{ true }}
160
- >
163
+ <DButton
164
+ class =" btn-primary confirm"
165
+ @ disabled ={{this .primaryBtnDisabled }}
166
+ @ action ={{this .triggerConfirmChanges }}
167
+ @ translatedLabel ={{this .primaryBtnLabel }}
168
+ >
169
+ {{#if this . loading }}
161
170
<AiIndicatorWave @ loading ={{this .loading }} />
162
- </DButton >
163
- {{else }}
164
- <DButton
165
- class =" btn-primary confirm"
166
- @ action ={{this .triggerConfirmChanges }}
167
- @ label =" discourse_ai.ai_helper.context_menu.confirm"
168
- />
169
- <DButton
170
- class =" btn-flat discard"
171
- @ action ={{@ closeModal }}
172
- @ label =" discourse_ai.ai_helper.context_menu.discard"
173
- />
174
- <DButton
175
- class =" regenerate"
176
- @ icon =" arrows-rotate"
177
- @ action ={{this .suggestChanges }}
178
- @ label =" discourse_ai.ai_helper.context_menu.regen"
179
- />
180
- {{/if }}
171
+ {{/if }}
172
+ </DButton >
173
+ <DButton
174
+ class =" btn-flat discard"
175
+ @ action ={{@ closeModal }}
176
+ @ label =" discourse_ai.ai_helper.context_menu.discard"
177
+ />
178
+ <DButton
179
+ class =" regenerate"
180
+ @ icon =" arrows-rotate"
181
+ @ action ={{this .suggestChanges }}
182
+ @ label =" discourse_ai.ai_helper.context_menu.regen"
183
+ />
181
184
</: footer >
182
185
</DModal >
183
186
</template >
0 commit comments