mirror of
https://ghfast.top/https://github.com/discourse/discourse-ai.git
synced 2026-07-17 11:46:28 +08:00
This update ensures topic title suggestions when suggesting from edit topic take into account the whole topic for more accurate title suggestions.
143 lines
3.9 KiB
Text
143 lines
3.9 KiB
Text
import Component from "@glimmer/component";
|
|
import { tracked } from "@glimmer/tracking";
|
|
import { fn } from "@ember/helper";
|
|
import { on } from "@ember/modifier";
|
|
import { action } from "@ember/object";
|
|
import DButton from "discourse/components/d-button";
|
|
import DropdownMenu from "discourse/components/dropdown-menu";
|
|
import { ajax } from "discourse/lib/ajax";
|
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
|
import { i18n } from "discourse-i18n";
|
|
import DMenu from "float-kit/components/d-menu";
|
|
import { MIN_CHARACTER_COUNT } from "../../lib/ai-helper-suggestions";
|
|
|
|
export default class AiTitleSuggester extends Component {
|
|
@tracked loading = false;
|
|
@tracked suggestions = null;
|
|
@tracked untriggers = [];
|
|
@tracked triggerIcon = "discourse-sparkles";
|
|
@tracked content = null;
|
|
|
|
get showSuggestionButton() {
|
|
const composerFields = document.querySelector(".composer-fields");
|
|
const editTopicTitleField = document.querySelector(".edit-topic-title");
|
|
|
|
this.content = this.args.composer?.reply;
|
|
const showTrigger =
|
|
this.content?.length > MIN_CHARACTER_COUNT ||
|
|
this.args.topicState === "edit";
|
|
|
|
if (composerFields) {
|
|
if (showTrigger) {
|
|
composerFields.classList.add("showing-ai-suggestions");
|
|
} else {
|
|
composerFields.classList.remove("showing-ai-suggestions");
|
|
}
|
|
}
|
|
|
|
if (editTopicTitleField) {
|
|
if (showTrigger) {
|
|
editTopicTitleField.classList.add("showing-ai-suggestions");
|
|
} else {
|
|
editTopicTitleField.classList.remove("showing-ai-suggestions");
|
|
}
|
|
}
|
|
|
|
return showTrigger;
|
|
}
|
|
|
|
@action
|
|
async loadSuggestions() {
|
|
if (this.suggestions && !this.dMenu.expanded) {
|
|
return this.suggestions;
|
|
}
|
|
|
|
this.loading = true;
|
|
this.triggerIcon = "spinner";
|
|
const data = {};
|
|
|
|
if (this.content) {
|
|
data.text = this.content;
|
|
} else {
|
|
data.topic_id = this.args.buffered.content.id;
|
|
}
|
|
|
|
try {
|
|
const { suggestions } = await ajax(
|
|
"/discourse-ai/ai-helper/suggest_title",
|
|
{
|
|
method: "POST",
|
|
data,
|
|
}
|
|
);
|
|
this.suggestions = suggestions;
|
|
} catch (error) {
|
|
popupAjaxError(error);
|
|
} finally {
|
|
this.loading = false;
|
|
this.triggerIcon = "rotate";
|
|
}
|
|
|
|
return this.suggestions;
|
|
}
|
|
|
|
@action
|
|
applySuggestion(suggestion) {
|
|
const model = this.args.composer ? this.args.composer : this.args.buffered;
|
|
if (!model) {
|
|
return;
|
|
}
|
|
|
|
model.set("title", suggestion);
|
|
this.dMenu.close();
|
|
}
|
|
|
|
@action
|
|
onRegisterApi(api) {
|
|
this.dMenu = api;
|
|
}
|
|
|
|
@action
|
|
onClose() {
|
|
this.triggerIcon = "discourse-sparkles";
|
|
}
|
|
|
|
<template>
|
|
{{#if this.showSuggestionButton}}
|
|
<DMenu
|
|
@title={{i18n "discourse_ai.ai_helper.suggest"}}
|
|
@icon={{this.triggerIcon}}
|
|
@identifier="ai-title-suggester"
|
|
@onClose={{this.onClose}}
|
|
@triggerClass="btn-transparent suggestion-button suggest-titles-button {{if
|
|
this.loading
|
|
'is-loading'
|
|
}}"
|
|
@contentClass="ai-suggestions-menu"
|
|
@onRegisterApi={{this.onRegisterApi}}
|
|
@modalForMobile={{true}}
|
|
@untriggers={{this.untriggers}}
|
|
{{on "click" this.loadSuggestions}}
|
|
>
|
|
<:content>
|
|
{{#unless this.loading}}
|
|
<DropdownMenu as |dropdown|>
|
|
{{#each this.suggestions as |suggestion index|}}
|
|
<dropdown.item>
|
|
<DButton
|
|
data-name={{suggestion}}
|
|
data-value={{index}}
|
|
title={{suggestion}}
|
|
@action={{fn this.applySuggestion suggestion}}
|
|
>
|
|
{{suggestion}}
|
|
</DButton>
|
|
</dropdown.item>
|
|
{{/each}}
|
|
</DropdownMenu>
|
|
{{/unless}}
|
|
</:content>
|
|
</DMenu>
|
|
{{/if}}
|
|
</template>
|
|
}
|