feat: implement undo friendship on friendlist modal

This commit is contained in:
Zamitto 2024-07-30 16:42:48 -03:00
parent f631cd3013
commit d9c140b2ab
3 changed files with 57 additions and 35 deletions

View File

@ -8,31 +8,28 @@ import cn from "classnames";
import { SPACING_UNIT } from "@renderer/theme.css";
import { useTranslation } from "react-i18next";
export interface UserFriendItemProps {
export type UserFriendItemProps = {
userId: string;
profileImageUrl: string | null;
displayName: string;
type: "SENT" | "RECEIVED" | "ACCEPTED";
onClickCancelRequest: (userId: string) => void;
onClickAcceptRequest: (userId: string) => void;
onClickRefuseRequest: (userId: string) => void;
onClickItem: (userId: string) => void;
}
} & (
| { type: "ACCEPTED"; onClickUndoFriendship: (userId: string) => void }
| {
type: "SENT" | "RECEIVED";
onClickCancelRequest: (userId: string) => void;
onClickAcceptRequest: (userId: string) => void;
onClickRefuseRequest: (userId: string) => void;
}
| { type: null }
);
export const UserFriendItem = ({
userId,
profileImageUrl,
displayName,
type,
onClickCancelRequest,
onClickAcceptRequest,
onClickRefuseRequest,
onClickItem,
}: UserFriendItemProps) => {
export const UserFriendItem = (props: UserFriendItemProps) => {
const { t } = useTranslation("user_profile");
const { userId, profileImageUrl, displayName, type, onClickItem } = props;
const getRequestDescription = () => {
if (type === null) return null;
if (type === "ACCEPTED" || type === null) return null;
return (
<small>
@ -42,11 +39,13 @@ export const UserFriendItem = ({
};
const getRequestActions = () => {
if (type === null) return null;
if (type === "SENT") {
return (
<button
className={styles.cancelRequestButton}
onClick={() => onClickCancelRequest(userId)}
onClick={() => props.onClickCancelRequest(userId)}
title={t("cancel_request")}
>
<XCircleIcon size={28} />
@ -59,14 +58,14 @@ export const UserFriendItem = ({
<>
<button
className={styles.acceptRequestButton}
onClick={() => onClickAcceptRequest(userId)}
onClick={() => props.onClickAcceptRequest(userId)}
title={t("accept_request")}
>
<CheckCircleIcon size={28} />
</button>
<button
className={styles.cancelRequestButton}
onClick={() => onClickRefuseRequest(userId)}
onClick={() => props.onClickRefuseRequest(userId)}
title={t("ignore_request")}
>
<XCircleIcon size={28} />
@ -75,15 +74,19 @@ export const UserFriendItem = ({
);
}
return (
<button
className={styles.cancelRequestButton}
onClick={() => onClickCancelRequest(userId)}
title={t("undo_friendship")}
>
<XCircleIcon size={28} />
</button>
);
if (type === "ACCEPTED") {
return (
<button
className={styles.cancelRequestButton}
onClick={() => props.onClickUndoFriendship(userId)}
title={t("undo_friendship")}
>
<XCircleIcon size={28} />
</button>
);
}
return null;
};
return (

View File

@ -3,6 +3,8 @@ import { UserFriend } from "@types";
import { useEffect, useState } from "react";
import { UserFriendItem } from "./user-friend-item";
import { useNavigate } from "react-router-dom";
import { useToast, useUserDetails } from "@renderer/hooks";
import { useTranslation } from "react-i18next";
export interface UserFriendModalListProps {
userId: string;
@ -15,12 +17,17 @@ export const UserFriendModalList = ({
userId,
closeModal,
}: UserFriendModalListProps) => {
const { t } = useTranslation("user_profile");
const { showErrorToast } = useToast();
const navigate = useNavigate();
const [page, setPage] = useState(0);
const [maxPage, setMaxPage] = useState(0);
const [friends, setFriends] = useState<UserFriend[]>([]);
const { userDetails, undoFriendship } = useUserDetails();
const isMe = userDetails?.id == userId;
const loadNextPage = () => {
if (page > maxPage) return;
window.electron
@ -36,11 +43,15 @@ export const UserFriendModalList = ({
.catch(() => {});
};
useEffect(() => {
const reloadList = () => {
setPage(0);
setMaxPage(0);
setFriends([]);
loadNextPage();
};
useEffect(() => {
reloadList();
}, [userId]);
const handleClickFriend = (userId: string) => {
@ -48,6 +59,16 @@ export const UserFriendModalList = ({
navigate(`/user/${userId}`);
};
const handleUndoFriendship = (userId: string) => {
undoFriendship(userId)
.then(() => {
reloadList();
})
.catch(() => {
showErrorToast(t("try_again"));
});
};
return (
<div
style={{
@ -62,11 +83,9 @@ export const UserFriendModalList = ({
userId={friend.id}
displayName={friend.displayName}
profileImageUrl={friend.profileImageUrl}
onClickAcceptRequest={() => {}}
onClickCancelRequest={() => {}}
onClickRefuseRequest={() => {}}
onClickItem={handleClickFriend}
type={"ACCEPTED"}
onClickUndoFriendship={handleUndoFriendship}
type={isMe ? "ACCEPTED" : null}
key={friend.id}
/>
);

View File

@ -301,7 +301,7 @@ export interface UserProfile {
id: string;
displayName: string;
profileImageUrl: string | null;
profileVisibility: "PUBLIC" | "PRIVATE" | "FRIEND";
profileVisibility: "PUBLIC" | "PRIVATE" | "FRIENDS";
totalPlayTimeInSeconds: number;
libraryGames: UserGame[];
recentGames: UserGame[];