From 7a27de892767aa8d9104ef16fe5ba2a2a75568cf Mon Sep 17 00:00:00 2001
From: Manti <67705577+mantikafasi@users.noreply.github.com>
Date: Sun, 14 May 2023 02:29:13 +0300
Subject: [ReviewDB] Improve UI & Use new RewviewDB api endpoints (#1104)

---
 src/plugins/reviewDB/Utils/Utils.tsx               | 11 ++--
 .../reviewDB/components/ReviewComponent.tsx        | 22 ++++----
 src/plugins/reviewDB/components/ReviewsView.tsx    | 19 ++++---
 src/plugins/reviewDB/entities/User.ts              | 20 +++++++-
 src/plugins/reviewDB/index.tsx                     | 60 ++++++++++++++++++++--
 5 files changed, 100 insertions(+), 32 deletions(-)

(limited to 'src')

diff --git a/src/plugins/reviewDB/Utils/Utils.tsx b/src/plugins/reviewDB/Utils/Utils.tsx
index d09c8d4..42426b2 100644
--- a/src/plugins/reviewDB/Utils/Utils.tsx
+++ b/src/plugins/reviewDB/Utils/Utils.tsx
@@ -44,20 +44,19 @@ export function authorize(callback?: any) {
             {...props}
             scopes={["identify"]}
             responseType="code"
-            redirectUri="https://manti.vendicated.dev/URauth"
+            redirectUri="https://manti.vendicated.dev/api/reviewdb/auth"
             permissions={0n}
             clientId="915703782174752809"
             cancelCompletesFlow={false}
             callback={async (u: string) => {
                 try {
                     const url = new URL(u);
-                    url.searchParams.append("returnType", "json");
                     url.searchParams.append("clientMod", "vencord");
                     const res = await fetch(url, {
                         headers: new Headers({ Accept: "application/json" })
                     });
-                    const { token, status } = await res.json();
-                    if (status === 0) {
+                    const { token, success } = await res.json();
+                    if (success) {
                         Settings.plugins.ReviewDB.token = token;
                         showToast("Successfully logged in!");
                         callback?.();
@@ -65,7 +64,7 @@ export function authorize(callback?: any) {
                         showToast("An Error occurred while logging in.");
                     }
                 } catch (e) {
-                    new Logger("ReviewDB").error("Failed to authorise", e);
+                    new Logger("ReviewDB").error("Failed to authorize", e);
                 }
             }}
         />
@@ -86,5 +85,5 @@ export function showToast(text: string) {
 export const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));
 
 export function canDeleteReview(review: Review, userId: string) {
-    if (review.sender.discordID === userId || Settings.plugins.ReviewDB.userType === UserType.Admin) return true;
+    if (review.sender.discordID === userId || Settings.plugins.ReviewDB.user?.type === UserType.Admin) return true;
 }
diff --git a/src/plugins/reviewDB/components/ReviewComponent.tsx b/src/plugins/reviewDB/components/ReviewComponent.tsx
index 04973d7..ac09b4c 100644
--- a/src/plugins/reviewDB/components/ReviewComponent.tsx
+++ b/src/plugins/reviewDB/components/ReviewComponent.tsx
@@ -34,19 +34,17 @@ export default LazyComponent(() => {
     const [
         { cozyMessage, buttons, message, groupStart },
         { container, isHeader },
-        { avatar, clickable, username, messageContent, wrapper, cozy, timestampInline, timestamp },
-        { contents },
+        { avatar, clickable, username, messageContent, wrapper, cozy },
         buttonClasses,
-        { defaultColor }
     ] = findBulk(
         p("cozyMessage"),
         p("container", "isHeader"),
         p("avatar", "zalgo"),
-        p("contents"),
         p("button", "wrapper", "selected"),
-        p("defaultColor")
     );
 
+    const dateFormat = new Intl.DateTimeFormat();
+
     return function ReviewComponent({ review, refetch }: { review: Review; refetch(): void; }) {
         function openModal() {
             openUserProfileModal(review.sender.discordID);
@@ -89,7 +87,7 @@ export default LazyComponent(() => {
                 }
             }>
 
-                <div className={contents} style={{ paddingLeft: "0px" }}>
+                <div>
                     <img
                         className={classes(avatar, clickable)}
                         onClick={openModal}
@@ -107,16 +105,14 @@ export default LazyComponent(() => {
 
                     {
                         !Settings.plugins.ReviewDB.hideTimestamps && (
-                            <Timestamp
-                                timestamp={moment(review.timestamp * 1000)}
-                                compact={true}
-                            />
-                        )
+                            <Timestamp timestamp={moment(review.timestamp * 1000)} >
+                                {dateFormat.format(review.timestamp * 1000)}
+                            </Timestamp>)
                     }
 
                     <p
-                        className={classes(messageContent, defaultColor)}
-                        style={{ fontSize: 15, marginTop: 4 }}
+                        className={classes(messageContent)}
+                        style={{ fontSize: 15, marginTop: 4, color: "var(--text-normal)" }}
                     >
                         {review.comment}
                     </p>
diff --git a/src/plugins/reviewDB/components/ReviewsView.tsx b/src/plugins/reviewDB/components/ReviewsView.tsx
index f4bd248..ff46cca 100644
--- a/src/plugins/reviewDB/components/ReviewsView.tsx
+++ b/src/plugins/reviewDB/components/ReviewsView.tsx
@@ -19,7 +19,7 @@
 import { Settings } from "@api/Settings";
 import { classes } from "@utils/misc";
 import { useAwaiter } from "@utils/react";
-import { findLazy } from "@webpack";
+import { findByPropsLazy } from "@webpack";
 import { Forms, React, Text, UserStore } from "@webpack/common";
 import type { KeyboardEvent } from "react";
 
@@ -27,7 +27,7 @@ import { addReview, getReviews } from "../Utils/ReviewDBAPI";
 import { authorize, showToast } from "../Utils/Utils";
 import ReviewComponent from "./ReviewComponent";
 
-const Classes = findLazy(m => typeof m.textarea === "string");
+const Classes = findByPropsLazy("inputDefault", "editable");
 
 export default function ReviewsView({ userId }: { userId: string; }) {
     const { token } = Settings.plugins.ReviewDB;
@@ -65,7 +65,7 @@ export default function ReviewsView({ userId }: { userId: string; }) {
                 tag="h2"
                 variant="eyebrow"
                 style={{
-                    marginBottom: "12px",
+                    marginBottom: "8px",
                     color: "var(--header-primary)"
                 }}
             >
@@ -79,13 +79,17 @@ export default function ReviewsView({ userId }: { userId: string; }) {
                 />
             )}
             {reviews?.length === 0 && (
-                <Forms.FormText style={{ padding: "12px", paddingTop: "0px", paddingLeft: "4px", fontWeight: "bold", fontStyle: "italic" }}>
+                <Forms.FormText style={{ paddingRight: "12px", paddingTop: "0px", paddingLeft: "0px", paddingBottom: "4px", fontWeight: "bold", fontStyle: "italic" }}>
                     Looks like nobody reviewed this user yet. You could be the first!
                 </Forms.FormText>
             )}
             <textarea
-                className={classes(Classes.textarea.replace("textarea", ""), "enter-comment")}
-                // this produces something like '-_59yqs ...' but since no class exists with that name its fine
+                className={classes(Classes.inputDefault, "enter-comment")}
+                onKeyDownCapture={e => {
+                    if (e.key === "Enter") {
+                        e.preventDefault(); // prevent newlines
+                    }
+                }}
                 placeholder={
                     token
                         ? (reviews?.some(r => r.sender.discordID === UserStore.getCurrentUser().id)
@@ -106,6 +110,9 @@ export default function ReviewsView({ userId }: { userId: string; }) {
                     resize: "none",
                     marginBottom: "12px",
                     overflow: "hidden",
+                    background: "transparent",
+                    border: "1px solid var(--profile-message-input-border-color)",
+                    fontSize: "14px",
                 }}
             />
         </div>
diff --git a/src/plugins/reviewDB/entities/User.ts b/src/plugins/reviewDB/entities/User.ts
index 4a3be0e..2c59992 100644
--- a/src/plugins/reviewDB/entities/User.ts
+++ b/src/plugins/reviewDB/entities/User.ts
@@ -22,7 +22,23 @@ export const enum UserType {
     Admin = 1
 }
 
+export interface BanInfo {
+    id: string;
+    discordID: string;
+    reviewID: number;
+    reviewContent: string;
+    banEndDate: string;
+}
+
 export interface ReviewDBUser {
-    lastReviewID: number,
-    type: UserType;
+    ID: number
+    discordID: string
+    username: string
+    profilePhoto: string
+    clientMod: string
+    warningCount: number
+    badges: any[]
+    banInfo: BanInfo | null
+    lastReviewID: number
+    type: UserType
 }
diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx
index 0495c77..52ddb3b 100644
--- a/src/plugins/reviewDB/index.tsx
+++ b/src/plugins/reviewDB/index.tsx
@@ -22,10 +22,11 @@ import { Settings } from "@api/Settings";
 import ErrorBoundary from "@components/ErrorBoundary";
 import { Devs } from "@utils/constants";
 import definePlugin, { OptionType } from "@utils/types";
-import { Button } from "@webpack/common";
+import { Alerts, Button } from "@webpack/common";
 import { User } from "discord-types/general";
 
 import ReviewsView from "./components/ReviewsView";
+import { UserType } from "./entities/User";
 import { getCurrentUserInfo } from "./Utils/ReviewDBAPI";
 import { authorize, showToast } from "./Utils/Utils";
 
@@ -47,10 +48,10 @@ export default definePlugin({
     options: {
         authorize: {
             type: OptionType.COMPONENT,
-            description: "Authorise with ReviewDB",
+            description: "Authorize with ReviewDB",
             component: () => (
                 <Button onClick={authorize}>
-                    Authorise with ReviewDB
+                    Authorize with ReviewDB
                 </Button>
             )
         },
@@ -68,7 +69,29 @@ export default definePlugin({
             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() {
@@ -82,7 +105,34 @@ export default definePlugin({
                 if (user.lastReviewID !== 0)
                     showToast("You have new reviews on your profile!");
             }
-            settings.userType = user.type;
+
+            if (user.banInfo) {
+                const endDate = new Date(user.banInfo.banEndDate);
+                if (endDate > new Date() && (settings.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>
+                        </>,
+                        cancelText: "Appeal",
+                        confirmText: "Ok",
+                        onCancel: () => {
+                            window.open("https://forms.gle/Thj3rDYaMdKoMMuq6");
+                        }
+                    });
+                }
+            }
+
+            settings.user = user;
         }, 4000);
     },
 
-- 
cgit