From 5b16546358bbf3f849de8a6f20567df28172ea77 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Wed, 16 Nov 2022 10:33:47 +0100 Subject: [PATCH] DEV: Refactor `_warnCannotSeeMention()` (#19042) --- .../app/components/composer-editor.js | 49 +++++++++---------- .../components/composer-editor-test.js | 44 +++++++++++++++++ 2 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 app/assets/javascripts/discourse/tests/integration/components/composer-editor-test.js diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js index 545039b79d3..1d3ccc6452c 100644 --- a/app/assets/javascripts/discourse/app/components/composer-editor.js +++ b/app/assets/javascripts/discourse/app/components/composer-editor.js @@ -10,6 +10,7 @@ import { } from "discourse/lib/utilities"; import discourseComputed, { bind, + debounce, observes, on, } from "discourse-common/utils/decorators"; @@ -118,6 +119,11 @@ export default Component.extend(ComposerUploadUppy, { uploadPreProcessors, uploadHandlers, + init() { + this._super(...arguments); + this.warnedCannotSeeMentions = []; + }, + @discourseComputed("composer.requiredCategoryMissing") replyPlaceholder(requiredCategoryMissing) { if (requiredCategoryMissing) { @@ -504,41 +510,30 @@ export default Component.extend(ComposerUploadUppy, { }); }, + // add a delay to allow for typing, so you don't open the warning right away + // previously we would warn after @bob even if you were about to mention @bob2 + @debounce(2000) _warnCannotSeeMention(preview) { - const composerDraftKey = this.get("composer.draftKey"); - - if (composerDraftKey === Composer.NEW_PRIVATE_MESSAGE_KEY) { + if (this.composer.draftKey === Composer.NEW_PRIVATE_MESSAGE_KEY) { return; } - schedule("afterRender", () => { - let found = this.warnedCannotSeeMentions || []; + const warnings = []; - preview?.querySelectorAll(".mention.cannot-see")?.forEach((mention) => { - let name = mention.dataset.name; + preview.querySelectorAll(".mention.cannot-see").forEach((mention) => { + const { name } = mention.dataset; - if (!found.includes(name)) { - // add a delay to allow for typing, so you don't open the warning right away - // previously we would warn after @bob even if you were about to mention @bob2 - discourseLater( - this, - () => { - if ( - preview?.querySelectorAll( - `.mention.cannot-see[data-name="${name}"]` - )?.length > 0 - ) { - this.cannotSeeMention([{ name, reason: cannotSee[name] }]); - found.push(name); - } - }, - 2000 - ); - } - }); + if (this.warnedCannotSeeMentions.includes(name)) { + return; + } - this.set("warnedCannotSeeMentions", found); + this.warnedCannotSeeMentions.push(name); + warnings.push({ name, reason: cannotSee[name] }); }); + + if (warnings.length > 0) { + this.cannotSeeMention(warnings); + } }, _warnHereMention(hereCount) { diff --git a/app/assets/javascripts/discourse/tests/integration/components/composer-editor-test.js b/app/assets/javascripts/discourse/tests/integration/components/composer-editor-test.js new file mode 100644 index 00000000000..6bd6016b72a --- /dev/null +++ b/app/assets/javascripts/discourse/tests/integration/components/composer-editor-test.js @@ -0,0 +1,44 @@ +import { module, test } from "qunit"; +import { setupRenderingTest } from "discourse/tests/helpers/component-test"; +import { fillIn, render } from "@ember/test-helpers"; +import { hbs } from "ember-cli-htmlbars"; +import pretender, { response } from "discourse/tests/helpers/create-pretender"; + +module("Integration | Component | ComposerEditor", function (hooks) { + setupRenderingTest(hooks); + + test("warns about users that will not see a mention", async function (assert) { + assert.expect(1); + + this.set("model", {}); + this.set("noop", () => {}); + this.set("expectation", (warnings) => { + assert.deepEqual(warnings, [ + { name: "user-no", reason: "a reason" }, + { name: "user-nope", reason: "a reason" }, + ]); + }); + + pretender.get("/u/is_local_username", () => { + return response({ + cannot_see: { + "user-no": "a reason", + "user-nope": "a reason", + }, + mentionable_groups: [], + valid: ["user-ok", "user-no", "user-nope"], + valid_groups: [], + }); + }); + + await render(hbs` + + `); + + await fillIn("textarea", "@user-no @user-ok @user-nope"); + }); +});