Apply suggestions from code review
authorMarcel Werk <burntime@woltlab.com>
Tue, 9 Jan 2024 11:37:59 +0000 (12:37 +0100)
committerMarcel Werk <burntime@woltlab.com>
Tue, 9 Jan 2024 11:37:59 +0000 (12:37 +0100)
ts/WoltLabSuite/Core/BootstrapFrontend.ts
ts/WoltLabSuite/Core/Component/User/Follow.ts
wcfsetup/install/files/js/WoltLabSuite/Core/BootstrapFrontend.js
wcfsetup/install/files/js/WoltLabSuite/Core/Component/User/Follow.js
wcfsetup/install/files/lib/action/UserFollowAction.class.php
wcfsetup/install/files/lib/system/event/listener/PreloadPhrasesCollectingListener.class.php

index 2ed6d376dfda2f042e3d512a8a4880919e342dcc..8b8b5fac8ca72f18cba722dfef5e5a9d2f1d25ab 100644 (file)
@@ -117,4 +117,7 @@ export function setup(options: BootstrapOptions): void {
   whenFirstSeen("woltlab-core-comment-response", () => {
     void import("./Component/Comment/Response/woltlab-core-comment-response");
   });
+  whenFirstSeen("[data-follow-user]", () => {
+    void import("./Component/User/Follow").then(({ setup }) => setup());
+  });
 }
index 0bb7d09e82e7461f1548f29d56dfeb86488b229d..4d4d35a06a0dc14c8dd1b62aa66ca9e1708713bb 100644 (file)
@@ -8,34 +8,42 @@
  */
 
 import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend";
+import { promiseMutex } from "WoltLabSuite/Core/Helper/PromiseMutex";
+import { wheneverFirstSeen } from "WoltLabSuite/Core/Helper/Selector";
 import { getPhrase } from "WoltLabSuite/Core/Language";
+import * as UiNotification from "WoltLabSuite/Core/Ui/Notification";
 
-function toggleFollow(button: HTMLButtonElement): void {
-  if (button.dataset.following != "1") {
-    button.dataset.following = "1";
-    button.dataset.tooltip = getPhrase("wcf.user.button.unfollow");
-    button.querySelector("fa-icon")?.setIcon("circle-minus");
-    void prepareRequest(button.dataset.endpoint!)
+async function toggleFollow(button: HTMLElement): Promise<void> {
+  if (button.dataset.following !== "1") {
+    await prepareRequest(button.dataset.followUser!)
       .post({
         action: "follow",
       })
       .fetchAsResponse();
+
+    button.dataset.following = "1";
+    button.dataset.tooltip = getPhrase("wcf.user.button.unfollow");
+    button.querySelector("fa-icon")?.setIcon("circle-minus");
   } else {
-    button.dataset.following = "0";
-    button.dataset.tooltip = getPhrase("wcf.user.button.follow");
-    button.querySelector("fa-icon")?.setIcon("circle-plus");
-    void prepareRequest(button.dataset.endpoint!)
+    await prepareRequest(button.dataset.followUser!)
       .post({
         action: "unfollow",
       })
       .fetchAsResponse();
+
+    button.dataset.following = "0";
+    button.dataset.tooltip = getPhrase("wcf.user.button.follow");
+    button.querySelector("fa-icon")?.setIcon("circle-plus");
   }
+
+  UiNotification.show();
 }
 
 export function setup(): void {
-  document.querySelectorAll<HTMLButtonElement>(".jsFollowButton").forEach((button) => {
-    button.addEventListener("click", () => {
-      toggleFollow(button);
-    });
+  wheneverFirstSeen("[data-follow-user]", (button) => {
+    button.addEventListener(
+      "click",
+      promiseMutex(() => toggleFollow(button)),
+    );
   });
 }
index 8ae7bbcc04bc1b9e4903507b645baffcd31f129b..a24fdbdd4e2d41d24f5f428f0be809f9b28b86d2 100644 (file)
@@ -90,6 +90,9 @@ define(["require", "exports", "tslib", "./BackgroundQueue", "./Bootstrap", "./Co
         (0, LazyLoader_1.whenFirstSeen)("woltlab-core-comment-response", () => {
             void new Promise((resolve_4, reject_4) => { require(["./Component/Comment/Response/woltlab-core-comment-response"], resolve_4, reject_4); }).then(tslib_1.__importStar);
         });
+        (0, LazyLoader_1.whenFirstSeen)("[data-follow-user]", () => {
+            void new Promise((resolve_5, reject_5) => { require(["./Component/User/Follow"], resolve_5, reject_5); }).then(tslib_1.__importStar).then(({ setup }) => setup());
+        });
     }
     exports.setup = setup;
 });
index 7f354bbe771b959674ccf61e639be9f296d0fc90..2a7f7659f52cf6224eb5c39f1955f04749556e91 100644 (file)
@@ -6,37 +6,37 @@
  * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @since 6.1
  */
-define(["require", "exports", "WoltLabSuite/Core/Ajax/Backend", "WoltLabSuite/Core/Language"], function (require, exports, Backend_1, Language_1) {
+define(["require", "exports", "tslib", "WoltLabSuite/Core/Ajax/Backend", "WoltLabSuite/Core/Helper/PromiseMutex", "WoltLabSuite/Core/Helper/Selector", "WoltLabSuite/Core/Language", "WoltLabSuite/Core/Ui/Notification"], function (require, exports, tslib_1, Backend_1, PromiseMutex_1, Selector_1, Language_1, UiNotification) {
     "use strict";
     Object.defineProperty(exports, "__esModule", { value: true });
     exports.setup = void 0;
-    function toggleFollow(button) {
-        if (button.dataset.following != "1") {
-            button.dataset.following = "1";
-            button.dataset.tooltip = (0, Language_1.getPhrase)("wcf.user.button.unfollow");
-            button.querySelector("fa-icon")?.setIcon("circle-minus");
-            void (0, Backend_1.prepareRequest)(button.dataset.endpoint)
+    UiNotification = tslib_1.__importStar(UiNotification);
+    async function toggleFollow(button) {
+        if (button.dataset.following !== "1") {
+            await (0, Backend_1.prepareRequest)(button.dataset.followUser)
                 .post({
                 action: "follow",
             })
                 .fetchAsResponse();
+            button.dataset.following = "1";
+            button.dataset.tooltip = (0, Language_1.getPhrase)("wcf.user.button.unfollow");
+            button.querySelector("fa-icon")?.setIcon("circle-minus");
         }
         else {
-            button.dataset.following = "0";
-            button.dataset.tooltip = (0, Language_1.getPhrase)("wcf.user.button.follow");
-            button.querySelector("fa-icon")?.setIcon("circle-plus");
-            void (0, Backend_1.prepareRequest)(button.dataset.endpoint)
+            await (0, Backend_1.prepareRequest)(button.dataset.followUser)
                 .post({
                 action: "unfollow",
             })
                 .fetchAsResponse();
+            button.dataset.following = "0";
+            button.dataset.tooltip = (0, Language_1.getPhrase)("wcf.user.button.follow");
+            button.querySelector("fa-icon")?.setIcon("circle-plus");
         }
+        UiNotification.show();
     }
     function setup() {
-        document.querySelectorAll(".jsFollowButton").forEach((button) => {
-            button.addEventListener("click", () => {
-                toggleFollow(button);
-            });
+        (0, Selector_1.wheneverFirstSeen)("[data-follow-user]", (button) => {
+            button.addEventListener("click", (0, PromiseMutex_1.promiseMutex)(() => toggleFollow(button)));
         });
     }
     exports.setup = setup;
index 959fa93716e571081444a51a627ad4cc7b472dbf..7cf6fafa9654af77469230a8b6722ca1755def41 100644 (file)
@@ -56,7 +56,7 @@ final class UserFollowAction implements RequestHandlerInterface
                     EOT
             );
 
-            if ($bodyParameters['action'] == 'follow') {
+            if ($bodyParameters['action'] === 'follow') {
                 $this->assertUserIsNotIgnored($user);
 
                 $command = new Follow(WCF::getUser(), $user);
@@ -82,10 +82,10 @@ final class UserFollowAction implements RequestHandlerInterface
     private function assertUserIsNotIgnored(User $target): void
     {
         $sql = "SELECT  ignoreID
-                FROM    wcf" . WCF_N . "_user_ignore
+                FROM    wcf1_user_ignore
                 WHERE   userID = ?
                     AND ignoreUserID = ?";
-        $statement = WCF::getDB()->prepareStatement($sql);
+        $statement = WCF::getDB()->prepare($sql);
         $statement->execute([
             $target->userID,
             WCF::getUser()->userID,
index d32a33fd4ad9f065682b79e6ed087b6c413e017e..9691c1fc48a65738af3687e6c46ae394e050920d 100644 (file)
@@ -151,5 +151,7 @@ final class PreloadPhrasesCollectingListener
         $event->preload('wcf.user.language');
         $event->preload('wcf.user.panel.settings');
         $event->preload('wcf.user.panel.showAll');
+        $event->preload('wcf.user.button.follow');
+        $event->preload('wcf.user.button.unfollow');
     }
 }