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 = ; + +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 + ); + } + + +} 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",