aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/reviewDB/components/ReviewsView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/reviewDB/components/ReviewsView.tsx')
-rw-r--r--src/plugins/reviewDB/components/ReviewsView.tsx179
1 files changed, 108 insertions, 71 deletions
diff --git a/src/plugins/reviewDB/components/ReviewsView.tsx b/src/plugins/reviewDB/components/ReviewsView.tsx
index ff46cca..bd264fa 100644
--- a/src/plugins/reviewDB/components/ReviewsView.tsx
+++ b/src/plugins/reviewDB/components/ReviewsView.tsx
@@ -16,42 +16,113 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-import { Settings } from "@api/Settings";
import { classes } from "@utils/misc";
-import { useAwaiter } from "@utils/react";
+import { useAwaiter, useForceUpdater } from "@utils/react";
import { findByPropsLazy } from "@webpack";
-import { Forms, React, Text, UserStore } from "@webpack/common";
+import { Forms, React, UserStore } from "@webpack/common";
import type { KeyboardEvent } from "react";
-import { addReview, getReviews } from "../Utils/ReviewDBAPI";
-import { authorize, showToast } from "../Utils/Utils";
+import { Review } from "../entities";
+import { addReview, getReviews, Response, REVIEWS_PER_PAGE } from "../reviewDbApi";
+import { settings } from "../settings";
+import { authorize, cl, showToast } from "../utils";
import ReviewComponent from "./ReviewComponent";
const Classes = findByPropsLazy("inputDefault", "editable");
-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: [],
- deps: [refetchCount],
+interface UserProps {
+ discordId: string;
+ name: string;
+}
+
+interface Props extends UserProps {
+ onFetchReviews(data: Response): void;
+ refetchSignal?: unknown;
+ showInput?: boolean;
+ page?: number;
+ scrollToTop?(): void;
+ hideOwnReview?: boolean;
+}
+
+export default function ReviewsView({
+ discordId,
+ name,
+ onFetchReviews,
+ refetchSignal,
+ scrollToTop,
+ page = 1,
+ showInput = false,
+ hideOwnReview = false,
+}: Props) {
+ const [signal, refetch] = useForceUpdater(true);
+
+ const [reviewData] = useAwaiter(() => getReviews(discordId, (page - 1) * REVIEWS_PER_PAGE), {
+ fallbackValue: null,
+ deps: [refetchSignal, signal, page],
+ onSuccess: data => {
+ scrollToTop?.();
+ onFetchReviews(data!);
+ }
});
- const username = UserStore.getUser(userId)?.username ?? "";
- const dirtyRefetch = () => setRefetchCount(refetchCount + 1);
+ if (!reviewData) return null;
+
+ return (
+ <>
+ <ReviewList
+ refetch={refetch}
+ reviews={reviewData!.reviews}
+ hideOwnReview={hideOwnReview}
+ />
+
+ {showInput && (
+ <ReviewsInputComponent
+ name={name}
+ discordId={discordId}
+ refetch={refetch}
+ isAuthor={reviewData!.reviews?.some(r => r.sender.discordID === UserStore.getCurrentUser().id)}
+ />
+ )}
+ </>
+ );
+}
+
+function ReviewList({ refetch, reviews, hideOwnReview }: { refetch(): void; reviews: Review[]; hideOwnReview: boolean; }) {
+ const myId = UserStore.getCurrentUser().id;
+
+ return (
+ <div className={cl("view")}>
+ {reviews?.map(review =>
+ (review.sender.discordID !== myId || !hideOwnReview) &&
+ <ReviewComponent
+ key={review.id}
+ review={review}
+ refetch={refetch}
+ />
+ )}
+
+ {reviews?.length === 0 && (
+ <Forms.FormText className={cl("placeholder")}>
+ Looks like nobody reviewed this user yet. You could be the first!
+ </Forms.FormText>
+ )}
+ </div>
+ );
+}
- if (isLoading) return null;
+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: userId,
+ userid: discordId,
comment: (target as HTMLInputElement).value,
star: -1
}).then(res => {
if (res?.success) {
(target as HTMLInputElement).value = ""; // clear the input
- dirtyRefetch();
+ refetch();
} else if (res?.message) {
showToast(res.message);
}
@@ -60,61 +131,27 @@ export default function ReviewsView({ userId }: { userId: string; }) {
}
return (
- <div className="vc-reviewdb-view">
- <Text
- tag="h2"
- variant="eyebrow"
- style={{
- marginBottom: "8px",
- color: "var(--header-primary)"
- }}
- >
- User Reviews
- </Text>
- {reviews?.map(review =>
- <ReviewComponent
- key={review.id}
- review={review}
- refetch={dirtyRefetch}
- />
- )}
- {reviews?.length === 0 && (
- <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!
- </Forms.FormText>
- )}
- <textarea
- className={classes(Classes.inputDefault, "enter-comment")}
- onKeyDownCapture={e => {
- if (e.key === "Enter") {
- e.preventDefault(); // prevent newlines
- }
- }}
- placeholder={
- token
- ? (reviews?.some(r => r.sender.discordID === UserStore.getCurrentUser().id)
- ? `Update review for @${username}`
- : `Review @${username}`)
- : "You need to authorize to review users!"
+ <textarea
+ className={classes(Classes.inputDefault, "enter-comment", cl("input"))}
+ onKeyDownCapture={e => {
+ if (e.key === "Enter") {
+ e.preventDefault(); // prevent newlines
}
- onKeyDown={onKeyPress}
- onClick={() => {
- if (!token) {
- showToast("Opening authorization window...");
- authorize();
- }
- }}
-
- style={{
- marginTop: "6px",
- resize: "none",
- marginBottom: "12px",
- overflow: "hidden",
- background: "transparent",
- border: "1px solid var(--profile-message-input-border-color)",
- fontSize: "14px",
- }}
- />
- </div>
+ }}
+ placeholder={
+ !token
+ ? "You need to authorize to review users!"
+ : isAuthor
+ ? `Update review for @${name}`
+ : `Review @${name}`
+ }
+ onKeyDown={onKeyPress}
+ onClick={() => {
+ if (!token) {
+ showToast("Opening authorization window...");
+ authorize();
+ }
+ }}
+ />
);
}