diff --git a/src/App.tsx b/src/App.tsx index 7106971..f3602e2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -134,6 +134,7 @@ import { useFetchResources } from "./common/useFetchResources"; import { Tutorials } from "./components/Tutorials/Tutorials"; import { useHandleTutorials } from "./components/Tutorials/useHandleTutorials"; import BoundedNumericTextField from "./common/BoundedNumericTextField"; +import { useHandleUserInfo } from "./components/Group/useHandleUserInfo"; type extStates = | "not-authenticated" @@ -396,7 +397,7 @@ function App() { const [isSettingsOpen, setIsSettingsOpen] = useState(false); const [showSeed, setShowSeed] = useState(false) const [creationStep, setCreationStep] = useState(1) - + const {getIndividualUserInfo} = useHandleUserInfo() const qortalRequestCheckbox1Ref = useRef(null); useRetrieveDataLocalStorage(); useQortalGetSaveSettings(userInfo?.name, extState === "authenticated"); @@ -1661,7 +1662,7 @@ function App() { infoSnackCustom: infoSnack, setInfoSnackCustom: setInfoSnack, downloadResource, - + getIndividualUserInfo }} > ({ get }) => { + const userInfo = get(addressInfoControllerAtom); + return userInfo[key] || null; // Return the value for the key or null if not found + }, }); \ No newline at end of file diff --git a/src/components/Chat/MessageItem.tsx b/src/components/Chat/MessageItem.tsx index cd9d605..e325840 100644 --- a/src/components/Chat/MessageItem.tsx +++ b/src/components/Chat/MessageItem.tsx @@ -1,11 +1,11 @@ import { Message } from "@chatscope/chat-ui-kit-react"; -import React, { useEffect, useState } from "react"; +import React, { useContext, useEffect, useState } from "react"; import { useInView } from "react-intersection-observer"; import { MessageDisplay } from "./MessageDisplay"; -import { Avatar, Box, Button, ButtonBase, List, ListItem, ListItemText, Popover, Typography } from "@mui/material"; +import { Avatar, Box, Button, ButtonBase, List, ListItem, ListItemText, Popover, Tooltip, Typography } from "@mui/material"; import { formatTimestamp } from "../../utils/time"; import { getBaseApi } from "../../background"; -import { getBaseApiReact } from "../../App"; +import { MyContext, getBaseApiReact } from "../../App"; import { generateHTML } from "@tiptap/react"; import Highlight from "@tiptap/extension-highlight"; import Mention from "@tiptap/extension-mention"; @@ -19,6 +19,37 @@ import { ReactionPicker } from "../ReactionPicker"; import KeyOffIcon from '@mui/icons-material/KeyOff'; import EditIcon from '@mui/icons-material/Edit'; import TextStyle from '@tiptap/extension-text-style'; +import { addressInfoKeySelector } from "../../atoms/global"; +import { useRecoilValue } from "recoil"; +import level0Img from "../../assets/badges/level-0.png" +import level1Img from "../../assets/badges/level-1.png" +import level2Img from "../../assets/badges/level-2.png" +import level3Img from "../../assets/badges/level-3.png" +import level4Img from "../../assets/badges/level-4.png" +import level5Img from "../../assets/badges/level-5.png" +import level6Img from "../../assets/badges/level-6.png" +import level7Img from "../../assets/badges/level-7.png" +import level8Img from "../../assets/badges/level-8.png" +import level9Img from "../../assets/badges/level-9.png" +import level10Img from "../../assets/badges/level-10.png" + +const getBadgeImg = (level)=> { + switch(level?.toString()){ + + case '0': return level0Img + case '1': return level1Img + case '2': return level2Img + case '3': return level3Img + case '4': return level4Img + case '5': return level5Img + case '6': return level6Img + case '7': return level7Img + case '8': return level8Img + case '9': return level9Img + case '10': return level10Img + default: return level0Img + } +} export const MessageItem = ({ message, onSeen, @@ -41,11 +72,10 @@ export const MessageItem = ({ threshold: 0.7, // Fully visible triggerOnce: false, // Only trigger once when it becomes visible }); - - +const {getIndividualUserInfo} = useContext(MyContext) const [anchorEl, setAnchorEl] = useState(null); const [selectedReaction, setSelectedReaction] = useState(null); - + const userInfo = useRecoilValue(addressInfoKeySelector(message?.sender)); useEffect(() => { if (inView && isLast && onSeen) { @@ -53,7 +83,11 @@ export const MessageItem = ({ } }, [inView, message.id, isLast]); - +useEffect(()=> { + if(message?.sender){ + getIndividualUserInfo(message?.sender) + } +}, [message?.sender]) return ( <> @@ -82,11 +116,18 @@ export const MessageItem = ({ }} /> ) : ( + + {message?.senderName?.charAt(0)} + + + + + + + + )} { if(!selectedGroup?.groupId || !groupsProperties[selectedGroup?.groupId]) return null @@ -1834,6 +1835,7 @@ export const Group = ({ setTriedToFetchSecretKey(false); setNewChat(false); setSelectedGroup(null); + setUserInfoForLevels({}) setSecretKey(null); lastFetchedSecretKey.current = null; setSecretKeyPublishDate(null); diff --git a/src/components/Group/useHandleUserInfo.tsx b/src/components/Group/useHandleUserInfo.tsx new file mode 100644 index 0000000..db6993a --- /dev/null +++ b/src/components/Group/useHandleUserInfo.tsx @@ -0,0 +1,36 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { getBaseApiReact } from "../../App"; +import { useRecoilState, useSetRecoilState } from "recoil"; +import { addressInfoControllerAtom } from "../../atoms/global"; + + + +export const useHandleUserInfo = () => { + const [userInfo, setUserInfo] = useRecoilState(addressInfoControllerAtom); + + + + const getIndividualUserInfo = useCallback(async (address)=> { + try { + if(!address || userInfo[address]) return + const url = `${getBaseApiReact()}/addresses/${address}`; + const response = await fetch(url); + if (!response.ok) { + throw new Error("network error"); + } + const data = await response.json(); + setUserInfo((prev)=> { + return { + ...prev, + [address]: data + } + }) + } catch (error) { + //error + } + }, [userInfo]) + + return { + getIndividualUserInfo, + }; +};