Delete src/plugins/reviewDB directory
Api owner refusing to properly moderate hate speech and related illegal / ToS infringing content
This commit is contained in:
		
							parent
							
								
									19c762f9c1
								
							
						
					
					
						commit
						3b945b87b8
					
				
					 9 changed files with 0 additions and 633 deletions
				
			
		| 
						 | 
					@ -1,95 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Settings } from "@api/settings";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Review } from "../entities/Review";
 | 
					 | 
				
			||||||
import { authorize, showToast } from "./Utils";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const API_URL = "https://manti.vendicated.dev";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const getToken = () => Settings.plugins.ReviewDB.token;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum Response {
 | 
					 | 
				
			||||||
    "Added your review" = 0,
 | 
					 | 
				
			||||||
    "Updated your review" = 1,
 | 
					 | 
				
			||||||
    "Error" = 2,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function getReviews(id: string): Promise<Review[]> {
 | 
					 | 
				
			||||||
    const res = await fetch(API_URL + "/getUserReviews?snowflakeFormat=string&discordid=" + id);
 | 
					 | 
				
			||||||
    return await res.json() as Review[];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function addReview(review: any): Promise<Response> {
 | 
					 | 
				
			||||||
    review.token = getToken();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!review.token) {
 | 
					 | 
				
			||||||
        showToast("Please authorize to add a review.");
 | 
					 | 
				
			||||||
        authorize();
 | 
					 | 
				
			||||||
        return Response.Error;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return fetch(API_URL + "/addUserReview", {
 | 
					 | 
				
			||||||
        method: "POST",
 | 
					 | 
				
			||||||
        body: JSON.stringify(review),
 | 
					 | 
				
			||||||
        headers: {
 | 
					 | 
				
			||||||
            "Content-Type": "application/json",
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
        .then(r => r.text())
 | 
					 | 
				
			||||||
        .then(res => {
 | 
					 | 
				
			||||||
            showToast(res);
 | 
					 | 
				
			||||||
            return Response[res] ?? Response.Error;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function deleteReview(id: number): Promise<any> {
 | 
					 | 
				
			||||||
    return fetch(API_URL + "/deleteReview", {
 | 
					 | 
				
			||||||
        method: "POST",
 | 
					 | 
				
			||||||
        headers: new Headers({
 | 
					 | 
				
			||||||
            "Content-Type": "application/json",
 | 
					 | 
				
			||||||
            Accept: "application/json",
 | 
					 | 
				
			||||||
        }),
 | 
					 | 
				
			||||||
        body: JSON.stringify({
 | 
					 | 
				
			||||||
            token: getToken(),
 | 
					 | 
				
			||||||
            reviewid: id
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    }).then(r => r.json());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function reportReview(id: number) {
 | 
					 | 
				
			||||||
    const res = await fetch(API_URL + "/reportReview", {
 | 
					 | 
				
			||||||
        method: "POST",
 | 
					 | 
				
			||||||
        headers: new Headers({
 | 
					 | 
				
			||||||
            "Content-Type": "application/json",
 | 
					 | 
				
			||||||
            Accept: "application/json",
 | 
					 | 
				
			||||||
        }),
 | 
					 | 
				
			||||||
        body: JSON.stringify({
 | 
					 | 
				
			||||||
            reviewid: id,
 | 
					 | 
				
			||||||
            token: getToken()
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    showToast(await res.text());
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function getLastReviewID(id: string): Promise<number> {
 | 
					 | 
				
			||||||
    return fetch(API_URL + "/getLastReviewID?discordid=" + id)
 | 
					 | 
				
			||||||
        .then(r => r.text())
 | 
					 | 
				
			||||||
        .then(Number);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,95 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Settings } from "@api/settings";
 | 
					 | 
				
			||||||
import { Devs } from "@utils/constants";
 | 
					 | 
				
			||||||
import Logger from "@utils/Logger";
 | 
					 | 
				
			||||||
import { openModal } from "@utils/modal";
 | 
					 | 
				
			||||||
import { findByProps } from "@webpack";
 | 
					 | 
				
			||||||
import { FluxDispatcher, React, SelectedChannelStore, Toasts, UserUtils } from "@webpack/common";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Review } from "../entities/Review";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function openUserProfileModal(userId: string) {
 | 
					 | 
				
			||||||
    await UserUtils.fetchUser(userId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await FluxDispatcher.dispatch({
 | 
					 | 
				
			||||||
        type: "USER_PROFILE_MODAL_OPEN",
 | 
					 | 
				
			||||||
        userId,
 | 
					 | 
				
			||||||
        channelId: SelectedChannelStore.getChannelId(),
 | 
					 | 
				
			||||||
        analyticsLocation: "Explosive Hotel"
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function authorize(callback?: any) {
 | 
					 | 
				
			||||||
    const { OAuth2AuthorizeModal } = findByProps("OAuth2AuthorizeModal");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    openModal((props: any) =>
 | 
					 | 
				
			||||||
        <OAuth2AuthorizeModal
 | 
					 | 
				
			||||||
            {...props}
 | 
					 | 
				
			||||||
            scopes={["identify"]}
 | 
					 | 
				
			||||||
            responseType="code"
 | 
					 | 
				
			||||||
            redirectUri="https://manti.vendicated.dev/URauth"
 | 
					 | 
				
			||||||
            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) {
 | 
					 | 
				
			||||||
                        Settings.plugins.ReviewDB.token = token;
 | 
					 | 
				
			||||||
                        showToast("Successfully logged in!");
 | 
					 | 
				
			||||||
                        callback?.();
 | 
					 | 
				
			||||||
                    } else if (res.status === 1) {
 | 
					 | 
				
			||||||
                        showToast("An Error occurred while logging in.");
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } catch (e) {
 | 
					 | 
				
			||||||
                    new Logger("ReviewDB").error("Failed to authorise", e);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }}
 | 
					 | 
				
			||||||
        />
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function showToast(text: string) {
 | 
					 | 
				
			||||||
    Toasts.show({
 | 
					 | 
				
			||||||
        type: Toasts.Type.MESSAGE,
 | 
					 | 
				
			||||||
        message: text,
 | 
					 | 
				
			||||||
        id: Toasts.genId(),
 | 
					 | 
				
			||||||
        options: {
 | 
					 | 
				
			||||||
            position: Toasts.Position.BOTTOM
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function canDeleteReview(review: Review, userId: string) {
 | 
					 | 
				
			||||||
    if (review.senderdiscordid === userId) return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const myId = BigInt(userId);
 | 
					 | 
				
			||||||
    return myId === Devs.mantikafasi.id ||
 | 
					 | 
				
			||||||
        myId === Devs.Ven.id ||
 | 
					 | 
				
			||||||
        myId === Devs.rushii.id;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,43 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { classes, LazyComponent } from "@utils/misc";
 | 
					 | 
				
			||||||
import { findByProps } from "@webpack";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default LazyComponent(() => {
 | 
					 | 
				
			||||||
    const { button, dangerous } = findByProps("button", "wrapper", "disabled");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return function MessageButton(props) {
 | 
					 | 
				
			||||||
        return props.type === "delete"
 | 
					 | 
				
			||||||
            ? (
 | 
					 | 
				
			||||||
                <div className={classes(button, dangerous)} aria-label="Delete Review" onClick={props.callback}>
 | 
					 | 
				
			||||||
                    <svg aria-hidden="false" width="16" height="16" viewBox="0 0 20 20">
 | 
					 | 
				
			||||||
                        <path fill="currentColor" d="M15 3.999V2H9V3.999H3V5.999H21V3.999H15Z"></path>
 | 
					 | 
				
			||||||
                        <path fill="currentColor" d="M5 6.99902V18.999C5 20.101 5.897 20.999 7 20.999H17C18.103 20.999 19 20.101 19 18.999V6.99902H5ZM11 17H9V11H11V17ZM15 17H13V11H15V17Z"></path>
 | 
					 | 
				
			||||||
                    </svg>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
            : (
 | 
					 | 
				
			||||||
                <div className={button} aria-label="Report Review" onClick={() => props.callback()}>
 | 
					 | 
				
			||||||
                    <svg aria-hidden="false" width="16" height="16" viewBox="0 0 20 20">
 | 
					 | 
				
			||||||
                        <path fill="currentColor" d="M20,6.002H14V3.002C14,2.45 13.553,2.002 13,2.002H4C3.447,2.002 3,2.45 3,3.002V22.002H5V14.002H10.586L8.293,16.295C8.007,16.581 7.922,17.011 8.076,17.385C8.23,17.759 8.596,18.002 9,18.002H20C20.553,18.002 21,17.554 21,17.002V7.002C21,6.45 20.553,6.002 20,6.002Z"></path>
 | 
					 | 
				
			||||||
                    </svg>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,45 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { MaskedLinkStore, Tooltip } from "@webpack/common";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Badge } from "../entities/Badge";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function ReviewBadge(badge: Badge) {
 | 
					 | 
				
			||||||
    return (
 | 
					 | 
				
			||||||
        <Tooltip
 | 
					 | 
				
			||||||
            text={badge.badge_name}>
 | 
					 | 
				
			||||||
            {({ onMouseEnter, onMouseLeave }) => (
 | 
					 | 
				
			||||||
                <img
 | 
					 | 
				
			||||||
                    width="24px"
 | 
					 | 
				
			||||||
                    height="24px"
 | 
					 | 
				
			||||||
                    onMouseEnter={onMouseEnter}
 | 
					 | 
				
			||||||
                    onMouseLeave={onMouseLeave}
 | 
					 | 
				
			||||||
                    src={badge.badge_icon}
 | 
					 | 
				
			||||||
                    alt={badge.badge_description}
 | 
					 | 
				
			||||||
                    style={{ verticalAlign: "middle", marginLeft: "4px" }}
 | 
					 | 
				
			||||||
                    onClick={() =>
 | 
					 | 
				
			||||||
                        MaskedLinkStore.openUntrustedLink({
 | 
					 | 
				
			||||||
                            href: badge.redirect_url,
 | 
					 | 
				
			||||||
                        })
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
        </Tooltip>
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,125 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { classes, LazyComponent } from "@utils/misc";
 | 
					 | 
				
			||||||
import { filters, findBulk } from "@webpack";
 | 
					 | 
				
			||||||
import { Alerts, UserStore } from "@webpack/common";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Review } from "../entities/Review";
 | 
					 | 
				
			||||||
import { deleteReview, reportReview } from "../Utils/ReviewDBAPI";
 | 
					 | 
				
			||||||
import { canDeleteReview, openUserProfileModal, showToast } from "../Utils/Utils";
 | 
					 | 
				
			||||||
import MessageButton from "./MessageButton";
 | 
					 | 
				
			||||||
import ReviewBadge from "./ReviewBadge";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default LazyComponent(() => {
 | 
					 | 
				
			||||||
    // this is terrible, blame mantika
 | 
					 | 
				
			||||||
    const p = filters.byProps;
 | 
					 | 
				
			||||||
    const [
 | 
					 | 
				
			||||||
        { cozyMessage, buttons, message, groupStart },
 | 
					 | 
				
			||||||
        { container, isHeader },
 | 
					 | 
				
			||||||
        { avatar, clickable, username, messageContent, wrapper, cozy },
 | 
					 | 
				
			||||||
        { contents },
 | 
					 | 
				
			||||||
        buttonClasses,
 | 
					 | 
				
			||||||
        { defaultColor }
 | 
					 | 
				
			||||||
    ] = findBulk(
 | 
					 | 
				
			||||||
        p("cozyMessage"),
 | 
					 | 
				
			||||||
        p("container", "isHeader"),
 | 
					 | 
				
			||||||
        p("avatar", "zalgo"),
 | 
					 | 
				
			||||||
        p("contents"),
 | 
					 | 
				
			||||||
        p("button", "wrapper", "disabled"),
 | 
					 | 
				
			||||||
        p("defaultColor")
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return function ReviewComponent({ review, refetch }: { review: Review; refetch(): void; }) {
 | 
					 | 
				
			||||||
        function openModal() {
 | 
					 | 
				
			||||||
            openUserProfileModal(review.senderdiscordid);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        function delReview() {
 | 
					 | 
				
			||||||
            Alerts.show({
 | 
					 | 
				
			||||||
                title: "Are you sure?",
 | 
					 | 
				
			||||||
                body: "Do you really want to delete this review?",
 | 
					 | 
				
			||||||
                confirmText: "Delete",
 | 
					 | 
				
			||||||
                cancelText: "Nevermind",
 | 
					 | 
				
			||||||
                onConfirm: () => {
 | 
					 | 
				
			||||||
                    deleteReview(review.id).then(res => {
 | 
					 | 
				
			||||||
                        if (res.successful) {
 | 
					 | 
				
			||||||
                            refetch();
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        showToast(res.message);
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        function reportRev() {
 | 
					 | 
				
			||||||
            Alerts.show({
 | 
					 | 
				
			||||||
                title: "Are you sure?",
 | 
					 | 
				
			||||||
                body: "Do you really you want to report this review?",
 | 
					 | 
				
			||||||
                confirmText: "Report",
 | 
					 | 
				
			||||||
                cancelText: "Nevermind",
 | 
					 | 
				
			||||||
                // confirmColor: "red", this just adds a class name and breaks the submit button guh
 | 
					 | 
				
			||||||
                onConfirm: () => reportReview(review.id)
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return (
 | 
					 | 
				
			||||||
            <div className={classes(cozyMessage, wrapper, message, groupStart, cozy, "user-review")} style={
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    marginLeft: "0px",
 | 
					 | 
				
			||||||
                    paddingLeft: "52px",
 | 
					 | 
				
			||||||
                    paddingRight: "16px"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                <div className={contents} style={{ paddingLeft: "0px" }}>
 | 
					 | 
				
			||||||
                    <img
 | 
					 | 
				
			||||||
                        className={classes(avatar, clickable)}
 | 
					 | 
				
			||||||
                        onClick={openModal}
 | 
					 | 
				
			||||||
                        src={review.profile_photo || "/assets/1f0bfc0865d324c2587920a7d80c609b.png?size=128"}
 | 
					 | 
				
			||||||
                        style={{ left: "0px" }}
 | 
					 | 
				
			||||||
                    />
 | 
					 | 
				
			||||||
                    <span
 | 
					 | 
				
			||||||
                        className={classes(clickable, username)}
 | 
					 | 
				
			||||||
                        style={{ color: "var(--channels-default)", fontSize: "14px" }}
 | 
					 | 
				
			||||||
                        onClick={() => openModal()}
 | 
					 | 
				
			||||||
                    >
 | 
					 | 
				
			||||||
                        {review.username}
 | 
					 | 
				
			||||||
                    </span>
 | 
					 | 
				
			||||||
                    {review.badges.map(badge => <ReviewBadge {...badge} />)}
 | 
					 | 
				
			||||||
                    <p
 | 
					 | 
				
			||||||
                        className={classes(messageContent, defaultColor)}
 | 
					 | 
				
			||||||
                        style={{ fontSize: 15, marginTop: 4 }}
 | 
					 | 
				
			||||||
                    >
 | 
					 | 
				
			||||||
                        {review.comment}
 | 
					 | 
				
			||||||
                    </p>
 | 
					 | 
				
			||||||
                    <div className={classes(container, isHeader, buttons)} style={{
 | 
					 | 
				
			||||||
                        padding: "0px",
 | 
					 | 
				
			||||||
                    }}>
 | 
					 | 
				
			||||||
                        <div className={buttonClasses.wrapper} >
 | 
					 | 
				
			||||||
                            <MessageButton type="report" callback={reportRev} />
 | 
					 | 
				
			||||||
                            {canDeleteReview(review, UserStore.getCurrentUser().id) && (
 | 
					 | 
				
			||||||
                                <MessageButton type="delete" callback={delReview} />
 | 
					 | 
				
			||||||
                            )}
 | 
					 | 
				
			||||||
                        </div>
 | 
					 | 
				
			||||||
                    </div>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,94 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { classes, useAwaiter } from "@utils/misc";
 | 
					 | 
				
			||||||
import { findLazy } from "@webpack";
 | 
					 | 
				
			||||||
import { Forms, React, Text, UserStore } from "@webpack/common";
 | 
					 | 
				
			||||||
import type { KeyboardEvent } from "react";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { addReview, getReviews } from "../Utils/ReviewDBAPI";
 | 
					 | 
				
			||||||
import ReviewComponent from "./ReviewComponent";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const Classes = findLazy(m => typeof m.textarea === "string");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function ReviewsView({ userId }: { userId: string; }) {
 | 
					 | 
				
			||||||
    const [refetchCount, setRefetchCount] = React.useState(0);
 | 
					 | 
				
			||||||
    const [reviews, _, isLoading] = useAwaiter(() => getReviews(userId), {
 | 
					 | 
				
			||||||
        fallbackValue: [],
 | 
					 | 
				
			||||||
        deps: [refetchCount],
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    const username = UserStore.getUser(userId)?.username ?? "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dirtyRefetch = () => setRefetchCount(refetchCount + 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (isLoading) return null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function onKeyPress({ key, target }: KeyboardEvent<HTMLTextAreaElement>) {
 | 
					 | 
				
			||||||
        if (key === "Enter") {
 | 
					 | 
				
			||||||
            addReview({
 | 
					 | 
				
			||||||
                userid: userId,
 | 
					 | 
				
			||||||
                comment: (target as HTMLInputElement).value,
 | 
					 | 
				
			||||||
                star: -1
 | 
					 | 
				
			||||||
            }).then(res => {
 | 
					 | 
				
			||||||
                if (res === 0 || res === 1) {
 | 
					 | 
				
			||||||
                    (target as HTMLInputElement).value = ""; // clear the input
 | 
					 | 
				
			||||||
                    dirtyRefetch();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (
 | 
					 | 
				
			||||||
        <div className="ReviewDB">
 | 
					 | 
				
			||||||
            <Text
 | 
					 | 
				
			||||||
                tag="h2"
 | 
					 | 
				
			||||||
                variant="eyebrow"
 | 
					 | 
				
			||||||
                style={{
 | 
					 | 
				
			||||||
                    marginBottom: "12px",
 | 
					 | 
				
			||||||
                    color: "var(--header-primary)"
 | 
					 | 
				
			||||||
                }}
 | 
					 | 
				
			||||||
            >
 | 
					 | 
				
			||||||
                User Reviews
 | 
					 | 
				
			||||||
            </Text>
 | 
					 | 
				
			||||||
            {reviews?.map(review =>
 | 
					 | 
				
			||||||
                <ReviewComponent
 | 
					 | 
				
			||||||
                    key={review.id}
 | 
					 | 
				
			||||||
                    review={review}
 | 
					 | 
				
			||||||
                    refetch={dirtyRefetch}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
            )}
 | 
					 | 
				
			||||||
            {reviews?.length === 0 && (
 | 
					 | 
				
			||||||
                <Forms.FormText style={{ padding: "12px", paddingTop: "0px", paddingLeft: "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
 | 
					 | 
				
			||||||
                placeholder={reviews?.some(r => r.senderdiscordid === UserStore.getCurrentUser().id) ? `Update review for @${username}` : `Review @${username}`}
 | 
					 | 
				
			||||||
                onKeyDown={onKeyPress}
 | 
					 | 
				
			||||||
                style={{
 | 
					 | 
				
			||||||
                    marginTop: "6px",
 | 
					 | 
				
			||||||
                    resize: "none",
 | 
					 | 
				
			||||||
                    marginBottom: "12px",
 | 
					 | 
				
			||||||
                    overflow: "hidden",
 | 
					 | 
				
			||||||
                }}
 | 
					 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,26 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface Badge {
 | 
					 | 
				
			||||||
    badge_name: string;
 | 
					 | 
				
			||||||
    badge_description: string;
 | 
					 | 
				
			||||||
    badge_icon: string;
 | 
					 | 
				
			||||||
    redirect_url: string;
 | 
					 | 
				
			||||||
    badge_type: number;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,30 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Badge } from "./Badge";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface Review {
 | 
					 | 
				
			||||||
    comment: string,
 | 
					 | 
				
			||||||
    id: number,
 | 
					 | 
				
			||||||
    senderdiscordid: string,
 | 
					 | 
				
			||||||
    senderuserid: number,
 | 
					 | 
				
			||||||
    star: number,
 | 
					 | 
				
			||||||
    username: string,
 | 
					 | 
				
			||||||
    profile_photo: string;
 | 
					 | 
				
			||||||
    badges: Badge[];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,80 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Vencord, a modification for Discord's desktop app
 | 
					 | 
				
			||||||
 * Copyright (c) 2022 Vendicated and contributors
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
 * it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
 * (at your option) any later version.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					 | 
				
			||||||
 * GNU General Public License for more details.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * You should have received a copy of the GNU General Public License
 | 
					 | 
				
			||||||
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Settings } from "@api/settings";
 | 
					 | 
				
			||||||
import ErrorBoundary from "@components/ErrorBoundary";
 | 
					 | 
				
			||||||
import { Devs } from "@utils/constants";
 | 
					 | 
				
			||||||
import definePlugin, { OptionType } from "@utils/types";
 | 
					 | 
				
			||||||
import { Button, UserStore } from "@webpack/common";
 | 
					 | 
				
			||||||
import { User } from "discord-types/general";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import ReviewsView from "./components/ReviewsView";
 | 
					 | 
				
			||||||
import { getLastReviewID } from "./Utils/ReviewDBAPI";
 | 
					 | 
				
			||||||
import { authorize, showToast } from "./Utils/Utils";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default definePlugin({
 | 
					 | 
				
			||||||
    name: "ReviewDB",
 | 
					 | 
				
			||||||
    description: "Review other users (Adds a new settings to profiles)",
 | 
					 | 
				
			||||||
    authors: [Devs.mantikafasi, Devs.Ven],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    patches: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            find: "disableBorderColor:!0",
 | 
					 | 
				
			||||||
            replacement: {
 | 
					 | 
				
			||||||
                match: /\(.{0,10}\{user:(.),setNote:.,canDM:.,.+?\}\)/,
 | 
					 | 
				
			||||||
                replace: "$&,$self.getReviewsComponent($1)"
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    options: {
 | 
					 | 
				
			||||||
        authorize: {
 | 
					 | 
				
			||||||
            type: OptionType.COMPONENT,
 | 
					 | 
				
			||||||
            description: "Authorise with ReviewDB",
 | 
					 | 
				
			||||||
            component: () => (
 | 
					 | 
				
			||||||
                <Button onClick={authorize}>
 | 
					 | 
				
			||||||
                    Authorise with ReviewDB
 | 
					 | 
				
			||||||
                </Button>
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        notifyReviews: {
 | 
					 | 
				
			||||||
            type: OptionType.BOOLEAN,
 | 
					 | 
				
			||||||
            description: "Notify about new reviews on startup",
 | 
					 | 
				
			||||||
            default: true,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async start() {
 | 
					 | 
				
			||||||
        const settings = Settings.plugins.ReviewDB;
 | 
					 | 
				
			||||||
        if (!settings.lastReviewId || !settings.notifyReviews) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        setTimeout(async () => {
 | 
					 | 
				
			||||||
            const id = await getLastReviewID(UserStore.getCurrentUser().id);
 | 
					 | 
				
			||||||
            if (settings.lastReviewId < id) {
 | 
					 | 
				
			||||||
                showToast("You have new reviews on your profile!");
 | 
					 | 
				
			||||||
                settings.lastReviewId = id;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }, 4000);
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    getReviewsComponent: (user: User) => (
 | 
					 | 
				
			||||||
        <ErrorBoundary message="Failed to render Reviews">
 | 
					 | 
				
			||||||
            <ReviewsView userId={user.id} />
 | 
					 | 
				
			||||||
        </ErrorBoundary>
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in a new issue