Compare commits

...
6 changed files with 68 additions and 42 deletions
@@ -3,9 +3,25 @@ import { LinkTo } from "@ember/routing";
import dIcon from "discourse-common/helpers/d-icon"; import dIcon from "discourse-common/helpers/d-icon";
import i18n from "discourse-common/helpers/i18n"; import i18n from "discourse-common/helpers/i18n";
function showAiPreferences(user, siteSettings) {
// Since we only have one AI related user setting we don't show
// AI preferences if these don't conditions aren't met.
// If we add more user settings in the future we can move this
// logic to the the specific settins and conditionally show it in the template.
const userGroups = user.groups.map((g) => g.id);
const captionGroups = siteSettings.ai_auto_image_caption_allowed_groups
.split("|")
.map((id) => parseInt(id, 10));
return userGroups.some((groupId) => captionGroups.includes(groupId));
}
export default class AutoImageCaptionSetting extends Component { export default class AutoImageCaptionSetting extends Component {
static shouldRender(outletArgs, helper) { static shouldRender(outletArgs, helper) {
return helper.siteSettings.discourse_ai_enabled; return (
helper.siteSettings.discourse_ai_enabled &&
showAiPreferences(outletArgs.model, helper.siteSettings)
);
} }
<template> <template>
@@ -11,15 +11,6 @@ export default class PreferencesAiController extends Controller {
@service siteSettings; @service siteSettings;
@tracked saved = false; @tracked saved = false;
get canToggleAutoImageCaption() {
const userGroups = this.model.groups.map((g) => g.id);
const captionGroups = this.siteSettings.ai_auto_image_caption_allowed_groups
.split("|")
.map((id) => parseInt(id, 10));
return userGroups.some((groupId) => captionGroups.includes(groupId));
}
@action @action
save() { save() {
this.saved = false; this.saved = false;
@@ -1,24 +1,17 @@
<label class="control-label">{{i18n "discourse_ai.title"}}</label> <label class="control-label">{{i18n "discourse_ai.title"}}</label>
{{#if this.canToggleAutoImageCaption}} <div class="control-group ai-setting">
<div class="control-group ai-setting"> <PreferenceCheckbox
<PreferenceCheckbox @labelKey="discourse_ai.ai_helper.image_caption.automatic_caption_setting"
@labelKey="discourse_ai.ai_helper.image_caption.automatic_caption_setting" @checked={{this.model.user_option.auto_image_caption}}
@checked={{this.model.user_option.auto_image_caption}} data-setting-name="auto-image-caption"
data-setting-name="auto-image-caption" class="pref-auto-image-caption"
class="pref-auto-image-caption" />
/> </div>
</div>
<SaveControls <SaveControls
@id="user_ai_preference_save" @id="user_ai_preference_save"
@model={{this.model}} @model={{this.model}}
@action={{this.save}} @action={{this.save}}
@saved={{this.saved}} @saved={{this.saved}}
/> />
{{else}}
<EmptyState
@title={{i18n "discourse_ai.user_preferences.empty_state.title"}}
@body={{i18n "discourse_ai.user_preferences.empty_state.body"}}
/>
{{/if}}
@@ -161,6 +161,11 @@ export default apiInitializer("1.25.0", (api) => {
const imageUploads = composer.model.reply.match(IMAGE_MARKDOWN_REGEX); const imageUploads = composer.model.reply.match(IMAGE_MARKDOWN_REGEX);
const hasImageUploads = imageUploads?.length > 0; const hasImageUploads = imageUploads?.length > 0;
if (!hasImageUploads) {
resolve();
}
const imagesToCaption = imageUploads.filter((image) => { const imagesToCaption = imageUploads.filter((image) => {
const caption = image const caption = image
.substring(image.indexOf("[") + 1, image.indexOf("]")) .substring(image.indexOf("[") + 1, image.indexOf("]"))
@@ -181,12 +186,7 @@ export default apiInitializer("1.25.0", (api) => {
const autoCaptionPromptKey = "ai-auto-caption-seen"; const autoCaptionPromptKey = "ai-auto-caption-seen";
const seenAutoCaptionPrompt = keyValueStore.getItem(autoCaptionPromptKey); const seenAutoCaptionPrompt = keyValueStore.getItem(autoCaptionPromptKey);
if ( if (autoCaptionEnabled || !needsBetterCaptions || seenAutoCaptionPrompt) {
autoCaptionEnabled ||
!hasImageUploads ||
!needsBetterCaptions ||
seenAutoCaptionPrompt
) {
return resolve(); return resolve();
} }
-5
View File
@@ -119,11 +119,6 @@ en:
discourse_ai: discourse_ai:
title: "AI" title: "AI"
user_preferences:
empty_state:
title: "No AI specific user preferences available."
body: "There are currently no user preferences related to AI that are available for you to toggle."
modals: modals:
select_option: "Select an option..." select_option: "Select an option..."
@@ -4,6 +4,9 @@ RSpec.describe "AI image caption", type: :system, js: true do
fab!(:user) { Fabricate(:admin, refresh_auto_groups: true) } fab!(:user) { Fabricate(:admin, refresh_auto_groups: true) }
fab!(:non_member_group) { Fabricate(:group) } fab!(:non_member_group) { Fabricate(:group) }
let(:user_preferences_ai_page) { PageObjects::Pages::UserPreferencesAi.new } let(:user_preferences_ai_page) { PageObjects::Pages::UserPreferencesAi.new }
let(:topic_page) { PageObjects::Pages::Topic.new }
fab!(:topic)
fab!(:post) { Fabricate(:post, topic: topic) }
let(:composer) { PageObjects::Components::Composer.new } let(:composer) { PageObjects::Components::Composer.new }
let(:popup) { PageObjects::Components::AiCaptionPopup.new } let(:popup) { PageObjects::Components::AiCaptionPopup.new }
let(:dialog) { PageObjects::Components::Dialog.new } let(:dialog) { PageObjects::Components::Dialog.new }
@@ -150,5 +153,33 @@ RSpec.describe "AI image caption", type: :system, js: true do
end end
end end
end end
context "when a post has no uploads" do
before { user.user_option.update!(auto_image_caption: true) }
it "should create the topic without triggering auto caption" do
title = "I love using Discourse! It is my favorite forum software"
visit("/latest")
page.find("#create-topic").click
composer.fill_title(title)
composer.fill_content(
"Culpa labore velit cupidatat commodo magna esse et minim consequat veniam dolore eiusmod. Labore eu elit in nulla ipsum elit consectetur sunt consectetur enim. Cillum ex ex velit eiusmod labore ullamco ut ad. Dolore dolor commodo nisi fugiat esse quis anim officia quis. Pariatur cillum pariatur irure cupidatat nostrud ullamco labore id aliqua ut nostrud. Eu adipisicing ut laboris.",
)
composer.create
expect(dialog).to be_closed
expect(topic_page).to have_topic_title(title)
end
it "should create a reply to a post without triggering auto caption" do
visit("/t/-/#{topic.id}")
topic_page.click_footer_reply
composer.fill_content(
"Culpa labore velit cupidatat commodo magna esse et minim consequat veniam dolore eiusmod. Labore eu elit in nulla ipsum elit consectetur sunt consectetur enim. Cillum ex ex velit eiusmod labore ullamco ut ad. Dolore dolor commodo nisi fugiat esse quis anim officia quis. Pariatur cillum pariatur irure cupidatat nostrud ullamco labore id aliqua ut nostrud. Eu adipisicing ut laboris.",
)
composer.create
expect(dialog).to be_closed
expect(topic_page).to have_post_number(post.post_number)
end
end
end end
end end