diff --git a/src/main/events/index.ts b/src/main/events/index.ts index 9cdc58b5..3963e4b0 100644 --- a/src/main/events/index.ts +++ b/src/main/events/index.ts @@ -43,6 +43,7 @@ import "./auth/sign-out"; import "./auth/open-auth-window"; import "./auth/get-session-hash"; import "./user/get-user"; +import "./user/get-user-blocks"; import "./user/block-user"; import "./user/unblock-user"; import "./user/get-user-friends"; diff --git a/src/main/events/user/get-user-blocks.ts b/src/main/events/user/get-user-blocks.ts new file mode 100644 index 00000000..65bb3eb4 --- /dev/null +++ b/src/main/events/user/get-user-blocks.ts @@ -0,0 +1,13 @@ +import { registerEvent } from "../register-event"; +import { HydraApi } from "@main/services"; +import { UserBlocks } from "@types"; + +export const getUserBlocks = async ( + _event: Electron.IpcMainInvokeEvent, + take: number, + skip: number +): Promise => { + return HydraApi.get(`/profile/blocks`, { take, skip }); +}; + +registerEvent("getUserBlocks", getUserBlocks); diff --git a/src/preload/index.ts b/src/preload/index.ts index 84100cab..087d573a 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -152,6 +152,8 @@ contextBridge.exposeInMainWorld("electron", { unblockUser: (userId: string) => ipcRenderer.invoke("unblockUser", userId), getUserFriends: (userId: string, take: number, skip: number) => ipcRenderer.invoke("getUserFriends", userId, take, skip), + getUserBlocks: (take: number, skip: number) => + ipcRenderer.invoke("getUserBlocks", take, skip), /* Auth */ signOut: () => ipcRenderer.invoke("signOut"), diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 3e954d40..29e4dcbb 100644 --- a/src/renderer/src/declaration.d.ts +++ b/src/renderer/src/declaration.d.ts @@ -17,6 +17,7 @@ import type { FriendRequest, FriendRequestAction, UserFriends, + UserBlocks, } from "@types"; import type { DiskSpace } from "check-disk-space"; @@ -135,6 +136,7 @@ declare global { take: number, skip: number ) => Promise; + getUserBlocks: (take: number, skip: number) => Promise; /* Profile */ getMe: () => Promise; diff --git a/src/renderer/src/pages/user/user-profile-settings-modal/user-block-list.tsx b/src/renderer/src/pages/user/user-profile-settings-modal/user-block-list.tsx index e69de29b..5b5d0e74 100644 --- a/src/renderer/src/pages/user/user-profile-settings-modal/user-block-list.tsx +++ b/src/renderer/src/pages/user/user-profile-settings-modal/user-block-list.tsx @@ -0,0 +1,92 @@ +import { SPACING_UNIT } from "@renderer/theme.css"; +import { UserFriend } from "@types"; +import { useEffect, useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { useToast, useUserDetails } from "@renderer/hooks"; +import { useTranslation } from "react-i18next"; +import { UserFriendItem } from "@renderer/pages/shared-modals/user-friend-modal/user-friend-item"; + +export interface UserEditProfileBlockListProps { + closeModal: () => void; +} + +const pageSize = 12; + +export const UserEditProfileBlockList = ({ + closeModal, +}: UserEditProfileBlockListProps) => { + const { t } = useTranslation("user_profile"); + const { showErrorToast } = useToast(); + const navigate = useNavigate(); + + const [page, setPage] = useState(0); + const [maxPage, setMaxPage] = useState(0); + const [blocks, setBlocks] = useState([]); + + const { unblockUser } = useUserDetails(); + + const loadNextPage = () => { + if (page > maxPage) return; + window.electron + .getUserBlocks(pageSize, page * pageSize) + .then((newPage) => { + if (page === 0) { + setMaxPage(newPage.totalBlocks / pageSize); + } + + setBlocks([...blocks, ...newPage.blocks]); + setPage(page + 1); + }) + .catch(() => {}); + }; + + const reloadList = () => { + setPage(0); + setMaxPage(0); + setBlocks([]); + loadNextPage(); + }; + + useEffect(() => { + reloadList(); + }, []); + + const handleClickBlocked = (userId: string) => { + closeModal(); + navigate(`/user/${userId}`); + }; + + const handleUnblock = (userId: string) => { + unblockUser(userId) + .then(() => { + reloadList(); + }) + .catch(() => { + showErrorToast(t("try_again")); + }); + }; + + return ( +
+ {blocks.map((friend) => { + return ( + + ); + })} +
+ ); +}; diff --git a/src/renderer/src/pages/user/user-profile-settings-modal/user-profile-settings-modal.tsx b/src/renderer/src/pages/user/user-profile-settings-modal/user-profile-settings-modal.tsx index 7818b4f8..a2fcb372 100644 --- a/src/renderer/src/pages/user/user-profile-settings-modal/user-profile-settings-modal.tsx +++ b/src/renderer/src/pages/user/user-profile-settings-modal/user-profile-settings-modal.tsx @@ -4,8 +4,9 @@ import { SPACING_UNIT } from "@renderer/theme.css"; import { useState } from "react"; import { useTranslation } from "react-i18next"; import { UserEditProfile } from "./user-edit-profile"; +import { UserEditProfileBlockList } from "./user-block-list"; -export interface UserEditProfileModalProps { +export interface UserProfileSettingsModalProps { userProfile: UserProfile; visible: boolean; onClose: () => void; @@ -17,7 +18,7 @@ export const UserProfileSettingsModal = ({ visible, onClose, updateUserProfile, -}: UserEditProfileModalProps) => { +}: UserProfileSettingsModalProps) => { const { t } = useTranslation("user_profile"); const tabs = [t("edit_profile"), t("blocked_users")]; @@ -35,7 +36,7 @@ export const UserProfileSettingsModal = ({ } if (currentTabIndex == 1) { - return <>; + return ; } return <>; diff --git a/src/types/index.ts b/src/types/index.ts index cb2f8c27..6200d825 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -282,6 +282,11 @@ export interface UserFriends { friends: UserFriend[]; } +export interface UserBlocks { + totalBlocks: number; + blocks: UserFriend[]; +} + export interface FriendRequest { id: string; displayName: string;