diff --git a/src/atoms/global.ts b/src/atoms/global.ts index f05da75..443d833 100644 --- a/src/atoms/global.ts +++ b/src/atoms/global.ts @@ -177,4 +177,9 @@ export const mailsAtom = atom({ export const groupsPropertiesAtom = atom({ key: 'groupsPropertiesAtom', default: {}, +}); + +export const isOpenBlockedModalAtom = atom({ + key: 'isOpenBlockedModalAtom', + default: false, }); \ No newline at end of file diff --git a/src/components/Group/BlockedUsersModal.tsx b/src/components/Group/BlockedUsersModal.tsx index 84fa3fa..e81d207 100644 --- a/src/components/Group/BlockedUsersModal.tsx +++ b/src/components/Group/BlockedUsersModal.tsx @@ -10,15 +10,23 @@ import { Typography, } from "@mui/material"; import React, { useContext, useEffect, useState } from "react"; -import { MyContext } from "../../App"; +import { getBaseApiReact, MyContext } from "../../App"; import { Spacer } from "../../common/Spacer"; -import { executeEvent } from "../../utils/events"; - -export const BlockedUsersModal = ({ close }) => { +import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events"; +import { validateAddress } from "../../utils/validateAddress"; +import { getNameInfo, requestQueueMemberNames } from "./Group"; +import { useModal } from "../../common/useModal"; +import { useRecoilState } from "recoil"; +import { isOpenBlockedModalAtom } from "../../atoms/global"; +import InfoIcon from '@mui/icons-material/Info'; +export const BlockedUsersModal = () => { + const [isOpenBlockedModal, setIsOpenBlockedModal] = useRecoilState(isOpenBlockedModalAtom) const [hasChanged, setHasChanged] = useState(false); const [value, setValue] = useState(""); - - const { getAllBlockedUsers, removeBlockFromList, addToBlockList } = useContext(MyContext); + const [addressesWithNames, setAddressesWithNames] = useState({}) + const { isShow, onCancel, onOk, show, message } = useModal(); + const { getAllBlockedUsers, removeBlockFromList, addToBlockList } = + useContext(MyContext); const [blockedUsers, setBlockedUsers] = useState({ addresses: {}, names: {}, @@ -28,60 +36,157 @@ export const BlockedUsersModal = ({ close }) => { }; useEffect(() => { + if(!isOpenBlockedModal) return fetchBlockedUsers(); - }, []); + }, [isOpenBlockedModal]); + + const getNames = async () => { + // const validApi = await findUsableApi(); + const addresses = Object.keys(blockedUsers?.addresses) + const addressNames = {} + + + const getMemNames = addresses.map(async (address) => { + const name = await requestQueueMemberNames.enqueue(() => { + return getNameInfo(address); + }); + if (name) { + addressNames[address] = name + } + + + return true; + }); + + await Promise.all(getMemNames); + + setAddressesWithNames(addressNames) + }; + + const blockUser = async (e, user?: string) => { + try { + const valUser = user || value + if (!valUser) return; + const isAddress = validateAddress(valUser); + let userName = null; + let userAddress = null; + if (isAddress) { + userAddress = valUser; + const name = await getNameInfo(valUser); + if (name) { + userName = name; + } + } + if (!isAddress) { + const response = await fetch(`${getBaseApiReact()}/names/${valUser}`); + const data = await response.json(); + if (!data?.owner) throw new Error("Name does not exist"); + if (data?.owner) { + userAddress = data.owner; + userName = valUser; + } + } + if(!userName){ + await addToBlockList(userAddress, null); + fetchBlockedUsers(); + setHasChanged(true); + executeEvent('updateChatMessagesWithBlocks', true) + setValue('') + return + } + const responseModal = await show({ + userName, + userAddress, + }); + if (responseModal === "both") { + await addToBlockList(userAddress, userName); + } else if (responseModal === "address") { + await addToBlockList(userAddress, null); + } else if (responseModal === "name") { + await addToBlockList(null, userName); + } + fetchBlockedUsers(); + setHasChanged(true); + setValue('') + if(user){ + setIsOpenBlockedModal(false) + } + if(responseModal === 'both' || responseModal === 'address'){ + executeEvent('updateChatMessagesWithBlocks', true) + } + } catch (error) { + console.error(error); + } + }; + const blockUserFromOutsideModalFunc = (e) => { + const user = e.detail?.user; + setIsOpenBlockedModal(true) + blockUser(null, user) + }; + + useEffect(() => { + subscribeToEvent("blockUserFromOutside", blockUserFromOutsideModalFunc); + + return () => { + unsubscribeFromEvent("blockUserFromOutside", blockUserFromOutsideModalFunc); + }; + }, []); return ( - Blocked Users - - Blocked Users + - { - setValue(e.target.value); + > + - - - + > + { + setValue(e.target.value); + }} + /> + + + {Object.entries(blockedUsers?.addresses).length > 0 && ( <> - Blocked Users for Chat ( addresses ) + Blocked addresses- blocks processing of txs + + )} - + {Object.entries(blockedUsers?.addresses || {})?.map( ([key, value]) => { return ( @@ -90,18 +195,22 @@ export const BlockedUsersModal = ({ close }) => { display: "flex", alignItems: "center", gap: "10px", - width: '100%', - justifyContent: 'space-between' + width: "100%", + justifyContent: "space-between", }} > - {key} + {addressesWithNames[key] || key} + + + + {"Decide what to block"} + + + + Blocking {message?.userName || message?.userAddress} + + + Choose "block txs" or "all" to block chat messages + + + + + + + + ); }; diff --git a/src/components/Group/Group.tsx b/src/components/Group/Group.tsx index 64dc541..9f95a3a 100644 --- a/src/components/Group/Group.tsx +++ b/src/components/Group/Group.tsx @@ -75,9 +75,9 @@ import { MessagingIcon } from "../../assets/Icons/MessagingIcon"; import { formatEmailDate } from "./QMailMessages"; import { AdminSpace } from "../Chat/AdminSpace"; import { useRecoilState, useSetRecoilState } from "recoil"; -import { addressInfoControllerAtom, groupsPropertiesAtom, selectedGroupIdAtom } from "../../atoms/global"; +import { addressInfoControllerAtom, groupsPropertiesAtom, isOpenBlockedModalAtom, selectedGroupIdAtom } from "../../atoms/global"; import { sortArrayByTimestampAndGroupName } from "../../utils/time"; -import BlockIcon from '@mui/icons-material/Block'; +import PersonOffIcon from '@mui/icons-material/PersonOff'; import LockIcon from '@mui/icons-material/Lock'; import NoEncryptionGmailerrorredIcon from '@mui/icons-material/NoEncryptionGmailerrorred'; import { BlockedUsersModal } from "./BlockedUsersModal"; @@ -421,7 +421,7 @@ export const Group = ({ const [groupAnnouncements, setGroupAnnouncements] = React.useState({}); const [defaultThread, setDefaultThread] = React.useState(null); const [isOpenDrawer, setIsOpenDrawer] = React.useState(false); - const [isOpenBlockedUserModal, setIsOpenBlockedUserModal] = React.useState(false); + const setIsOpenBlockedUserModal = useSetRecoilState(isOpenBlockedModalAtom) const [hideCommonKeyPopup, setHideCommonKeyPopup] = React.useState(false); const [isLoadingGroupMessage, setIsLoadingGroupMessage] = React.useState(""); @@ -2035,7 +2035,7 @@ export const Group = ({ padding: '10px' }} > - )} - {isOpenBlockedUserModal && ( - { - setIsOpenBlockedUserModal(false) - }} /> - )} + + {selectedDirect && !newChat && ( <> diff --git a/src/components/Group/useBlockUsers.tsx b/src/components/Group/useBlockUsers.tsx index 05cbe90..eeb5361 100644 --- a/src/components/Group/useBlockUsers.tsx +++ b/src/components/Group/useBlockUsers.tsx @@ -19,7 +19,7 @@ export const useBlockedAddresses = () => { const isUserBlocked = useCallback((address, name)=> { try { if(!address) return false - if(userBlockedRef.current[address] || userNamesBlockedRef.current[name]) return true + if(userBlockedRef.current[address]) return true return false @@ -90,43 +90,13 @@ export const useBlockedAddresses = () => { }, []) const removeBlockFromList = useCallback(async (address, name)=> { - await new Promise((res, rej) => { - window.sendMessage("listActions", { - - type: 'remove', - items: name ? [name] : [address], - listName: name ? 'blockedNames' : 'blockedAddresses' - - }) - .then((response) => { - if (response.error) { - rej(response?.message); - return; - } else { - if(!name){ - const copyObject = {...userBlockedRef.current} - delete copyObject[address] - userBlockedRef.current = copyObject - } else { - const copyObject = {...userNamesBlockedRef.current} - delete copyObject[name] - userNamesBlockedRef.current = copyObject - } - - res(response); - } - }) - .catch((error) => { - console.error("Failed qortalRequest", error); - }); - }) - if(name && userBlockedRef.current[address]){ + if(name){ await new Promise((res, rej) => { window.sendMessage("listActions", { type: 'remove', - items: !name ? [name] : [address], - listName: !name ? 'blockedNames' : 'blockedAddresses' + items: [name] , + listName: 'blockedNames' }) .then((response) => { @@ -134,9 +104,12 @@ export const useBlockedAddresses = () => { rej(response?.message); return; } else { - const copyObject = {...userBlockedRef.current} - delete copyObject[address] - userBlockedRef.current = copyObject + + const copyObject = {...userNamesBlockedRef.current} + delete copyObject[name] + userNamesBlockedRef.current = copyObject + + res(response); } }) @@ -145,42 +118,95 @@ export const useBlockedAddresses = () => { }); }) } + + if(address){ + await new Promise((res, rej) => { + window.sendMessage("listActions", { + + type: 'remove', + items: [address], + listName: 'blockedAddresses' + + }) + .then((response) => { + if (response.error) { + rej(response?.message); + return; + } else { + + const copyObject = {...userBlockedRef.current} + delete copyObject[address] + userBlockedRef.current = copyObject + + + res(response); + } + }) + .catch((error) => { + console.error("Failed qortalRequest", error); + }); + }) + } + }, []) const addToBlockList = useCallback(async (address, name)=> { - await new Promise((res, rej) => { - window.sendMessage("listActions", { - - type: 'add', - items: name ? [name] : [address], - listName: name ? 'blockedNames' : 'blockedAddresses' - - }) - .then((response) => { - if (response.error) { - rej(response?.message); - return; - } else { - if(name){ - - const copyObject = {...userNamesBlockedRef.current} - copyObject[name] = true - userNamesBlockedRef.current = copyObject - }else { - const copyObject = {...userBlockedRef.current} - copyObject[address] = true - userBlockedRef.current = copyObject - - } + if(name){ + await new Promise((res, rej) => { + window.sendMessage("listActions", { - res(response); - } + type: 'add', + items: [name], + listName: 'blockedNames' + + }) + .then((response) => { + if (response.error) { + rej(response?.message); + return; + } else { + const copyObject = {...userNamesBlockedRef.current} + copyObject[name] = true + userNamesBlockedRef.current = copyObject + + + res(response); + } + }) + .catch((error) => { + console.error("Failed qortalRequest", error); + }); }) - .catch((error) => { - console.error("Failed qortalRequest", error); - }); - }) + } + if(address){ + await new Promise((res, rej) => { + window.sendMessage("listActions", { + + type: 'add', + items: [address], + listName: 'blockedAddresses' + + }) + .then((response) => { + if (response.error) { + rej(response?.message); + return; + } else { + + const copyObject = {...userBlockedRef.current} + copyObject[address] = true + userBlockedRef.current = copyObject + + res(response); + } + }) + .catch((error) => { + console.error("Failed qortalRequest", error); + }); + }) + } + }, []) return { diff --git a/src/components/WrapperUserAction.tsx b/src/components/WrapperUserAction.tsx index a3bcc3f..c074c16 100644 --- a/src/components/WrapperUserAction.tsx +++ b/src/components/WrapperUserAction.tsx @@ -169,12 +169,15 @@ useEffect(()=> { onClick={async () => { try { setIsLoading(true) - if(isAlreadyBlocked === true){ - await removeBlockFromList(address, name) - } else if(isAlreadyBlocked === false) { - await addToBlockList(address, name) - } - executeEvent('updateChatMessagesWithBlocks', true) + executeEvent("blockUserFromOutside", { + user: address + }) + // if(isAlreadyBlocked === true){ + // await removeBlockFromList(address, name) + // } else if(isAlreadyBlocked === false) { + // await addToBlockList(address, name) + // } + // executeEvent('updateChatMessagesWithBlocks', true) } catch (error) { console.error(error) } finally {