[ReviewDB] Improve UI & Use new RewviewDB api endpoints (#1104)
This commit is contained in:
parent
1bc0678422
commit
7a27de8927
5 changed files with 101 additions and 33 deletions
|
@ -44,20 +44,19 @@ export function authorize(callback?: any) {
|
||||||
{...props}
|
{...props}
|
||||||
scopes={["identify"]}
|
scopes={["identify"]}
|
||||||
responseType="code"
|
responseType="code"
|
||||||
redirectUri="https://manti.vendicated.dev/URauth"
|
redirectUri="https://manti.vendicated.dev/api/reviewdb/auth"
|
||||||
permissions={0n}
|
permissions={0n}
|
||||||
clientId="915703782174752809"
|
clientId="915703782174752809"
|
||||||
cancelCompletesFlow={false}
|
cancelCompletesFlow={false}
|
||||||
callback={async (u: string) => {
|
callback={async (u: string) => {
|
||||||
try {
|
try {
|
||||||
const url = new URL(u);
|
const url = new URL(u);
|
||||||
url.searchParams.append("returnType", "json");
|
|
||||||
url.searchParams.append("clientMod", "vencord");
|
url.searchParams.append("clientMod", "vencord");
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
headers: new Headers({ Accept: "application/json" })
|
headers: new Headers({ Accept: "application/json" })
|
||||||
});
|
});
|
||||||
const { token, status } = await res.json();
|
const { token, success } = await res.json();
|
||||||
if (status === 0) {
|
if (success) {
|
||||||
Settings.plugins.ReviewDB.token = token;
|
Settings.plugins.ReviewDB.token = token;
|
||||||
showToast("Successfully logged in!");
|
showToast("Successfully logged in!");
|
||||||
callback?.();
|
callback?.();
|
||||||
|
@ -65,7 +64,7 @@ export function authorize(callback?: any) {
|
||||||
showToast("An Error occurred while logging in.");
|
showToast("An Error occurred while logging in.");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} 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 const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));
|
||||||
|
|
||||||
export function canDeleteReview(review: Review, userId: string) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,19 +34,17 @@ export default LazyComponent(() => {
|
||||||
const [
|
const [
|
||||||
{ cozyMessage, buttons, message, groupStart },
|
{ cozyMessage, buttons, message, groupStart },
|
||||||
{ container, isHeader },
|
{ container, isHeader },
|
||||||
{ avatar, clickable, username, messageContent, wrapper, cozy, timestampInline, timestamp },
|
{ avatar, clickable, username, messageContent, wrapper, cozy },
|
||||||
{ contents },
|
|
||||||
buttonClasses,
|
buttonClasses,
|
||||||
{ defaultColor }
|
|
||||||
] = findBulk(
|
] = findBulk(
|
||||||
p("cozyMessage"),
|
p("cozyMessage"),
|
||||||
p("container", "isHeader"),
|
p("container", "isHeader"),
|
||||||
p("avatar", "zalgo"),
|
p("avatar", "zalgo"),
|
||||||
p("contents"),
|
|
||||||
p("button", "wrapper", "selected"),
|
p("button", "wrapper", "selected"),
|
||||||
p("defaultColor")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const dateFormat = new Intl.DateTimeFormat();
|
||||||
|
|
||||||
return function ReviewComponent({ review, refetch }: { review: Review; refetch(): void; }) {
|
return function ReviewComponent({ review, refetch }: { review: Review; refetch(): void; }) {
|
||||||
function openModal() {
|
function openModal() {
|
||||||
openUserProfileModal(review.sender.discordID);
|
openUserProfileModal(review.sender.discordID);
|
||||||
|
@ -89,7 +87,7 @@ export default LazyComponent(() => {
|
||||||
}
|
}
|
||||||
}>
|
}>
|
||||||
|
|
||||||
<div className={contents} style={{ paddingLeft: "0px" }}>
|
<div>
|
||||||
<img
|
<img
|
||||||
className={classes(avatar, clickable)}
|
className={classes(avatar, clickable)}
|
||||||
onClick={openModal}
|
onClick={openModal}
|
||||||
|
@ -107,16 +105,14 @@ export default LazyComponent(() => {
|
||||||
|
|
||||||
{
|
{
|
||||||
!Settings.plugins.ReviewDB.hideTimestamps && (
|
!Settings.plugins.ReviewDB.hideTimestamps && (
|
||||||
<Timestamp
|
<Timestamp timestamp={moment(review.timestamp * 1000)} >
|
||||||
timestamp={moment(review.timestamp * 1000)}
|
{dateFormat.format(review.timestamp * 1000)}
|
||||||
compact={true}
|
</Timestamp>)
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<p
|
<p
|
||||||
className={classes(messageContent, defaultColor)}
|
className={classes(messageContent)}
|
||||||
style={{ fontSize: 15, marginTop: 4 }}
|
style={{ fontSize: 15, marginTop: 4, color: "var(--text-normal)" }}
|
||||||
>
|
>
|
||||||
{review.comment}
|
{review.comment}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
import { Settings } from "@api/Settings";
|
import { Settings } from "@api/Settings";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
import { findLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { Forms, React, Text, UserStore } from "@webpack/common";
|
import { Forms, React, Text, UserStore } from "@webpack/common";
|
||||||
import type { KeyboardEvent } from "react";
|
import type { KeyboardEvent } from "react";
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import { addReview, getReviews } from "../Utils/ReviewDBAPI";
|
||||||
import { authorize, showToast } from "../Utils/Utils";
|
import { authorize, showToast } from "../Utils/Utils";
|
||||||
import ReviewComponent from "./ReviewComponent";
|
import ReviewComponent from "./ReviewComponent";
|
||||||
|
|
||||||
const Classes = findLazy(m => typeof m.textarea === "string");
|
const Classes = findByPropsLazy("inputDefault", "editable");
|
||||||
|
|
||||||
export default function ReviewsView({ userId }: { userId: string; }) {
|
export default function ReviewsView({ userId }: { userId: string; }) {
|
||||||
const { token } = Settings.plugins.ReviewDB;
|
const { token } = Settings.plugins.ReviewDB;
|
||||||
|
@ -65,7 +65,7 @@ export default function ReviewsView({ userId }: { userId: string; }) {
|
||||||
tag="h2"
|
tag="h2"
|
||||||
variant="eyebrow"
|
variant="eyebrow"
|
||||||
style={{
|
style={{
|
||||||
marginBottom: "12px",
|
marginBottom: "8px",
|
||||||
color: "var(--header-primary)"
|
color: "var(--header-primary)"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -79,13 +79,17 @@ export default function ReviewsView({ userId }: { userId: string; }) {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{reviews?.length === 0 && (
|
{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!
|
Looks like nobody reviewed this user yet. You could be the first!
|
||||||
</Forms.FormText>
|
</Forms.FormText>
|
||||||
)}
|
)}
|
||||||
<textarea
|
<textarea
|
||||||
className={classes(Classes.textarea.replace("textarea", ""), "enter-comment")}
|
className={classes(Classes.inputDefault, "enter-comment")}
|
||||||
// this produces something like '-_59yqs ...' but since no class exists with that name its fine
|
onKeyDownCapture={e => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault(); // prevent newlines
|
||||||
|
}
|
||||||
|
}}
|
||||||
placeholder={
|
placeholder={
|
||||||
token
|
token
|
||||||
? (reviews?.some(r => r.sender.discordID === UserStore.getCurrentUser().id)
|
? (reviews?.some(r => r.sender.discordID === UserStore.getCurrentUser().id)
|
||||||
|
@ -106,6 +110,9 @@ export default function ReviewsView({ userId }: { userId: string; }) {
|
||||||
resize: "none",
|
resize: "none",
|
||||||
marginBottom: "12px",
|
marginBottom: "12px",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
|
background: "transparent",
|
||||||
|
border: "1px solid var(--profile-message-input-border-color)",
|
||||||
|
fontSize: "14px",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,23 @@ export const enum UserType {
|
||||||
Admin = 1
|
Admin = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ReviewDBUser {
|
export interface BanInfo {
|
||||||
lastReviewID: number,
|
id: string;
|
||||||
type: UserType;
|
discordID: string;
|
||||||
|
reviewID: number;
|
||||||
|
reviewContent: string;
|
||||||
|
banEndDate: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReviewDBUser {
|
||||||
|
ID: number
|
||||||
|
discordID: string
|
||||||
|
username: string
|
||||||
|
profilePhoto: string
|
||||||
|
clientMod: string
|
||||||
|
warningCount: number
|
||||||
|
badges: any[]
|
||||||
|
banInfo: BanInfo | null
|
||||||
|
lastReviewID: number
|
||||||
|
type: UserType
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,11 @@ import { Settings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { Button } from "@webpack/common";
|
import { Alerts, Button } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
|
|
||||||
import ReviewsView from "./components/ReviewsView";
|
import ReviewsView from "./components/ReviewsView";
|
||||||
|
import { UserType } from "./entities/User";
|
||||||
import { getCurrentUserInfo } from "./Utils/ReviewDBAPI";
|
import { getCurrentUserInfo } from "./Utils/ReviewDBAPI";
|
||||||
import { authorize, showToast } from "./Utils/Utils";
|
import { authorize, showToast } from "./Utils/Utils";
|
||||||
|
|
||||||
|
@ -47,10 +48,10 @@ export default definePlugin({
|
||||||
options: {
|
options: {
|
||||||
authorize: {
|
authorize: {
|
||||||
type: OptionType.COMPONENT,
|
type: OptionType.COMPONENT,
|
||||||
description: "Authorise with ReviewDB",
|
description: "Authorize with ReviewDB",
|
||||||
component: () => (
|
component: () => (
|
||||||
<Button onClick={authorize}>
|
<Button onClick={authorize}>
|
||||||
Authorise with ReviewDB
|
Authorize with ReviewDB
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -68,7 +69,29 @@ export default definePlugin({
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
description: "Hide timestamps on reviews",
|
description: "Hide timestamps on reviews",
|
||||||
default: false,
|
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() {
|
async start() {
|
||||||
|
@ -82,7 +105,34 @@ export default definePlugin({
|
||||||
if (user.lastReviewID !== 0)
|
if (user.lastReviewID !== 0)
|
||||||
showToast("You have new reviews on your profile!");
|
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);
|
}, 4000);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue