From 25ddf1cd0783725c580e78ee3c37fa9e95363fd0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20Saquetim?=
<1108771+megothss@users.noreply.github.com>
Date: Mon, 11 Nov 2024 16:49:36 -0300
Subject: [PATCH] DEV: Add compatibility with the Glimmer post menu (#310)
This commit adds compatibility with the Glimmer post menu, updating the code to use the latest proposed API while maintaining compatibility with the legacy widget-based system.
---
.../discourse-reactions-actions-button.gjs | 12 ++
.../discourse-reactions-actions-summary.gjs | 34 +++++
...e-reactions.js => discourse-reactions.gjs} | 129 +++++++++++-------
.../discourse-reactions-enabled-test.js | 27 ++++
4 files changed, 150 insertions(+), 52 deletions(-)
create mode 100644 assets/javascripts/discourse/components/discourse-reactions-actions-button.gjs
create mode 100644 assets/javascripts/discourse/components/discourse-reactions-actions-summary.gjs
rename assets/javascripts/discourse/initializers/{discourse-reactions.js => discourse-reactions.gjs} (87%)
diff --git a/assets/javascripts/discourse/components/discourse-reactions-actions-button.gjs b/assets/javascripts/discourse/components/discourse-reactions-actions-button.gjs
new file mode 100644
index 00000000..080d4f65
--- /dev/null
+++ b/assets/javascripts/discourse/components/discourse-reactions-actions-button.gjs
@@ -0,0 +1,12 @@
+import { hash } from "@ember/helper";
+import MountWidget from "discourse/components/mount-widget";
+
+const ReactionsActionButton =
+ {{! template-lint-disable no-capital-arguments }}
+
+;
+
+export default ReactionsActionButton;
diff --git a/assets/javascripts/discourse/components/discourse-reactions-actions-summary.gjs b/assets/javascripts/discourse/components/discourse-reactions-actions-summary.gjs
new file mode 100644
index 00000000..ee975728
--- /dev/null
+++ b/assets/javascripts/discourse/components/discourse-reactions-actions-summary.gjs
@@ -0,0 +1,34 @@
+import Component from "@glimmer/component";
+import { hash } from "@ember/helper";
+import MountWidget from "discourse/components/mount-widget";
+
+export default class ReactionsActionSummary extends Component {
+ static extraControls = true;
+
+ static shouldRender(args, context, owner) {
+ const site = owner.lookup("service:site");
+
+ if (site.mobileView || args.post.deleted) {
+ return false;
+ }
+
+ const siteSettings = owner.lookup("service:site-settings");
+ const mainReaction = siteSettings.discourse_reactions_reaction_for_like;
+
+ return !(
+ args.post.reactions &&
+ args.post.reactions.length === 1 &&
+ args.post.reactions[0].id === mainReaction
+ );
+ }
+
+
+ {{#if @shouldRender}}
+ {{! template-lint-disable no-capital-arguments }}
+
+ {{/if}}
+
+}
diff --git a/assets/javascripts/discourse/initializers/discourse-reactions.js b/assets/javascripts/discourse/initializers/discourse-reactions.gjs
similarity index 87%
rename from assets/javascripts/discourse/initializers/discourse-reactions.js
rename to assets/javascripts/discourse/initializers/discourse-reactions.gjs
index 247ba44f..fab5d895 100644
--- a/assets/javascripts/discourse/initializers/discourse-reactions.js
+++ b/assets/javascripts/discourse/initializers/discourse-reactions.gjs
@@ -2,39 +2,19 @@ import { withPluginApi } from "discourse/lib/plugin-api";
import { emojiUrlFor } from "discourse/lib/text";
import { userPath } from "discourse/lib/url";
import { formatUsername } from "discourse/lib/utilities";
+import { withSilencedDeprecations } from "discourse-common/lib/deprecated";
import { replaceIcon } from "discourse-common/lib/icon-library";
import I18n from "I18n";
import { resetCurrentReaction } from "discourse/plugins/discourse-reactions/discourse/widgets/discourse-reactions-actions";
+import ReactionsActionButton from "../components/discourse-reactions-actions-button";
+import ReactionsActionSummary from "../components/discourse-reactions-actions-summary";
const PLUGIN_ID = "discourse-reactions";
replaceIcon("notification.reaction", "bell");
function initializeDiscourseReactions(api) {
- if (api.replacePostMenuButton) {
- api.replacePostMenuButton("like", {
- name: "discourse-reactions-actions",
- buildAttrs: (widget) => {
- return { post: widget.findAncestorModel() };
- },
- shouldRender: (widget) => {
- const post = widget.findAncestorModel();
- return post && !post.deleted_at;
- },
- });
- } else {
- api.removePostMenuButton("like");
- api.decorateWidget("post-menu:before-extra-controls", (dec) => {
- const post = dec.getModel();
- if (!post || post.deleted_at) {
- return;
- }
-
- return dec.attach("discourse-reactions-actions", {
- post,
- });
- });
- }
+ customizePostMenu(api);
api.addKeyboardShortcut("l", null, {
click: ".topic-post.selected .discourse-reactions-reaction-button",
@@ -73,33 +53,6 @@ function initializeDiscourseReactions(api) {
},
});
- api.decorateWidget("post-menu:extra-post-controls", (dec) => {
- if (dec.widget.site.mobileView) {
- return;
- }
-
- const mainReaction =
- dec.widget.siteSettings.discourse_reactions_reaction_for_like;
- const post = dec.getModel();
-
- if (!post || post.deleted_at) {
- return;
- }
-
- if (
- post.reactions &&
- post.reactions.length === 1 &&
- post.reactions[0].id === mainReaction
- ) {
- return;
- }
-
- return dec.attach("discourse-reactions-actions", {
- post,
- position: "left",
- });
- });
-
api.modifyClass(
"component:emoji-value-list",
{
@@ -220,13 +173,85 @@ function initializeDiscourseReactions(api) {
}
}
+function customizePostMenu(api) {
+ const transformerRegistered = api.registerValueTransformer(
+ "post-menu-buttons",
+ ({ value: dag, context: { buttonKeys } }) => {
+ dag.replace(buttonKeys.LIKE, ReactionsActionButton);
+ dag.add("discourse-reactions-actions", ReactionsActionSummary, {
+ after: buttonKeys.REPLIES,
+ });
+ }
+ );
+
+ const silencedKey =
+ transformerRegistered && "discourse.post-menu-widget-overrides";
+
+ withSilencedDeprecations(silencedKey, () => customizeWidgetPostMenu(api));
+}
+
+function customizeWidgetPostMenu(api) {
+ if (api.replacePostMenuButton) {
+ api.replacePostMenuButton("like", {
+ name: "discourse-reactions-actions",
+ buildAttrs: (widget) => {
+ return { post: widget.findAncestorModel() };
+ },
+ shouldRender: (widget) => {
+ const post = widget.findAncestorModel();
+ return post && !post.deleted_at;
+ },
+ });
+ } else {
+ api.removePostMenuButton("like");
+ api.decorateWidget("post-menu:before-extra-controls", (dec) => {
+ const post = dec.getModel();
+ if (!post || post.deleted_at) {
+ return;
+ }
+
+ return dec.attach("discourse-reactions-actions", {
+ post,
+ });
+ });
+ }
+
+ api.decorateWidget("post-menu:extra-post-controls", (dec) => {
+ if (dec.widget.site.mobileView) {
+ return;
+ }
+
+ const mainReaction =
+ dec.widget.siteSettings.discourse_reactions_reaction_for_like;
+ const post = dec.getModel();
+
+ if (!post || post.deleted_at) {
+ return;
+ }
+
+ if (
+ post.reactions &&
+ post.reactions.length === 1 &&
+ post.reactions[0].id === mainReaction
+ ) {
+ return;
+ }
+
+ return dec.attach("discourse-reactions-actions", {
+ post,
+ position: "left",
+ });
+ });
+}
+
export default {
name: "discourse-reactions",
initialize(container) {
const siteSettings = container.lookup("service:site-settings");
+
if (siteSettings.discourse_reactions_enabled) {
- withPluginApi("0.10.1", initializeDiscourseReactions);
+ withPluginApi("1.34.0", initializeDiscourseReactions);
}
},
diff --git a/test/javascripts/acceptance/discourse-reactions-enabled-test.js b/test/javascripts/acceptance/discourse-reactions-enabled-test.js
index aed5aaf5..7af8c085 100644
--- a/test/javascripts/acceptance/discourse-reactions-enabled-test.js
+++ b/test/javascripts/acceptance/discourse-reactions-enabled-test.js
@@ -6,6 +6,33 @@ import { default as ReactionsTopics } from "../fixtures/reactions-topic-fixtures
acceptance("Discourse Reactions - Enabled", function (needs) {
needs.user();
+ needs.settings({
+ glimmer_post_menu_mode: "enabled",
+ discourse_reactions_enabled: true,
+ discourse_reactions_enabled_reactions: "otter|open_mouth",
+ discourse_reactions_reaction_for_like: "heart",
+ discourse_reactions_like_icon: "heart",
+ });
+
+ needs.pretender((server, helper) => {
+ const topicPath = "/t/374.json";
+ server.get(topicPath, () => helper.response(ReactionsTopics[topicPath]));
+ });
+
+ test("It shows reactions controls", async (assert) => {
+ await visit("/t/topic_with_reactions_and_likes/374");
+
+ assert.ok(
+ exists(".discourse-reactions-actions"),
+ "reaction controls are available"
+ );
+ });
+});
+
+// TODO (glimmer-post-menu) remove this test when the post menu is removed from core
+acceptance("Discourse Reactions - Widgets", function (needs) {
+ needs.user();
+
needs.settings({
discourse_reactions_enabled: true,
discourse_reactions_enabled_reactions: "otter|open_mouth",