diff --git a/src/plugins/reviewDB/auth.tsx b/src/plugins/reviewDB/auth.tsx index e7a369217..136001b2d 100644 --- a/src/plugins/reviewDB/auth.tsx +++ b/src/plugins/reviewDB/auth.tsx @@ -61,14 +61,17 @@ export function authorize(callback?: any) { const res = await fetch(url, { headers: new Headers({ Accept: "application/json" }) }); - const { token, success } = await res.json(); - if (success) { - updateAuth({ token }); - showToast("Successfully logged in!", Toasts.Type.SUCCESS); - callback?.(); - } else if (res.status === 1) { - showToast("An Error occurred while logging in.", Toasts.Type.FAILURE); + + if (!res.ok) { + const { message } = await res.json(); + showToast(message || "An error occured while authorizing", Toasts.Type.FAILURE); + return; } + + const { token } = await res.json(); + updateAuth({ token }); + showToast("Successfully logged in!", Toasts.Type.SUCCESS); + callback?.(); } catch (e) { new Logger("ReviewDB").error("Failed to authorize", e); } diff --git a/src/plugins/reviewDB/components/ReviewComponent.tsx b/src/plugins/reviewDB/components/ReviewComponent.tsx index 13b0f167f..977745a25 100644 --- a/src/plugins/reviewDB/components/ReviewComponent.tsx +++ b/src/plugins/reviewDB/components/ReviewComponent.tsx @@ -20,13 +20,13 @@ import { openUserProfile } from "@utils/discord"; import { classes } from "@utils/misc"; import { LazyComponent } from "@utils/react"; import { filters, findBulk } from "@webpack"; -import { Alerts, moment, Parser, showToast, Timestamp } from "@webpack/common"; +import { Alerts, moment, Parser, Timestamp, useState } from "@webpack/common"; import { Auth, getToken } from "../auth"; import { Review, ReviewType } from "../entities"; import { blockUser, deleteReview, reportReview, unblockUser } from "../reviewDbApi"; import { settings } from "../settings"; -import { canBlockReviewAuthor, canDeleteReview, canReportReview, cl } from "../utils"; +import { canBlockReviewAuthor, canDeleteReview, canReportReview, cl, showToast } from "../utils"; import { openBlockModal } from "./BlockedUserModal"; import { BlockButton, DeleteButton, ReportButton } from "./MessageButton"; import ReviewBadge from "./ReviewBadge"; @@ -51,6 +51,8 @@ export default LazyComponent(() => { const dateFormat = new Intl.DateTimeFormat(); return function ReviewComponent({ review, refetch, profileId }: { review: Review; refetch(): void; profileId: string; }) { + const [showAll, setShowAll] = useState(false); + function openModal() { openUserProfile(review.sender.discordID); } @@ -66,10 +68,9 @@ export default LazyComponent(() => { return showToast("You must be logged in to delete reviews."); } else { deleteReview(review.id).then(res => { - if (res.success) { + if (res) { refetch(); } - showToast(res.message); }); } } @@ -116,11 +117,11 @@ export default LazyComponent(() => { } return ( -
@@ -168,7 +169,9 @@ export default LazyComponent(() => { }
- {Parser.parseGuildEventDescription(review.comment)} + {(review.comment.length > 200 && !showAll) + ? [Parser.parseGuildEventDescription(review.comment.substring(0, 200)), "...",
, ( setShowAll(true)}>Read more)] + : Parser.parseGuildEventDescription(review.comment)}
{review.id !== 0 && ( diff --git a/src/plugins/reviewDB/components/ReviewsView.tsx b/src/plugins/reviewDB/components/ReviewsView.tsx index cfd5477db..64cea1815 100644 --- a/src/plugins/reviewDB/components/ReviewsView.tsx +++ b/src/plugins/reviewDB/components/ReviewsView.tsx @@ -18,13 +18,13 @@ import { LazyComponent, useAwaiter, useForceUpdater } from "@utils/react"; import { find, findByPropsLazy } from "@webpack"; -import { Forms, React, RelationshipStore, showToast, useRef, UserStore } from "@webpack/common"; +import { Forms, React, RelationshipStore, useRef, UserStore } from "@webpack/common"; import { Auth, authorize } from "../auth"; import { Review } from "../entities"; import { addReview, getReviews, Response, REVIEWS_PER_PAGE } from "../reviewDbApi"; import { settings } from "../settings"; -import { cl } from "../utils"; +import { cl, showToast } from "../utils"; import ReviewComponent from "./ReviewComponent"; @@ -168,7 +168,7 @@ export function ReviewsInputComponent({ discordId, isAuthor, refetch, name }: { comment: res.value, }); - if (response?.success) { + if (response) { refetch(); const slateEditor = editorRef.current.ref.current.getSlateEditor(); @@ -180,8 +180,6 @@ export function ReviewsInputComponent({ discordId, isAuthor, refetch, name }: { focus: Editor.end(slateEditor, []), } }); - } else if (response?.message) { - showToast(response.message); } // even tho we need to return this, it doesnt do anything diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx index d8357faf2..50bb62184 100644 --- a/src/plugins/reviewDB/index.tsx +++ b/src/plugins/reviewDB/index.tsx @@ -25,7 +25,7 @@ import { OpenExternalIcon } from "@components/Icons"; import { Devs } from "@utils/constants"; import { Logger } from "@utils/Logger"; import definePlugin from "@utils/types"; -import { Alerts, Menu, Parser, showToast, useState } from "@webpack/common"; +import { Alerts, Menu, Parser, useState } from "@webpack/common"; import { Guild, User } from "discord-types/general"; import { Auth, initAuth, updateAuth } from "./auth"; @@ -34,6 +34,7 @@ import ReviewsView from "./components/ReviewsView"; import { NotificationType } from "./entities"; import { getCurrentUserInfo, readNotification } from "./reviewDbApi"; import { settings } from "./settings"; +import { showToast } from "./utils"; const guildPopoutPatch: NavContextMenuPatchCallback = (children, props: { guild: Guild, onClose(): void; }) => () => { children.push( diff --git a/src/plugins/reviewDB/reviewDbApi.ts b/src/plugins/reviewDB/reviewDbApi.ts index 657e9c475..ec6d9ff3b 100644 --- a/src/plugins/reviewDB/reviewDbApi.ts +++ b/src/plugins/reviewDB/reviewDbApi.ts @@ -16,18 +16,18 @@ * along with this program. If not, see . */ -import { showToast, Toasts } from "@webpack/common"; +import { Toasts } from "@webpack/common"; import { Auth, authorize, getToken, updateAuth } from "./auth"; import { Review, ReviewDBCurrentUser, ReviewDBUser, ReviewType } from "./entities"; import { settings } from "./settings"; +import { showToast } from "./utils"; const API_URL = "https://manti.vendicated.dev/api/reviewdb"; export const REVIEWS_PER_PAGE = 50; export interface Response { - success: boolean, message: string; reviews: Review[]; updated: boolean; @@ -37,6 +37,16 @@ export interface Response { const WarningFlag = 0b00000010; +async function rdbRequest(path: string, options: RequestInit = {}) { + return fetch(API_URL + path, { + ...options, + headers: { + ...options.headers, + Authorization: await getToken() || "", + } + }); +} + export async function getReviews(id: string, offset = 0): Promise { let flags = 0; if (!settings.store.showWarning) flags |= WarningFlag; @@ -47,10 +57,9 @@ export async function getReviews(id: string, offset = 0): Promise { }); const req = await fetch(`${API_URL}/users/${id}/reviews?${params}`); - const res = (req.status === 200) + const res = (req.ok) ? await req.json() as Response : { - success: false, message: req.status === 429 ? "You are sending requests too fast. Wait a few seconds and try again." : "An Error occured while fetching reviews. Please try again later.", reviews: [], updated: false, @@ -58,7 +67,7 @@ export async function getReviews(id: string, offset = 0): Promise { reviewCount: 0 }; - if (!res.success) { + if (!req.ok) { showToast(res.message, Toasts.Type.FAILURE); return { ...res, @@ -85,44 +94,46 @@ export async function getReviews(id: string, offset = 0): Promise { } export async function addReview(review: any): Promise { - review.token = await getToken(); - if (!review.token) { + const token = await getToken(); + if (!token) { showToast("Please authorize to add a review."); authorize(); return null; } - return fetch(API_URL + `/users/${review.userid}/reviews`, { + return await rdbRequest(`/users/${review.userid}/reviews`, { method: "PUT", body: JSON.stringify(review), headers: { "Content-Type": "application/json", } - }) - .then(r => r.json()) - .then(res => { - showToast(res.message); - return res ?? null; - }); + }).then(async r => { + const data = await r.json() as Response; + showToast(data.message); + return r.ok ? data : null; + }); } -export async function deleteReview(id: number): Promise { - return fetch(API_URL + `/users/${id}/reviews`, { +export async function deleteReview(id: number): Promise { + return await rdbRequest(`/users/${id}/reviews`, { method: "DELETE", headers: new Headers({ "Content-Type": "application/json", Accept: "application/json", }), body: JSON.stringify({ - token: await getToken(), reviewid: id }) - }).then(r => r.json()); + }).then(async r => { + const data = await r.json() as Response; + showToast(data.message); + return r.ok ? data : null; + }); } export async function reportReview(id: number) { - const res = await fetch(API_URL + "/reports", { + const res = await rdbRequest("/reports", { method: "PUT", headers: new Headers({ "Content-Type": "application/json", @@ -130,7 +141,6 @@ export async function reportReview(id: number) { }), body: JSON.stringify({ reviewid: id, - token: await getToken() }) }).then(r => r.json()) as Response; @@ -138,12 +148,11 @@ export async function reportReview(id: number) { } async function patchBlock(action: "block" | "unblock", userId: string) { - const res = await fetch(API_URL + "/blocks", { + const res = await rdbRequest("/blocks", { method: "PATCH", headers: new Headers({ "Content-Type": "application/json", Accept: "application/json", - Authorization: await getToken() || "" }), body: JSON.stringify({ action: action, @@ -169,11 +178,10 @@ export const blockUser = (userId: string) => patchBlock("block", userId); export const unblockUser = (userId: string) => patchBlock("unblock", userId); export async function fetchBlocks(): Promise { - const res = await fetch(API_URL + "/blocks", { + const res = await rdbRequest("/blocks", { method: "GET", headers: new Headers({ Accept: "application/json", - Authorization: await getToken() || "" }) }); @@ -182,17 +190,13 @@ export async function fetchBlocks(): Promise { } export function getCurrentUserInfo(token: string): Promise { - return fetch(API_URL + "/users", { - body: JSON.stringify({ token }), + return rdbRequest("/users", { method: "POST", }).then(r => r.json()); } export async function readNotification(id: number) { - return fetch(API_URL + `/notifications?id=${id}`, { - method: "PATCH", - headers: { - "Authorization": await getToken() || "", - }, + return rdbRequest(`/notifications?id=${id}`, { + method: "PATCH" }); } diff --git a/src/plugins/reviewDB/settings.tsx b/src/plugins/reviewDB/settings.tsx index efcb80588..79cf4174e 100644 --- a/src/plugins/reviewDB/settings.tsx +++ b/src/plugins/reviewDB/settings.tsx @@ -22,13 +22,14 @@ import { Button } from "@webpack/common"; import { authorize, getToken } from "./auth"; import { openBlockModal } from "./components/BlockedUserModal"; +import { cl } from "./utils"; export const settings = definePluginSettings({ authorize: { type: OptionType.COMPONENT, description: "Authorize with ReviewDB", component: () => ( - ) @@ -53,38 +54,40 @@ export const settings = definePluginSettings({ description: "Hide reviews from blocked users", default: true, }, - manageBlocks: { + buttons: { type: OptionType.COMPONENT, - description: "Manage Blocked Users", + description: "ReviewDB buttons", component: () => ( - - ) - }, - website: { - type: OptionType.COMPONENT, - description: "ReviewDB website", - component: () => ( - - VencordNative.native.openExternal(url); - }}> - ReviewDB website - - ) - }, - supportServer: { - type: OptionType.COMPONENT, - description: "ReviewDB Support Server", - component: () => ( - + + + + + + +
) } }).withPrivateSettings<{ diff --git a/src/plugins/reviewDB/style.css b/src/plugins/reviewDB/style.css index a812ecaf2..190b8f620 100644 --- a/src/plugins/reviewDB/style.css +++ b/src/plugins/reviewDB/style.css @@ -59,8 +59,14 @@ } .vc-rdb-review { - margin-top: 8px; - margin-bottom: 8px; + padding-top: 8px !important; + padding-bottom: 8px !important; + padding-right: 32px !important; +} + +.vc-rdb-review:hover { + background: var(--background-message-hover) !important; + border-radius: 8px; } .vc-rdb-review-comment img { @@ -91,6 +97,19 @@ gap: 0.75em; } +.vc-rdb-button-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} + +/* stylelint-disable-next-line media-feature-range-notation */ +@media (max-width: 600px) { + .vc-rdb-button-grid { + grid-template-columns: 1fr; + } +} + .vc-rdb-block-modal-row { display: flex; height: 2em; diff --git a/src/plugins/reviewDB/utils.tsx b/src/plugins/reviewDB/utils.tsx index eeaca1204..916adc45e 100644 --- a/src/plugins/reviewDB/utils.tsx +++ b/src/plugins/reviewDB/utils.tsx @@ -17,7 +17,7 @@ */ import { classNameFactory } from "@api/Styles"; -import { UserStore } from "@webpack/common"; +import { Toasts, UserStore } from "@webpack/common"; import { Auth } from "./auth"; import { Review, UserType } from "./entities"; @@ -41,3 +41,14 @@ export function canBlockReviewAuthor(profileId: string, review: Review) { export function canReportReview(review: Review) { return review.sender.discordID !== UserStore.getCurrentUser().id; } + +export function showToast(message: string, type = Toasts.Type.MESSAGE) { + Toasts.show({ + id: Toasts.genId(), + message, + type, + options: { + position: Toasts.Position.BOTTOM, // NOBODY LIKES TOASTS AT THE TOP + }, + }); +}