2023-11-03 07:30:09 -04:00
|
|
|
import Component from "@glimmer/component";
|
2023-10-23 10:41:36 -04:00
|
|
|
import { tracked } from "@glimmer/tracking";
|
|
|
|
import { action } from "@ember/object";
|
2023-12-12 12:28:39 -05:00
|
|
|
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
|
|
|
import willDestroy from "@ember/render-modifiers/modifiers/will-destroy";
|
|
|
|
import { inject as service } from "@ember/service";
|
2023-11-03 07:30:09 -04:00
|
|
|
import DButton from "discourse/components/d-button";
|
2023-10-23 10:41:36 -04:00
|
|
|
import { ajax } from "discourse/lib/ajax";
|
|
|
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
2023-12-12 12:28:39 -05:00
|
|
|
import { bind } from "discourse-common/utils/decorators";
|
2023-11-03 07:30:09 -04:00
|
|
|
import eq from "truth-helpers/helpers/eq";
|
2023-11-17 12:25:41 -05:00
|
|
|
import not from "truth-helpers/helpers/not";
|
2023-12-12 12:28:39 -05:00
|
|
|
import AiHelperLoading from "../../components/ai-helper-loading";
|
2023-11-29 17:01:48 -05:00
|
|
|
import { showPostAIHelper } from "../../lib/show-ai-helper";
|
2023-10-23 10:41:36 -04:00
|
|
|
|
|
|
|
export default class AIHelperOptionsMenu extends Component {
|
|
|
|
static shouldRender(outletArgs, helper) {
|
|
|
|
return showPostAIHelper(outletArgs, helper);
|
|
|
|
}
|
2023-12-12 12:28:39 -05:00
|
|
|
@service messageBus;
|
2023-10-23 10:41:36 -04:00
|
|
|
@tracked helperOptions = [];
|
|
|
|
@tracked menuState = this.MENU_STATES.triggers;
|
|
|
|
@tracked loading = false;
|
|
|
|
@tracked suggestion = "";
|
|
|
|
@tracked showMainButtons = true;
|
|
|
|
|
2023-11-17 12:25:41 -05:00
|
|
|
@tracked copyButtonIcon = "copy";
|
|
|
|
@tracked copyButtonLabel = "discourse_ai.ai_helper.post_options_menu.copy";
|
|
|
|
|
2023-10-23 10:41:36 -04:00
|
|
|
MENU_STATES = {
|
|
|
|
triggers: "TRIGGERS",
|
|
|
|
options: "OPTIONS",
|
|
|
|
loading: "LOADING",
|
2023-11-03 07:30:09 -04:00
|
|
|
result: "RESULT",
|
2023-10-23 10:41:36 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
@tracked _activeAIRequest = null;
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
super(...arguments);
|
|
|
|
|
|
|
|
if (this.helperOptions.length === 0) {
|
|
|
|
this.loadPrompts();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
async showAIHelperOptions() {
|
|
|
|
this.showMainButtons = false;
|
|
|
|
this.menuState = this.MENU_STATES.options;
|
|
|
|
}
|
|
|
|
|
2023-12-12 12:28:39 -05:00
|
|
|
@bind
|
|
|
|
subscribe() {
|
|
|
|
const channel = `/discourse-ai/ai-helper/explain/${this.args.outletArgs.data.quoteState.postId}`;
|
|
|
|
this.messageBus.subscribe(channel, this._updateResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
@bind
|
|
|
|
unsubscribe() {
|
|
|
|
this.messageBus.unsubscribe(
|
|
|
|
"/discourse-ai/ai-helper/explain/*",
|
|
|
|
this._updateResult
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
@bind
|
|
|
|
_updateResult(result) {
|
|
|
|
const suggestion = result.result;
|
|
|
|
|
|
|
|
if (suggestion.length > 0) {
|
|
|
|
this.suggestion = suggestion;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-23 10:41:36 -04:00
|
|
|
@action
|
|
|
|
async performAISuggestion(option) {
|
|
|
|
this.menuState = this.MENU_STATES.loading;
|
|
|
|
|
|
|
|
if (option.name === "Explain") {
|
2023-12-12 12:28:39 -05:00
|
|
|
this.menuState = this.MENU_STATES.result;
|
|
|
|
|
|
|
|
const fetchUrl = `/discourse-ai/ai-helper/explain`;
|
|
|
|
this._activeAIRequest = ajax(fetchUrl, {
|
2023-10-23 10:41:36 -04:00
|
|
|
method: "POST",
|
|
|
|
data: {
|
|
|
|
mode: option.value,
|
|
|
|
text: this.args.outletArgs.data.quoteState.buffer,
|
2023-11-03 07:30:09 -04:00
|
|
|
post_id: this.args.outletArgs.data.quoteState.postId,
|
|
|
|
},
|
2023-10-23 10:41:36 -04:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this._activeAIRequest = ajax("/discourse-ai/ai-helper/suggest", {
|
|
|
|
method: "POST",
|
|
|
|
data: {
|
|
|
|
mode: option.value,
|
|
|
|
text: this.args.outletArgs.data.quoteState.buffer,
|
|
|
|
custom_prompt: "",
|
2023-11-03 07:30:09 -04:00
|
|
|
},
|
2023-10-23 10:41:36 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-12-12 12:28:39 -05:00
|
|
|
if (option.name !== "Explain") {
|
|
|
|
this._activeAIRequest
|
|
|
|
.then(({ suggestions }) => {
|
|
|
|
this.suggestion = suggestions[0];
|
|
|
|
})
|
|
|
|
.catch(popupAjaxError)
|
|
|
|
.finally(() => {
|
|
|
|
this.loading = false;
|
|
|
|
this.menuState = this.MENU_STATES.result;
|
|
|
|
});
|
|
|
|
}
|
2023-10-23 10:41:36 -04:00
|
|
|
|
|
|
|
return this._activeAIRequest;
|
|
|
|
}
|
|
|
|
|
|
|
|
@action
|
|
|
|
cancelAIAction() {
|
|
|
|
if (this._activeAIRequest) {
|
|
|
|
this._activeAIRequest.abort();
|
|
|
|
this._activeAIRequest = null;
|
|
|
|
this.loading = false;
|
|
|
|
this.menuState = this.MENU_STATES.options;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-17 12:25:41 -05:00
|
|
|
@action
|
|
|
|
copySuggestion() {
|
|
|
|
if (this.suggestion?.length > 0) {
|
|
|
|
navigator.clipboard.writeText(this.suggestion).then(() => {
|
|
|
|
this.copyButtonIcon = "check";
|
2023-11-29 17:01:48 -05:00
|
|
|
this.copyButtonLabel =
|
|
|
|
"discourse_ai.ai_helper.post_options_menu.copied";
|
2023-11-17 12:25:41 -05:00
|
|
|
setTimeout(() => {
|
|
|
|
this.copyButtonIcon = "copy";
|
2023-11-29 17:01:48 -05:00
|
|
|
this.copyButtonLabel =
|
|
|
|
"discourse_ai.ai_helper.post_options_menu.copy";
|
2023-11-17 12:25:41 -05:00
|
|
|
}, 3500);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-23 10:41:36 -04:00
|
|
|
async loadPrompts() {
|
|
|
|
let prompts = await ajax("/discourse-ai/ai-helper/prompts");
|
|
|
|
|
2023-11-03 07:30:09 -04:00
|
|
|
this.helperOptions = prompts
|
|
|
|
.filter((item) => item.location.includes("post"))
|
|
|
|
.map((p) => {
|
|
|
|
return {
|
|
|
|
name: p.translated_name,
|
|
|
|
value: p.id,
|
|
|
|
icon: p.icon,
|
|
|
|
};
|
|
|
|
});
|
2023-10-23 10:41:36 -04:00
|
|
|
}
|
2023-11-03 07:30:09 -04:00
|
|
|
|
|
|
|
<template>
|
|
|
|
{{#if this.showMainButtons}}
|
|
|
|
{{yield}}
|
|
|
|
{{/if}}
|
|
|
|
<div class="ai-post-helper">
|
|
|
|
{{#if (eq this.menuState this.MENU_STATES.triggers)}}
|
|
|
|
<DButton
|
|
|
|
@class="btn-flat ai-post-helper__trigger"
|
|
|
|
@icon="discourse-sparkles"
|
2023-12-05 15:33:10 -05:00
|
|
|
@title="discourse_ai.ai_helper.post_options_menu.title"
|
2023-11-03 07:30:09 -04:00
|
|
|
@label="discourse_ai.ai_helper.post_options_menu.trigger"
|
|
|
|
@action={{this.showAIHelperOptions}}
|
|
|
|
/>
|
|
|
|
|
|
|
|
{{else if (eq this.menuState this.MENU_STATES.options)}}
|
|
|
|
<div class="ai-post-helper__options">
|
|
|
|
{{#each this.helperOptions as |option|}}
|
|
|
|
<DButton
|
|
|
|
@class="btn-flat"
|
|
|
|
@icon={{option.icon}}
|
|
|
|
@translatedLabel={{option.name}}
|
|
|
|
@action={{this.performAISuggestion}}
|
|
|
|
@actionParam={{option}}
|
|
|
|
data-name={{option.name}}
|
|
|
|
data-value={{option.value}}
|
|
|
|
/>
|
|
|
|
{{/each}}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{{else if (eq this.menuState this.MENU_STATES.loading)}}
|
2023-12-12 12:28:39 -05:00
|
|
|
<AiHelperLoading @cancel={{this.cancelAIAction}} />
|
2023-11-03 07:30:09 -04:00
|
|
|
{{else if (eq this.menuState this.MENU_STATES.result)}}
|
2023-12-12 12:28:39 -05:00
|
|
|
<div
|
|
|
|
class="ai-post-helper__suggestion"
|
|
|
|
{{didInsert this.subscribe}}
|
|
|
|
{{willDestroy this.unsubscribe}}
|
|
|
|
>
|
|
|
|
{{#if this.suggestion}}
|
|
|
|
<div class="ai-post-helper__suggestion__text">
|
|
|
|
{{this.suggestion}}
|
|
|
|
</div>
|
|
|
|
<di class="ai-post-helper__suggestion__buttons">
|
|
|
|
<DButton
|
|
|
|
@class="btn-flat ai-post-helper__suggestion__cancel"
|
|
|
|
@icon="times"
|
|
|
|
@label="discourse_ai.ai_helper.post_options_menu.cancel"
|
|
|
|
@action={{this.cancelAIAction}}
|
|
|
|
/>
|
|
|
|
<DButton
|
|
|
|
@class="btn-flat ai-post-helper__suggestion__copy"
|
|
|
|
@icon={{this.copyButtonIcon}}
|
|
|
|
@label={{this.copyButtonLabel}}
|
|
|
|
@action={{this.copySuggestion}}
|
|
|
|
@disabled={{not this.suggestion}}
|
|
|
|
/>
|
|
|
|
</di>
|
|
|
|
{{else}}
|
|
|
|
<AiHelperLoading @cancel={{this.cancelAIAction}} />
|
|
|
|
{{/if}}
|
2023-11-17 12:25:41 -05:00
|
|
|
</div>
|
2023-11-03 07:30:09 -04:00
|
|
|
{{/if}}
|
|
|
|
</div>
|
|
|
|
</template>
|
2023-11-29 17:01:48 -05:00
|
|
|
}
|