ReviewDB: make warning review disableable; add timestamps (#948)

This commit is contained in:
Manti 2023-04-30 01:53:37 +03:00 committed by GitHub
parent 5b485806ea
commit 043381963b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 93 additions and 23 deletions

@ -19,6 +19,7 @@
import { Settings } from "@api/settings";
import { Review } from "../entities/Review";
import { ReviewDBUser } from "../entities/User";
import { authorize, showToast } from "./Utils";
const API_URL = "https://manti.vendicated.dev";
@ -32,8 +33,12 @@ interface Response {
updated: boolean;
}
const WarningFlag = 0b00000010;
export async function getReviews(id: string): Promise<Review[]> {
const req = await fetch(API_URL + `/api/reviewdb/users/${id}/reviews`);
var flags = 0;
if (!Settings.plugins.ReviewDB.showWarning) flags |= WarningFlag;
const req = await fetch(API_URL + `/api/reviewdb/users/${id}/reviews?flags=${flags}`);
const res = (req.status === 200) ? await req.json() as Response : { success: false, message: "An Error occured while fetching reviews. Please try again later.", reviews: [], updated: false };
if (!res.success) {
@ -43,6 +48,7 @@ export async function getReviews(id: string): Promise<Review[]> {
id: 0,
comment: "An Error occured while fetching reviews. Please try again later.",
star: 0,
timestamp: 0,
sender: {
id: 0,
username: "Error",
@ -108,8 +114,10 @@ export async function reportReview(id: number) {
showToast(await res.message);
}
export function getLastReviewID(id: string): Promise<number> {
return fetch(API_URL + "/getLastReviewID?discordid=" + id)
.then(r => r.text())
.then(Number);
export function getCurrentUserInfo(token: string): Promise<ReviewDBUser> {
return fetch(API_URL + "/api/reviewdb/users", {
body: JSON.stringify({ token }),
method: "POST",
})
.then(r => r.json());
}

@ -17,13 +17,13 @@
*/
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";
import { UserType } from "../entities/User";
export async function openUserProfileModal(userId: string) {
await UserUtils.fetchUser(userId);
@ -86,10 +86,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) return true;
const myId = BigInt(userId);
return myId === Devs.mantikafasi.id ||
myId === Devs.Ven.id ||
myId === Devs.rushii.id;
if (review.sender.discordID === userId || Settings.plugins.ReviewDB.userType === UserType.Admin) return true;
}

@ -16,9 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Settings } from "@api/settings";
import { classes, LazyComponent } from "@utils/misc";
import { filters, findBulk } from "@webpack";
import { Alerts, UserStore } from "@webpack/common";
import { Alerts, moment, Timestamp, UserStore } from "@webpack/common";
import { Review } from "../entities/Review";
import { deleteReview, reportReview } from "../Utils/ReviewDBAPI";
@ -32,7 +33,7 @@ export default LazyComponent(() => {
const [
{ cozyMessage, buttons, message, groupStart },
{ container, isHeader },
{ avatar, clickable, username, messageContent, wrapper, cozy },
{ avatar, clickable, username, messageContent, wrapper, cozy, timestampInline, timestamp },
{ contents },
buttonClasses,
{ defaultColor }
@ -102,6 +103,16 @@ export default LazyComponent(() => {
{review.sender.username}
</span>
{review.sender.badges.map(badge => <ReviewBadge {...badge} />)}
{
!Settings.plugins.ReviewDB.hideTimestamps && (
<Timestamp
timestamp={moment(review.timestamp * 1000)}
compact={true}
/>
)
}
<p
className={classes(messageContent, defaultColor)}
style={{ fontSize: 15, marginTop: 4 }}

@ -16,18 +16,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Settings } from "@api/settings";
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 { showToast } from "../Utils/Utils";
import { authorize, showToast } from "../Utils/Utils";
import ReviewComponent from "./ReviewComponent";
const Classes = findLazy(m => typeof m.textarea === "string");
export default function ReviewsView({ userId }: { userId: string; }) {
const { token } = Settings.plugins.ReviewDB;
const [refetchCount, setRefetchCount] = React.useState(0);
const [reviews, _, isLoading] = useAwaiter(() => getReviews(userId), {
fallbackValue: [],
@ -83,8 +85,21 @@ export default function ReviewsView({ userId }: { userId: string; }) {
<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.sender.discordID === UserStore.getCurrentUser().id) ? `Update review for @${username}` : `Review @${username}`}
placeholder={
token
? (reviews?.some(r => r.sender.discordID === UserStore.getCurrentUser().id)
? `Update review for @${username}`
: `Review @${username}`)
: "You need to authorize to review users!"
}
onKeyDown={onKeyPress}
onClick={() => {
if (!token) {
showToast("Opening authorization window...");
authorize();
}
}}
style={{
marginTop: "6px",
resize: "none",

@ -31,4 +31,5 @@ export interface Review {
id: number,
star: number,
sender: Sender,
timestamp: number
}

@ -0,0 +1,28 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 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 const enum UserType {
Banned = -1,
Normal = 0,
Admin = 1
}
export interface ReviewDBUser {
lastReviewID: number,
type: UserType;
}

@ -22,11 +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, UserStore } from "@webpack/common";
import { Button } from "@webpack/common";
import { User } from "discord-types/general";
import ReviewsView from "./components/ReviewsView";
import { getLastReviewID } from "./Utils/ReviewDBAPI";
import { getCurrentUserInfo } from "./Utils/ReviewDBAPI";
import { authorize, showToast } from "./Utils/Utils";
export default definePlugin({
@ -58,19 +58,31 @@ export default definePlugin({
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,
}
},
async start() {
const settings = Settings.plugins.ReviewDB;
if (!settings.lastReviewId || !settings.notifyReviews) return;
if (!settings.notifyReviews || !settings.token) return;
setTimeout(async () => {
const id = await getLastReviewID(UserStore.getCurrentUser().id);
if (settings.lastReviewId < id) {
const user = await getCurrentUserInfo(settings.token);
if (settings.lastReviewId < user.lastReviewID) {
settings.lastReviewId = user.lastReviewID;
if (user.lastReviewID !== 0)
showToast("You have new reviews on your profile!");
settings.lastReviewId = id;
}
settings.userType = user.type;
}, 4000);
},