feat: pass userId to modal

This commit is contained in:
Zamitto 2024-07-23 20:27:38 -03:00
parent 010f07373d
commit a196b91cb9
9 changed files with 104 additions and 31 deletions

View File

@ -145,7 +145,8 @@ contextBridge.exposeInMainWorld("electron", {
/* User */
getUser: (userId: string) => ipcRenderer.invoke("getUser", userId),
getUserFriends: (userId: string) => ipcRenderer.invoke("getUserFriends", userId),
getUserFriends: (userId: string, take: number, skip: number) =>
ipcRenderer.invoke("getUserFriends", userId, take, skip),
/* Auth */
signOut: () => ipcRenderer.invoke("signOut"),

View File

@ -42,11 +42,12 @@ export function App() {
const {
isFriendsModalVisible,
friendRequetsModalTab,
friendModalUserId,
fetchFriendRequests,
hideFriendsModal,
} = useUserDetails();
const { fetchUserDetails, updateUserDetails, clearUserDetails } =
const { userDetails, fetchUserDetails, updateUserDetails, clearUserDetails } =
useUserDetails();
const dispatch = useAppDispatch();
@ -218,11 +219,14 @@ export function App() {
onClose={handleToastClose}
/>
<UserFriendModal
visible={isFriendsModalVisible}
initialTab={friendRequetsModalTab}
onClose={hideFriendsModal}
/>
{userDetails && (
<UserFriendModal
visible={isFriendsModalVisible}
initialTab={friendRequetsModalTab}
onClose={hideFriendsModal}
userId={friendModalUserId}
/>
)}
<main>
<Sidebar />

View File

@ -84,7 +84,9 @@ export function SidebarProfile() {
<button
type="button"
className={styles.friendRequestButton}
onClick={() => showFriendsModal(UserFriendModalTab.AddFriend)}
onClick={() =>
showFriendsModal(UserFriendModalTab.AddFriend, userDetails.id)
}
>
<PersonAddIcon size={24} />
{friendRequests.length}

View File

@ -128,7 +128,11 @@ declare global {
/* User */
getUser: (userId: string) => Promise<UserProfile | null>;
getUserFriends: (userId: string) => Promise<UserFriends>;
getUserFriends: (
userId: string,
take: number,
skip: number
) => Promise<UserFriends>;
/* Profile */
getMe: () => Promise<UserProfile | null>;

View File

@ -8,6 +8,7 @@ export interface UserDetailsState {
friendRequests: FriendRequest[];
isFriendsModalVisible: boolean;
friendRequetsModalTab: UserFriendModalTab | null;
friendModalUserId: string;
}
const initialState: UserDetailsState = {
@ -16,6 +17,7 @@ const initialState: UserDetailsState = {
friendRequests: [],
isFriendsModalVisible: false,
friendRequetsModalTab: null,
friendModalUserId: "",
};
export const userDetailsSlice = createSlice({
@ -33,10 +35,11 @@ export const userDetailsSlice = createSlice({
},
setFriendsModalVisible: (
state,
action: PayloadAction<UserFriendModalTab>
action: PayloadAction<{ initialTab: UserFriendModalTab; userId: string }>
) => {
state.isFriendsModalVisible = true;
state.friendRequetsModalTab = action.payload;
state.friendRequetsModalTab = action.payload.initialTab;
state.friendModalUserId = action.payload.userId;
},
setFriendsModalHidden: (state) => {
state.isFriendsModalVisible = false;

View File

@ -19,6 +19,7 @@ export function useUserDetails() {
profileBackground,
friendRequests,
isFriendsModalVisible,
friendModalUserId,
friendRequetsModalTab,
} = useAppSelector((state) => state.userDetails);
@ -90,8 +91,8 @@ export function useUserDetails() {
}, [dispatch]);
const showFriendsModal = useCallback(
(tab: UserFriendModalTab) => {
dispatch(setFriendsModalVisible(tab));
(initialTab: UserFriendModalTab, userId: string) => {
dispatch(setFriendsModalVisible({ initialTab, userId }));
fetchFriendRequests();
},
[dispatch]
@ -125,6 +126,7 @@ export function useUserDetails() {
friendRequests,
friendRequetsModalTab,
isFriendsModalVisible,
friendModalUserId,
showFriendsModal,
hideFriendsModal,
fetchUserDetails,

View File

@ -0,0 +1,40 @@
import { UserFriend } from "@types";
import { useEffect, useState } from "react";
export interface UserFriendModalListProps {
userId: string;
}
const pageSize = 12;
export const UserFriendModalList = ({ userId }: UserFriendModalListProps) => {
const [page, setPage] = useState(0);
const [maxPage, setMaxPage] = useState(0);
const [friends, setFriends] = useState<UserFriend[]>([]);
const loadNextPage = () => {
if (page > maxPage) return;
window.electron
.getUserFriends(userId, pageSize, page * pageSize)
.then((newPage) => {
if (page === 0) {
setMaxPage(newPage.totalFriends / pageSize);
}
setFriends([...friends, ...newPage.friends]);
setPage(page + 1);
})
.catch(() => {});
};
useEffect(() => {
setPage(0);
setMaxPage(0);
setFriends([]);
loadNextPage();
}, [userId]);
return friends.map((friend) => {
return <p key={friend.id}>{friend.displayName}</p>;
});
};

View File

@ -3,23 +3,27 @@ import { SPACING_UNIT } from "@renderer/theme.css";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { UserFriendModalAddFriend } from "./user-friend-modal-add-friend";
import { useUserDetails } from "@renderer/hooks";
import { UserFriendModalList } from "./user-friend-modal-list";
export enum UserFriendModalTab {
FriendsList,
AddFriend,
}
export interface UserAddFriendsModalProps {
export interface UserFriendsModalProps {
visible: boolean;
onClose: () => void;
initialTab: UserFriendModalTab | null;
userId: string;
}
export const UserFriendModal = ({
visible,
onClose,
initialTab,
}: UserAddFriendsModalProps) => {
userId,
}: UserFriendsModalProps) => {
const { t } = useTranslation("user_profile");
const tabs = [t("friends_list"), t("add_friends")];
@ -28,6 +32,9 @@ export const UserFriendModal = ({
initialTab || UserFriendModalTab.FriendsList
);
const { userDetails } = useUserDetails();
const isMe = userDetails?.id == userId;
useEffect(() => {
if (initialTab != null) {
setCurrentTab(initialTab);
@ -36,7 +43,7 @@ export const UserFriendModal = ({
const renderTab = () => {
if (currentTab == UserFriendModalTab.FriendsList) {
return <></>;
return <UserFriendModalList userId={userId} />;
}
if (currentTab == UserFriendModalTab.AddFriend) {
@ -56,19 +63,21 @@ export const UserFriendModal = ({
gap: `${SPACING_UNIT * 2}px`,
}}
>
<section style={{ display: "flex", gap: `${SPACING_UNIT}px` }}>
{tabs.map((tab, index) => {
return (
<Button
key={tab}
theme={index === currentTab ? "primary" : "outline"}
onClick={() => setCurrentTab(index)}
>
{tab}
</Button>
);
})}
</section>
{isMe && (
<section style={{ display: "flex", gap: `${SPACING_UNIT}px` }}>
{tabs.map((tab, index) => {
return (
<Button
key={tab}
theme={index === currentTab ? "primary" : "outline"}
onClick={() => setCurrentTab(index)}
>
{tab}
</Button>
);
})}
</section>
)}
<h2>{tabs[currentTab]}</h2>
{renderTab()}
</div>

View File

@ -424,7 +424,12 @@ export function UserContent({
<div className={styles.friendsSection}>
<button
className={styles.friendsSectionHeader}
onClick={() => showFriendsModal(UserFriendModalTab.FriendsList)}
onClick={() =>
showFriendsModal(
UserFriendModalTab.FriendsList,
userProfile.id
)
}
>
<h2>{t("friends")}</h2>
@ -480,7 +485,10 @@ export function UserContent({
<Button
theme="outline"
onClick={() =>
showFriendsModal(UserFriendModalTab.AddFriend)
showFriendsModal(
UserFriendModalTab.AddFriend,
userProfile.id
)
}
>
<PlusIcon /> {t("add")}