diff --git a/src/main/events/index.ts b/src/main/events/index.ts index 64f95108..ab82eefd 100644 --- a/src/main/events/index.ts +++ b/src/main/events/index.ts @@ -45,6 +45,7 @@ import "./auth/get-session-hash"; import "./user/get-user"; import "./profile/get-friend-requests"; import "./profile/get-me"; +import "./profile/update-friend-request"; import "./profile/update-profile"; ipcMain.handle("ping", () => "pong"); diff --git a/src/main/events/profile/get-friend-requests.ts b/src/main/events/profile/get-friend-requests.ts index ba2cf1b5..0e75efba 100644 --- a/src/main/events/profile/get-friend-requests.ts +++ b/src/main/events/profile/get-friend-requests.ts @@ -1,10 +1,10 @@ import { registerEvent } from "../register-event"; import { HydraApi } from "@main/services"; -import { PendingFriendRequest } from "@types"; +import { FriendRequest } from "@types"; const getFriendRequests = async ( _event: Electron.IpcMainInvokeEvent -): Promise => { +): Promise => { try { const response = await HydraApi.get(`/profile/friend-requests`); return response.data; diff --git a/src/main/events/profile/update-friend-request.ts b/src/main/events/profile/update-friend-request.ts new file mode 100644 index 00000000..24929544 --- /dev/null +++ b/src/main/events/profile/update-friend-request.ts @@ -0,0 +1,19 @@ +import { registerEvent } from "../register-event"; +import { HydraApi } from "@main/services"; +import { FriendRequestAction } from "@types"; + +const updateFriendRequest = async ( + _event: Electron.IpcMainInvokeEvent, + userId: string, + action: FriendRequestAction +) => { + if (action == "CANCEL") { + return HydraApi.delete(`/profile/friend-requests/${userId}`); + } + + return HydraApi.patch(`/profile/friend-requests/${userId}`, { + requestState: action, + }); +}; + +registerEvent("updateFriendRequest", updateFriendRequest); diff --git a/src/preload/index.ts b/src/preload/index.ts index 759b0224..26601ebd 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -9,6 +9,7 @@ import type { AppUpdaterEvent, StartGameDownloadPayload, GameRunning, + FriendRequestAction, } from "@types"; contextBridge.exposeInMainWorld("electron", { @@ -137,6 +138,8 @@ contextBridge.exposeInMainWorld("electron", { updateProfile: (displayName: string, newProfileImagePath: string | null) => ipcRenderer.invoke("updateProfile", displayName, newProfileImagePath), getFriendRequests: () => ipcRenderer.invoke("getFriendRequests"), + updateFriendRequest: (userId: string, action: FriendRequestAction) => + ipcRenderer.invoke("updateFriendRequest", userId, action), /* User */ getUser: (userId: string) => ipcRenderer.invoke("getUser", userId), diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 0ff9e876..747f8be4 100644 --- a/src/renderer/src/declaration.d.ts +++ b/src/renderer/src/declaration.d.ts @@ -14,7 +14,8 @@ import type { RealDebridUser, DownloadSource, UserProfile, - PendingFriendRequest, + FriendRequest, + FriendRequestAction, } from "@types"; import type { DiskSpace } from "check-disk-space"; @@ -133,7 +134,11 @@ declare global { displayName: string, newProfileImagePath: string | null ) => Promise; - getFriendRequests: () => Promise; + getFriendRequests: () => Promise; + updateFriendRequest: ( + userId: string, + action: FriendRequestAction + ) => Promise; } interface Window { diff --git a/src/renderer/src/features/user-details-slice.ts b/src/renderer/src/features/user-details-slice.ts index 0cc395b0..1912c810 100644 --- a/src/renderer/src/features/user-details-slice.ts +++ b/src/renderer/src/features/user-details-slice.ts @@ -1,14 +1,16 @@ import { PayloadAction, createSlice } from "@reduxjs/toolkit"; -import type { UserDetails } from "@types"; +import type { FriendRequest, UserDetails } from "@types"; export interface UserDetailsState { userDetails: UserDetails | null; profileBackground: null | string; + friendRequests: FriendRequest[] | null; } const initialState: UserDetailsState = { userDetails: null, profileBackground: null, + friendRequests: null, }; export const userDetailsSlice = createSlice({ @@ -21,8 +23,14 @@ export const userDetailsSlice = createSlice({ setProfileBackground: (state, action: PayloadAction) => { state.profileBackground = action.payload; }, + setFriendRequests: ( + state, + action: PayloadAction + ) => { + state.friendRequests = action.payload; + }, }, }); -export const { setUserDetails, setProfileBackground } = +export const { setUserDetails, setProfileBackground, setFriendRequests } = userDetailsSlice.actions; diff --git a/src/renderer/src/hooks/use-user-details.ts b/src/renderer/src/hooks/use-user-details.ts index d39c2578..bdbfcf2c 100644 --- a/src/renderer/src/hooks/use-user-details.ts +++ b/src/renderer/src/hooks/use-user-details.ts @@ -2,14 +2,18 @@ import { useCallback } from "react"; import { average } from "color.js"; import { useAppDispatch, useAppSelector } from "./redux"; -import { setProfileBackground, setUserDetails } from "@renderer/features"; +import { + setProfileBackground, + setUserDetails, + setFriendRequests, +} from "@renderer/features"; import { darkenColor } from "@renderer/helpers"; import { UserDetails } from "@types"; export function useUserDetails() { const dispatch = useAppDispatch(); - const { userDetails, profileBackground } = useAppSelector( + const { userDetails, profileBackground, friendRequests } = useAppSelector( (state) => state.userDetails ); @@ -82,19 +86,21 @@ export function useUserDetails() { console.log("sending friend request to", userId); }, []); - const fetchPendingRequests = useCallback(async () => { - return window.electron.getFriendRequests(); - }, []); + const updateFriendRequests = useCallback(async () => { + const friendRequests = await window.electron.getFriendRequests(); + dispatch(setFriendRequests(friendRequests)); + }, [dispatch]); return { userDetails, + profileBackground, + friendRequests, fetchUserDetails, signOut, clearUserDetails, updateUserDetails, patchUser, sendFriendRequest, - fetchPendingRequests, - profileBackground, + updateFriendRequests, }; } diff --git a/src/renderer/src/pages/user/user-add-friends-modal.tsx b/src/renderer/src/pages/user/user-add-friends-modal.tsx index 3037eadb..c5a2d9ec 100644 --- a/src/renderer/src/pages/user/user-add-friends-modal.tsx +++ b/src/renderer/src/pages/user/user-add-friends-modal.tsx @@ -1,22 +1,19 @@ import { Button, Modal, TextField } from "@renderer/components"; -import { PendingFriendRequest } from "@types"; import { SPACING_UNIT } from "@renderer/theme.css"; import { useState } from "react"; import { useToast, useUserDetails } from "@renderer/hooks"; import { useTranslation } from "react-i18next"; import { useNavigate } from "react-router-dom"; -import { UserFriendPendingRequest } from "./user-friend-pending-request"; +import { UserFriendRequest } from "./user-friend-request"; export interface UserAddFriendsModalProps { visible: boolean; onClose: () => void; - pendingRequests: PendingFriendRequest[]; } export const UserAddFriendsModal = ({ visible, onClose, - pendingRequests, }: UserAddFriendsModalProps) => { const { t } = useTranslation("user_profile"); @@ -25,7 +22,8 @@ export const UserAddFriendsModal = ({ const navigate = useNavigate(); - const { sendFriendRequest } = useUserDetails(); + const { sendFriendRequest, updateFriendRequests, friendRequests } = + useUserDetails(); const { showSuccessToast, showErrorToast } = useToast(); @@ -33,6 +31,7 @@ export const UserAddFriendsModal = ({ setIsAddingFriend(true); sendFriendRequest(friendCode) .then(() => { + updateFriendRequests(); showSuccessToast(t("friend_request_sent")); }) .catch(() => { @@ -54,14 +53,17 @@ export const UserAddFriendsModal = ({ const handleClickCancelFriendRequest = (userId: string) => { console.log(userId); + updateFriendRequests(); }; const handleClickAcceptFriendRequest = (userId: string) => { console.log(userId); + updateFriendRequests(); }; const handleClickRefuseFriendRequest = (userId: string) => { console.log(userId); + updateFriendRequests(); }; const resetModal = () => { @@ -131,9 +133,9 @@ export const UserAddFriendsModal = ({ }} >

Pendentes

- {pendingRequests.map((request) => { + {friendRequests?.map((request) => { return ( - ([]); - const isMe = userDetails?.id == userProfile.id; useEffect(() => { - window.electron.getFriendRequests().then((friendsRequests) => { - setPendingRequests(friendsRequests ?? []); - }); + if (isMe) updateFriendRequests(); }, [isMe]); const profileContentBoxBackground = useMemo(() => { @@ -123,7 +118,6 @@ export function UserContent({ /> setShowAddFriendsModal(false)} /> diff --git a/src/renderer/src/pages/user/user-friend-pending-request.tsx b/src/renderer/src/pages/user/user-friend-request.tsx similarity index 94% rename from src/renderer/src/pages/user/user-friend-pending-request.tsx rename to src/renderer/src/pages/user/user-friend-request.tsx index 99fcb2f7..1348cc2b 100644 --- a/src/renderer/src/pages/user/user-friend-pending-request.tsx +++ b/src/renderer/src/pages/user/user-friend-request.tsx @@ -6,7 +6,7 @@ import { import * as styles from "./user.css"; import cn from "classnames"; -export interface UserFriendPendingRequestProps { +export interface UserFriendRequestProps { userId: string; profileImageUrl: string | null; displayName: string; @@ -17,7 +17,7 @@ export interface UserFriendPendingRequestProps { onClickRequest: (userId: string) => void; } -export const UserFriendPendingRequest = ({ +export const UserFriendRequest = ({ userId, profileImageUrl, displayName, @@ -26,7 +26,7 @@ export const UserFriendPendingRequest = ({ onClickAcceptRequest, onClickRefuseRequest, onClickRequest, -}: UserFriendPendingRequestProps) => { +}: UserFriendRequestProps) => { return (