aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/reviewDB
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/reviewDB')
-rw-r--r--src/plugins/reviewDB/components/ReviewBadge.tsx4
-rw-r--r--src/plugins/reviewDB/components/ReviewComponent.tsx16
-rw-r--r--src/plugins/reviewDB/components/ReviewsView.tsx119
-rw-r--r--src/plugins/reviewDB/entities.ts15
-rw-r--r--src/plugins/reviewDB/index.tsx65
-rw-r--r--src/plugins/reviewDB/reviewDbApi.ts9
-rw-r--r--src/plugins/reviewDB/style.css37
7 files changed, 171 insertions, 94 deletions
diff --git a/src/plugins/reviewDB/components/ReviewBadge.tsx b/src/plugins/reviewDB/components/ReviewBadge.tsx
index e65dff2..3c02c35 100644
--- a/src/plugins/reviewDB/components/ReviewBadge.tsx
+++ b/src/plugins/reviewDB/components/ReviewBadge.tsx
@@ -28,8 +28,8 @@ export default function ReviewBadge(badge: Badge) {
{({ onMouseEnter, onMouseLeave }) => (
<img
className={cl("badge")}
- width="24px"
- height="24px"
+ width="22px"
+ height="22px"
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
src={badge.icon}
diff --git a/src/plugins/reviewDB/components/ReviewComponent.tsx b/src/plugins/reviewDB/components/ReviewComponent.tsx
index fa4cad4..1278a50 100644
--- a/src/plugins/reviewDB/components/ReviewComponent.tsx
+++ b/src/plugins/reviewDB/components/ReviewComponent.tsx
@@ -20,7 +20,7 @@ import { openUserProfile } from "@utils/discord";
import { classes } from "@utils/misc";
import { LazyComponent } from "@utils/react";
import { filters, findBulk } from "@webpack";
-import { Alerts, moment, Timestamp, UserStore } from "@webpack/common";
+import { Alerts, moment, Parser, Timestamp, UserStore } from "@webpack/common";
import { Review, ReviewType } from "../entities";
import { deleteReview, reportReview } from "../reviewDbApi";
@@ -30,12 +30,12 @@ import { DeleteButton, ReportButton } from "./MessageButton";
import ReviewBadge from "./ReviewBadge";
export default LazyComponent(() => {
- // this is terrible, blame mantika
+ // this is terrible, blame ven
const p = filters.byProps;
const [
{ cozyMessage, buttons, message, buttonsInner, groupStart },
{ container, isHeader },
- { avatar, clickable, username, messageContent, wrapper, cozy },
+ { avatar, clickable, username, wrapper, cozy },
buttonClasses,
botTag
] = findBulk(
@@ -124,12 +124,10 @@ export default LazyComponent(() => {
</Timestamp>)
}
- <p
- className={classes(messageContent)}
- style={{ fontSize: 15, marginTop: 4, color: "var(--text-normal)" }}
- >
- {review.comment}
- </p>
+ <div className={cl("review-comment")}>
+ {Parser.parseGuildEventDescription(review.comment)}
+ </div>
+
{review.id !== 0 && (
<div className={classes(container, isHeader, buttons)} style={{
padding: "0px",
diff --git a/src/plugins/reviewDB/components/ReviewsView.tsx b/src/plugins/reviewDB/components/ReviewsView.tsx
index ada0fa0..e5bc426 100644
--- a/src/plugins/reviewDB/components/ReviewsView.tsx
+++ b/src/plugins/reviewDB/components/ReviewsView.tsx
@@ -16,11 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { classes } from "@utils/misc";
-import { useAwaiter, useForceUpdater } from "@utils/react";
-import { findByPropsLazy } from "@webpack";
-import { Forms, React, RelationshipStore, UserStore } from "@webpack/common";
-import type { KeyboardEvent } from "react";
+import { LazyComponent, useAwaiter, useForceUpdater } from "@utils/react";
+import { find, findByPropsLazy } from "@webpack";
+import { Forms, React, RelationshipStore, useRef, UserStore } from "@webpack/common";
import { Review } from "../entities";
import { addReview, getReviews, Response, REVIEWS_PER_PAGE } from "../reviewDbApi";
@@ -28,7 +26,12 @@ import { settings } from "../settings";
import { authorize, cl, showToast } from "../utils";
import ReviewComponent from "./ReviewComponent";
-const Classes = findByPropsLazy("inputDefault", "editable");
+
+const Editor = findByPropsLazy("start", "end", "addMark");
+const Transform = findByPropsLazy("unwrapNodes");
+const InputTypes = findByPropsLazy("VOICE_CHANNEL_STATUS", "SIDEBAR");
+
+const InputComponent = LazyComponent(() => find(m => m?.type?.render?.toString().includes("CHANNEL_TEXT_AREA).AnalyticsLocationProvider")));
interface UserProps {
discordId: string;
@@ -113,48 +116,82 @@ function ReviewList({ refetch, reviews, hideOwnReview }: { refetch(): void; revi
);
}
+
export function ReviewsInputComponent({ discordId, isAuthor, refetch, name }: { discordId: string, name: string; isAuthor: boolean; refetch(): void; }) {
const { token } = settings.store;
-
- function onKeyPress({ key, target }: KeyboardEvent<HTMLTextAreaElement>) {
- if (key === "Enter") {
- addReview({
- userid: discordId,
- comment: (target as HTMLInputElement).value,
- star: -1
- }).then(res => {
- if (res?.success) {
- (target as HTMLInputElement).value = ""; // clear the input
- refetch();
- } else if (res?.message) {
- showToast(res.message);
- }
- });
- }
- }
+ const editorRef = useRef<any>(null);
+ const inputType = InputTypes.FORM;
+ inputType.disableAutoFocus = true;
+
+ const channel = {
+ flags_: 256,
+ guild_id_: null,
+ id: "0",
+ getGuildId: () => null,
+ isPrivate: () => true,
+ isActiveThread: () => false,
+ isArchivedLockedThread: () => false,
+ isDM: () => true,
+ roles: { "0": { permissions: 0n } },
+ getRecipientId: () => "0",
+ hasFlag: () => false,
+ };
return (
- <textarea
- className={classes(Classes.inputDefault, "enter-comment", cl("input"))}
- onKeyDownCapture={e => {
- if (e.key === "Enter") {
- e.preventDefault(); // prevent newlines
- }
- }}
- placeholder={
- !token
- ? "You need to authorize to review users!"
- : isAuthor
- ? `Update review for @${name}`
- : `Review @${name}`
- }
- onKeyDown={onKeyPress}
- onClick={() => {
+ <>
+ <div onClick={() => {
if (!token) {
showToast("Opening authorization window...");
authorize();
}
- }}
- />
+ }}>
+ <InputComponent
+ className={cl("input")}
+ channel={channel}
+ placeholder={
+ !token
+ ? "You need to authorize to review users!"
+ : isAuthor
+ ? `Update review for @${name}`
+ : `Review @${name}`
+ }
+ type={inputType}
+ disableThemedBackground={true}
+ setEditorRef={ref => editorRef.current = ref}
+ textValue=""
+ onSubmit={
+ async res => {
+ const response = await addReview({
+ userid: discordId,
+ comment: res.value,
+ });
+
+ if (response?.success) {
+ refetch();
+
+ const slateEditor = editorRef.current.ref.current.getSlateEditor();
+
+ // clear editor
+ Transform.delete(slateEditor, {
+ at: {
+ anchor: Editor.start(slateEditor, []),
+ focus: Editor.end(slateEditor, []),
+ }
+ });
+ } else if (response?.message) {
+ showToast(response.message);
+ }
+
+ // even tho we need to return this, it doesnt do anything
+ return {
+ shouldClear: false,
+ shouldRefocus: true,
+ };
+ }
+ }
+ />
+ </div>
+
+ </>
);
}
diff --git a/src/plugins/reviewDB/entities.ts b/src/plugins/reviewDB/entities.ts
index 1415101..fefb1d3 100644
--- a/src/plugins/reviewDB/entities.ts
+++ b/src/plugins/reviewDB/entities.ts
@@ -29,6 +29,13 @@ export const enum ReviewType {
System = 3
}
+export const enum NotificationType {
+ Info = 0,
+ Ban = 1,
+ Unban = 2,
+ Warning = 3
+}
+
export interface Badge {
name: string;
description: string;
@@ -45,6 +52,13 @@ export interface BanInfo {
banEndDate: number;
}
+export interface Notification {
+ id: number;
+ title: string;
+ content: string;
+ type: NotificationType;
+}
+
export interface ReviewDBUser {
ID: number;
discordID: string;
@@ -54,6 +68,7 @@ export interface ReviewDBUser {
warningCount: number;
badges: any[];
banInfo: BanInfo | null;
+ notification: Notification | null;
lastReviewID: number;
type: UserType;
}
diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx
index de09ac7..a519713 100644
--- a/src/plugins/reviewDB/index.tsx
+++ b/src/plugins/reviewDB/index.tsx
@@ -24,13 +24,13 @@ import ExpandableHeader from "@components/ExpandableHeader";
import { OpenExternalIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
-import { Alerts, Menu, useState } from "@webpack/common";
+import { Alerts, Menu, Parser, 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";
-import { getCurrentUserInfo } from "./reviewDbApi";
+import { NotificationType } from "./entities";
+import { getCurrentUserInfo, readNotification } from "./reviewDbApi";
import { settings } from "./settings";
import { showToast } from "./utils";
@@ -78,40 +78,33 @@ export default definePlugin({
addContextMenuPatch("guild-header-popout", guildPopoutPatch);
- if (user.banInfo) {
- const endDate = new Date(user.banInfo.banEndDate);
- if (endDate.getTime() > Date.now() && (s.user?.banInfo?.banEndDate ?? 0) < endDate.getTime()) {
- 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>
- {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: () =>
- VencordNative.native.openExternal(
- "https://reviewdb.mantikafasi.dev/api/redirect?"
- + new URLSearchParams({
- token: settings.store.token!,
- page: "dashboard/appeal"
- })
- )
- });
- }
+ if (user.notification) {
+ const props = user.notification.type === NotificationType.Ban ? {
+ cancelText: "Appeal",
+ confirmText: "Ok",
+ onCancel: () =>
+ VencordNative.native.openExternal(
+ "https://reviewdb.mantikafasi.dev/api/redirect?"
+ + new URLSearchParams({
+ token: settings.store.token!,
+ page: "dashboard/appeal"
+ })
+ )
+ } : {};
+
+ Alerts.show({
+ title: user.notification.title,
+ body: (
+ Parser.parse(
+ user.notification.content,
+ false
+ )
+ ),
+ ...props
+ });
+
+ readNotification(user.notification.id);
}
-
s.user = user;
}, 4000);
},
diff --git a/src/plugins/reviewDB/reviewDbApi.ts b/src/plugins/reviewDB/reviewDbApi.ts
index e8008c8..5370a9b 100644
--- a/src/plugins/reviewDB/reviewDbApi.ts
+++ b/src/plugins/reviewDB/reviewDbApi.ts
@@ -140,3 +140,12 @@ export function getCurrentUserInfo(token: string): Promise<ReviewDBUser> {
method: "POST",
}).then(r => r.json());
}
+
+export function readNotification(id: number) {
+ return fetch(API_URL + `/api/reviewdb/notifications?id=${id}`, {
+ method: "PATCH",
+ headers: {
+ "Authorization": settings.store.token || "",
+ },
+ });
+}
diff --git a/src/plugins/reviewDB/style.css b/src/plugins/reviewDB/style.css
index 83cf087..f4d890f 100644
--- a/src/plugins/reviewDB/style.css
+++ b/src/plugins/reviewDB/style.css
@@ -14,7 +14,16 @@
overflow: hidden;
background: transparent;
border: 1px solid var(--profile-message-input-border-color);
- font-size: 14px;
+}
+
+.vc-rdb-modal-footer > div {
+ width: 100%;
+ margin: 6px 16px;
+}
+
+/* When input becomes disabled(while sending review), input adds unneccesary padding to left, this prevents it */
+.vc-rdb-input > div > div {
+ padding-left: 0 !important;
}
.vc-rdb-placeholder {
@@ -24,13 +33,12 @@
color: var(--text-muted);
}
-.vc-rdb-modal-footer {
- padding: 0;
+.vc-rdb-input * {
+ font-size: 14px;
}
-.vc-rdb-modal-footer > div {
- width: 100%;
- margin: 6px 16px;
+.vc-rdb-modal-footer {
+ padding: 0;
}
.vc-rdb-modal-footer .vc-rdb-input {
@@ -49,3 +57,20 @@
.vc-rdb-modal-reviews {
margin-top: 16px;
}
+
+.vc-rdb-review {
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+.vc-rdb-review-comment img {
+ vertical-align: text-top;
+}
+
+.vc-rdb-review-comment {
+ overflow-y: hidden;
+ margin-top: 1px;
+ margin-bottom: 8px;
+ color: var(--text-normal);
+ font-size: 15px;
+}