From c96dce29348f3bffbfd82cb573bb1c9afe8bbc50 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Tue, 13 Aug 2024 18:57:57 +0200 Subject: [PATCH] DEV: Convert user-status-picker to glimmer/gjs/dbutton/input (#28344) --- .../app/components/user-status-picker.gjs | 99 +++++++++++++++++++ .../app/components/user-status-picker.hbs | 35 ------- .../app/components/user-status-picker.js | 67 ------------- .../components/user-status-picker-test.gjs | 58 +++++++++++ .../components/user-status-picker-test.js | 60 ----------- 5 files changed, 157 insertions(+), 162 deletions(-) create mode 100644 app/assets/javascripts/discourse/app/components/user-status-picker.gjs delete mode 100644 app/assets/javascripts/discourse/app/components/user-status-picker.hbs delete mode 100644 app/assets/javascripts/discourse/app/components/user-status-picker.js create mode 100644 app/assets/javascripts/discourse/tests/integration/components/user-status-picker-test.gjs delete mode 100644 app/assets/javascripts/discourse/tests/integration/components/user-status-picker-test.js diff --git a/app/assets/javascripts/discourse/app/components/user-status-picker.gjs b/app/assets/javascripts/discourse/app/components/user-status-picker.gjs new file mode 100644 index 00000000000..589d2cfd2b0 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/user-status-picker.gjs @@ -0,0 +1,99 @@ +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import { on } from "@ember/modifier"; +import { action } from "@ember/object"; +import { scheduleOnce } from "@ember/runloop"; +import { htmlSafe } from "@ember/template"; +import DButton from "discourse/components/d-button"; +import EmojiPicker from "discourse/components/emoji-picker"; +import concatClass from "discourse/helpers/concat-class"; +import { emojiUnescape } from "discourse/lib/text"; +import { escapeExpression } from "discourse/lib/utilities"; +import autoFocus from "discourse/modifiers/auto-focus"; +import i18n from "discourse-common/helpers/i18n"; + +export default class UserStatusPicker extends Component { + @tracked isFocused = false; + @tracked emojiPickerIsActive = false; + + get emojiHtml() { + return emojiUnescape(escapeExpression(`:${this.args.status.emoji}:`)); + } + + focusEmojiButton() { + document.querySelector(".user-status-picker .btn-emoji")?.focus(); + } + + @action + blur() { + this.isFocused = false; + } + + @action + emojiSelected(emoji) { + this.args.status.emoji = emoji; + this.emojiPickerIsActive = false; + + scheduleOnce("afterRender", this, this.focusEmojiButton); + } + + @action + focus() { + this.isFocused = true; + } + + @action + onEmojiPickerOutsideClick() { + this.emojiPickerIsActive = false; + } + + @action + updateDescription(event) { + this.args.status.description = event.target.value; + this.args.status.emoji ||= "speech_balloon"; + } + + @action + toggleEmojiPicker() { + this.emojiPickerIsActive = !this.emojiPickerIsActive; + } + + +} diff --git a/app/assets/javascripts/discourse/app/components/user-status-picker.hbs b/app/assets/javascripts/discourse/app/components/user-status-picker.hbs deleted file mode 100644 index 0a526547e08..00000000000 --- a/app/assets/javascripts/discourse/app/components/user-status-picker.hbs +++ /dev/null @@ -1,35 +0,0 @@ -
-
- - -
-
- \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/user-status-picker.js b/app/assets/javascripts/discourse/app/components/user-status-picker.js deleted file mode 100644 index d51411a62ac..00000000000 --- a/app/assets/javascripts/discourse/app/components/user-status-picker.js +++ /dev/null @@ -1,67 +0,0 @@ -import Component from "@ember/component"; -import { action, computed } from "@ember/object"; -import { scheduleOnce } from "@ember/runloop"; -import { emojiUnescape } from "discourse/lib/text"; -import { escapeExpression } from "discourse/lib/utilities"; - -export default class UserStatusPicker extends Component { - tagName = ""; - isFocused = false; - emojiPickerIsActive = false; - - didInsertElement() { - super.didInsertElement(...arguments); - - if (!this.status) { - this.set("status", {}); - } - - document.querySelector(".user-status-description")?.focus(); - } - - @computed("status.emoji") - get emojiHtml() { - const emoji = escapeExpression(`:${this.status.emoji}:`); - return emojiUnescape(emoji); - } - - focusEmojiButton() { - document.querySelector(".btn-emoji")?.focus(); - } - - @action - blur() { - this.set("isFocused", false); - } - - @action - emojiSelected(emoji) { - this.set("status.emoji", emoji); - this.set("emojiPickerIsActive", false); - - scheduleOnce("afterRender", this, this.focusEmojiButton); - } - - @action - focus() { - this.set("isFocused", true); - } - - @action - onEmojiPickerOutsideClick() { - this.set("emojiPickerIsActive", false); - } - - @action - setDefaultEmoji() { - if (!this.status.emoji) { - this.set("status.emoji", "speech_balloon"); - } - } - - @action - toggleEmojiPicker(event) { - event.stopPropagation(); - this.set("emojiPickerIsActive", !this.emojiPickerIsActive); - } -} diff --git a/app/assets/javascripts/discourse/tests/integration/components/user-status-picker-test.gjs b/app/assets/javascripts/discourse/tests/integration/components/user-status-picker-test.gjs new file mode 100644 index 00000000000..1f929617182 --- /dev/null +++ b/app/assets/javascripts/discourse/tests/integration/components/user-status-picker-test.gjs @@ -0,0 +1,58 @@ +import { click, fillIn, render } from "@ember/test-helpers"; +import { TrackedObject } from "@ember-compat/tracked-built-ins"; +import { module, test } from "qunit"; +import UserStatusPicker from "discourse/components/user-status-picker"; +import { setupRenderingTest } from "discourse/tests/helpers/component-test"; + +module("Integration | Component | user-status-picker", function (hooks) { + setupRenderingTest(hooks); + + test("it renders current status", async function (assert) { + const status = new TrackedObject({ + emoji: "tooth", + description: "off to dentist", + }); + + await render(); + + assert + .dom(".emoji") + .hasAttribute("alt", status.emoji, "the status emoji is shown"); + assert + .dom(".user-status-description") + .hasValue(status.description, "the status description is shown"); + }); + + test("it focuses the input on insert", async function (assert) { + const status = new TrackedObject({}); + await render(); + + assert.dom(".user-status-description").isFocused(); + }); + + test("it picks emoji", async function (assert) { + const status = new TrackedObject({ + emoji: "tooth", + description: "off to dentist", + }); + + await render(); + + await click(".btn-emoji"); + await fillIn(".emoji-picker-content .filter", "mega"); + await click(".results .emoji"); + + assert.dom(".emoji").hasAttribute("alt", "mega"); + assert.strictEqual(status.emoji, "mega"); + }); + + test("it sets default emoji when user starts typing a description", async function (assert) { + const status = new TrackedObject({}); + + await render(); + + await fillIn(".user-status-description", "s"); + assert.dom(".emoji").hasAttribute("alt", "speech_balloon"); + assert.strictEqual(status.emoji, "speech_balloon"); + }); +}); diff --git a/app/assets/javascripts/discourse/tests/integration/components/user-status-picker-test.js b/app/assets/javascripts/discourse/tests/integration/components/user-status-picker-test.js deleted file mode 100644 index 7d046d92497..00000000000 --- a/app/assets/javascripts/discourse/tests/integration/components/user-status-picker-test.js +++ /dev/null @@ -1,60 +0,0 @@ -import { click, fillIn, render } from "@ember/test-helpers"; -import { hbs } from "ember-cli-htmlbars"; -import { module, test } from "qunit"; -import { setupRenderingTest } from "discourse/tests/helpers/component-test"; -import { query } from "discourse/tests/helpers/qunit-helpers"; - -module("Integration | Component | user-status-picker", function (hooks) { - setupRenderingTest(hooks); - - test("it renders current status", async function (assert) { - const status = { - emoji: "tooth", - description: "off to dentist", - }; - this.set("status", status); - await render(hbs``); - assert.equal( - query(".emoji").alt, - status.emoji, - "the status emoji is shown" - ); - assert.equal( - query(".user-status-description").value, - status.description, - "the status description is shown" - ); - }); - - test("it focuses the input on insert", async function (assert) { - await render(hbs``); - - assert.dom(".user-status-description").isFocused(); - }); - - test("it picks emoji", async function (assert) { - const status = { - emoji: "tooth", - description: "off to dentist", - }; - this.set("status", status); - await render(hbs``); - - const newEmoji = "mega"; - await click(".btn-emoji"); - await fillIn(".emoji-picker-content .filter", newEmoji); - await click(".results .emoji"); - - assert.equal(query(".emoji").alt, newEmoji); - }); - - test("it sets default emoji when user starts typing a description", async function (assert) { - const defaultEmoji = "speech_balloon"; - - this.set("status", null); - await render(hbs``); - await fillIn(".user-status-description", "s"); - - assert.equal(query(".emoji").alt, defaultEmoji); - }); -});