From 3e3d05fc26a634b17549c9473bd8aeebb7dec4ec Mon Sep 17 00:00:00 2001
From: Manti <67705577+mantikafasi@users.noreply.github.com>
Date: Sun, 28 May 2023 23:03:06 +0300
Subject: ReviewDB: Add Review Modal & Pagination (#1174)

Co-authored-by: V <vendicated@riseup.net>
---
 src/plugins/reviewDB/index.tsx | 171 +++++++++++++++++++++--------------------
 1 file changed, 87 insertions(+), 84 deletions(-)

(limited to 'src/plugins/reviewDB/index.tsx')

diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx
index 52ddb3b..0dcb7cd 100644
--- a/src/plugins/reviewDB/index.tsx
+++ b/src/plugins/reviewDB/index.tsx
@@ -18,23 +18,40 @@
 
 import "./style.css";
 
-import { Settings } from "@api/Settings";
+import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
 import ErrorBoundary from "@components/ErrorBoundary";
+import ExpandableHeader from "@components/ExpandableHeader";
+import { OpenExternalIcon } from "@components/Icons";
 import { Devs } from "@utils/constants";
-import definePlugin, { OptionType } from "@utils/types";
-import { Alerts, Button } from "@webpack/common";
-import { User } from "discord-types/general";
+import definePlugin from "@utils/types";
+import { Alerts, Menu, useState } from "@webpack/common";
+import { Guild, User } from "discord-types/general";
 
+import { openReviewsModal } from "./components/ReviewModal";
 import ReviewsView from "./components/ReviewsView";
-import { UserType } from "./entities/User";
-import { getCurrentUserInfo } from "./Utils/ReviewDBAPI";
-import { authorize, showToast } from "./Utils/Utils";
+import { UserType } from "./entities";
+import { getCurrentUserInfo } from "./reviewDbApi";
+import { settings } from "./settings";
+import { showToast } from "./utils";
+
+const guildPopoutPatch: NavContextMenuPatchCallback = (children, props: { guild: Guild, onClose(): void; }) => () => {
+    children.push(
+        <Menu.MenuItem
+            label="View Reviews"
+            id="vc-rdb-server-reviews"
+            icon={OpenExternalIcon}
+            action={() => openReviewsModal(props.guild.id, props.guild.name)}
+        />
+    );
+};
 
 export default definePlugin({
     name: "ReviewDB",
     description: "Review other users (Adds a new settings to profiles)",
     authors: [Devs.mantikafasi, Devs.Ven],
 
+    settings,
+
     patches: [
         {
             find: "disableBorderColor:!0",
@@ -45,100 +62,86 @@ export default definePlugin({
         }
     ],
 
-    options: {
-        authorize: {
-            type: OptionType.COMPONENT,
-            description: "Authorize with ReviewDB",
-            component: () => (
-                <Button onClick={authorize}>
-                    Authorize with ReviewDB
-                </Button>
-            )
-        },
-        notifyReviews: {
-            type: OptionType.BOOLEAN,
-            description: "Notify about new reviews on startup",
-            default: true,
-        },
-        showWarning: {
-            type: OptionType.BOOLEAN,
-            description: "Display warning to be respectful at the top of the reviews list",
-            default: true,
-        },
-        hideTimestamps: {
-            type: OptionType.BOOLEAN,
-            description: "Hide timestamps on reviews",
-            default: false,
-        },
-        website: {
-            type: OptionType.COMPONENT,
-            description: "ReviewDB website",
-            component: () => (
-                <Button onClick={() => {
-                    window.open("https://reviewdb.mantikafasi.dev");
-                }}>
-                    ReviewDB website
-                </Button>
-            )
-        },
-        supportServer: {
-            type: OptionType.COMPONENT,
-            description: "ReviewDB Support Server",
-            component: () => (
-                <Button onClick={() => {
-                    window.open("https://discord.gg/eWPBSbvznt");
-                }}>
-                    ReviewDB Support Server
-                </Button>
-            )
-        },
-    },
-
     async start() {
-        const settings = Settings.plugins.ReviewDB;
-        if (!settings.notifyReviews || !settings.token) return;
+        const s = settings.store;
+        const { token, lastReviewId, notifyReviews } = s;
+
+        if (!notifyReviews || !token) return;
 
         setTimeout(async () => {
-            const user = await getCurrentUserInfo(settings.token);
-            if (settings.lastReviewId < user.lastReviewID) {
-                settings.lastReviewId = user.lastReviewID;
+            const user = await getCurrentUserInfo(token);
+            if (lastReviewId && lastReviewId < user.lastReviewID) {
+                s.lastReviewId = user.lastReviewID;
                 if (user.lastReviewID !== 0)
                     showToast("You have new reviews on your profile!");
             }
 
-            if (user.banInfo) {
-                const endDate = new Date(user.banInfo.banEndDate);
-                if (endDate > new Date() && (settings.user?.banInfo?.banEndDate ?? 0) < endDate) {
+            addContextMenuPatch("guild-header-popout", guildPopoutPatch);
 
+            if (user.banInfo) {
+                const endDate = new Date(user.banInfo.banEndDate).getTime();
+                if (endDate > Date.now() && (s.user?.banInfo?.banEndDate ?? 0) < endDate) {
                     Alerts.show({
                         title: "You have been banned from ReviewDB",
-                        body: <>
-                            <p>
-                                You are banned from ReviewDB {(user.type === UserType.Banned) ? "permanently" : "until " + endDate.toLocaleString()}
-                            </p>
-                            <p>
-                                Offending Review: {user.banInfo.reviewContent}
-                            </p>
-                            <p>
-                                Continued offenses will result in a permanent ban.
-                            </p>
-                        </>,
+                        body: (
+                            <>
+                                <p>
+                                    You are banned from ReviewDB {
+                                        user.type === UserType.Banned
+                                            ? "permanently"
+                                            : "until " + endDate.toLocaleString()
+                                    }
+                                </p>
+                                {user.banInfo.reviewContent && (
+                                    <p>Offending Review: {user.banInfo.reviewContent}</p>
+                                )}
+                                <p>Continued offenses will result in a permanent ban.</p>
+                            </>
+                        ),
                         cancelText: "Appeal",
                         confirmText: "Ok",
-                        onCancel: () => {
-                            window.open("https://forms.gle/Thj3rDYaMdKoMMuq6");
-                        }
+                        onCancel: () =>
+                            VencordNative.native.openExternal(
+                                "https://reviewdb.mantikafasi.dev/api/redirect?"
+                                + new URLSearchParams({
+                                    token: settings.store.token!,
+                                    page: "dashboard/appeal"
+                                })
+                            )
                     });
                 }
             }
 
-            settings.user = user;
+            s.user = user;
         }, 4000);
     },
 
-    getReviewsComponent: (user: User) => (
-        <ErrorBoundary message="Failed to render Reviews">
-            <ReviewsView userId={user.id} />
-        </ErrorBoundary>
-    )
+    stop() {
+        removeContextMenuPatch("guild-header-popout", guildPopoutPatch);
+    },
+
+    getReviewsComponent: ErrorBoundary.wrap((user: User) => {
+        const [reviewCount, setReviewCount] = useState<number>();
+
+        return (
+            <ExpandableHeader
+                headerText="User Reviews"
+                onMoreClick={() => openReviewsModal(user.id, user.username)}
+                moreTooltipText={
+                    reviewCount && reviewCount > 50
+                        ? `View all ${reviewCount} reviews`
+                        : "Open Review Modal"
+                }
+                onDropDownClick={state => settings.store.reviewsDropdownState = !state}
+                defaultState={settings.store.reviewsDropdownState}
+            >
+                <ReviewsView
+                    discordId={user.id}
+                    name={user.username}
+                    onFetchReviews={r => setReviewCount(r.reviewCount)}
+                    showInput
+                />
+            </ExpandableHeader>
+        );
+    }, { message: "Failed to render Reviews" })
 });
-- 
cgit 

