diff --git a/src/App.tsx b/src/App.tsx index d6033d4..3c8bc1a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -82,7 +82,7 @@ import { groupApiSocket, groupApiSocketLocal, } from "./background"; -import { executeEvent } from "./utils/events"; +import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "./utils/events"; import { requestQueueCommentCount, requestQueuePublishedAccouncements } from "./components/Chat/GroupAnnouncements"; import { requestQueueGroupJoinRequests } from "./components/Group/GroupJoinRequests"; import { DrawerComponent } from "./components/Drawer/Drawer"; @@ -293,7 +293,8 @@ function App() { const [confirmUseOfLocal, setConfirmUseOfLocal] = useState(false); const [isOpenDrawerProfile, setIsOpenDrawerProfile] = useState(false); const [apiKey, setApiKey] = useState(""); - + const [isOpenSendQort, setIsOpenSendQort] = useState(false) + const [isOpenSendQortSuccess, setIsOpenSendQortSuccess] = useState(false) useEffect(() => { if(!isMobile) return // Function to set the height of the app to the viewport height @@ -519,7 +520,9 @@ function App() { if (response?.error) { setSendPaymentError(response.error); } else { - setExtstate("transfer-success-regular"); + setIsOpenSendQort(false) + setIsOpenSendQortSuccess(true) + // setExtstate("transfer-success-regular"); // setSendPaymentSuccess("Payment successfully sent"); } setIsLoading(false); @@ -901,6 +904,8 @@ function App() { setWalletToBeDownloaded(null); setWalletToBeDownloadedPassword(""); setExtstate("authenticated"); + setIsOpenSendQort(false) + setIsOpenSendQortSuccess(false) }; const resetAllStates = () => { @@ -1026,6 +1031,17 @@ function App() { // Handler for when the window gains focus const handleFocus = () => { setIsFocused(true); + if(isMobile){ + chrome?.runtime?.sendMessage( + { + action: "clearAllNotifications", + payload: { + + }, + } + ); + } + console.log("Webview is focused"); }; @@ -1043,6 +1059,16 @@ function App() { const handleVisibilityChange = () => { if (document.visibilityState === "visible") { setIsFocused(true); + if(isMobile){ + chrome?.runtime?.sendMessage( + { + action: "clearAllNotifications", + payload: { + + }, + } + ); + } console.log("Webview is visible"); } else { setIsFocused(false); @@ -1060,6 +1086,22 @@ function App() { }; }, []); + + const openPaymentInternal = (e) => { + const directAddress = e.detail?.address; + const name = e.detail?.name + setIsOpenSendQort(true) + setPaymentTo(name || directAddress) + }; + + useEffect(() => { + subscribeToEvent("openPaymentInternal", openPaymentInternal); + + return () => { + unsubscribeFromEvent("openPaymentInternal", openPaymentInternal); + }; + }, []); + const registerName = async () => { try { if (!userInfo?.address) throw new Error("Your address was not found"); @@ -1262,7 +1304,8 @@ function App() { { - setExtstate("send-qort"); + setIsOpenSendQort(true) + // setExtstate("send-qort"); setIsOpenDrawerProfile(false) }} > @@ -1584,8 +1627,17 @@ function App() { )} - {extState === "send-qort" && isMainWindow && ( - <> + {isOpenSendQort && isMainWindow && ( + Send - + )} {extState === "web-app-request-buy-order" && !isMainWindow && ( <> @@ -2225,8 +2277,17 @@ function App() { )} )} - {extState === "transfer-success-regular" && ( - <> + {isOpenSendQortSuccess && ( + @@ -2246,7 +2307,7 @@ function App() { > Continue - + )} {extState === "transfer-success-request" && ( <> diff --git a/src/background.ts b/src/background.ts index 826dc8a..c6eb1a6 100644 --- a/src/background.ts +++ b/src/background.ts @@ -202,7 +202,7 @@ export function isExtMsg(data){ } catch (error) { isMsgFromExtensionGroup = false } -console.log('isMsgFromExtensionGroup', isMsgFromExtensionGroup) + return isMsgFromExtensionGroup } @@ -264,7 +264,7 @@ if (!oldestLatestTimestamp || oldChat?.timestamp > oldestLatestTimestamp?.timest } }); - console.log('newestLatestTimestamp', newestLatestTimestamp) + if(checkDifference(newestLatestTimestamp.timestamp) && !oldestLatestTimestamp || (newestLatestTimestamp && newestLatestTimestamp?.timestamp > oldestLatestTimestamp?.timestamp)){ const notificationId = 'chat_notification_' + Date.now() + '_type=direct' + `_from=${newestLatestTimestamp.address}`; chrome.notifications.create(notificationId, { @@ -460,7 +460,7 @@ const handleNotification = async (groups)=> { if(checkDifference(newestLatestTimestamp.timestamp) && !oldestLatestTimestamp || (newestLatestTimestamp && newestLatestTimestamp?.timestamp > oldestLatestTimestamp?.timestamp)){ if (!lastGroupNotification || ((Date.now() - lastGroupNotification) >= 120000)) { if(!newestLatestTimestamp?.data || !isExtMsg(newestLatestTimestamp?.data)) return - console.log('newestLatestTimestamp', newestLatestTimestamp) + const notificationId = 'chat_notification_' + Date.now() + '_type=group' + `_from=${newestLatestTimestamp.groupId}`; chrome.notifications.create(notificationId, { @@ -859,6 +859,13 @@ async function getSaveWallet() { } } +async function clearAllNotifications(){ + const notifications = await chrome.notifications.getAll(); + for (const notificationId of Object.keys(notifications)) { + await chrome.notifications.clear(notificationId); + } +} + async function getUserInfo() { const wallet = await getSaveWallet(); const address = wallet.address0; @@ -1502,7 +1509,7 @@ async function decryptDirectFunc({ messages, involvingAddress }) { publicKey: uint8PublicKey, }; for (const message of messages) { - console.log('messagedep', message) + try { const decodedMessage = decryptChatMessage( message.data, @@ -2905,6 +2912,18 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => { }); break; } + case "clearAllNotifications": { + + ; + clearAllNotifications() + .then((res) => { + + }) + .catch((error) => { + + }); + break; + } case "setGroupData": { const { groupId, diff --git a/src/components/Chat/AnnouncementDiscussion.tsx b/src/components/Chat/AnnouncementDiscussion.tsx index 792695a..9c3c1b8 100644 --- a/src/components/Chat/AnnouncementDiscussion.tsx +++ b/src/components/Chat/AnnouncementDiscussion.tsx @@ -283,6 +283,7 @@ export const AnnouncementDiscussion = ({ disableComment showLoadMore={comments.length > 0 && comments.length % 20 === 0} loadMore={loadMore} + myName={myName} />
+ {isFocusedParent && ( + { + if(isSending) return + setIsFocusedParent(false) + clearEditorContent() + // Unfocus the editor + }} + style={{ + marginTop: 'auto', + alignSelf: 'center', + cursor: isSending ? 'default' : 'pointer', + flexShrink: 0, + padding: isMobile && '5px', + fontSize: isMobile && '14px', + background: 'red', + }} + > + + {` Close`} + + + )} { if (isSending) return; @@ -361,29 +385,7 @@ export const AnnouncementDiscussion = ({ )} {` Publish Comment`} - {isFocusedParent && ( - { - if(isSending) return - setIsFocusedParent(false) - clearEditorContent() - // Unfocus the editor - }} - style={{ - marginTop: 'auto', - alignSelf: 'center', - cursor: isSending ? 'default' : 'pointer', - background: isSending && 'rgba(0, 0, 0, 0.8)', - flexShrink: 0, - padding: isMobile && '5px', - fontSize: isMobile && '14px', - }} - > - - {` Close`} - - - )} +
diff --git a/src/components/Chat/AnnouncementItem.tsx b/src/components/Chat/AnnouncementItem.tsx index e580d77..499ca9c 100644 --- a/src/components/Chat/AnnouncementItem.tsx +++ b/src/components/Chat/AnnouncementItem.tsx @@ -10,7 +10,8 @@ import { getBaseApi } from "../../background"; import { requestQueueCommentCount } from "./GroupAnnouncements"; import { CustomLoader } from "../../common/CustomLoader"; import { getBaseApiReact } from "../../App"; -export const AnnouncementItem = ({ message, messageData, setSelectedAnnouncement, disableComment }) => { +import { WrapperUserAction } from "../WrapperUserAction"; +export const AnnouncementItem = ({ message, messageData, setSelectedAnnouncement, disableComment, myName }) => { const [commentLength, setCommentLength] = useState(0) const getNumberOfComments = React.useCallback( @@ -63,6 +64,7 @@ export const AnnouncementItem = ({ message, messageData, setSelectedAnnouncement width: '100%', wordBreak: 'break-word' }}> + {message?.name?.charAt(0)} + + {message?.name} + {!messageData?.decryptedData && ( { const listRef = useRef(); @@ -63,7 +64,7 @@ export const AnnouncementList = ({ alignItems: "center", }} > - + ); diff --git a/src/components/Chat/ChatDirect.tsx b/src/components/Chat/ChatDirect.tsx index a0fd312..f975340 100644 --- a/src/components/Chat/ChatDirect.tsx +++ b/src/components/Chat/ChatDirect.tsx @@ -6,7 +6,7 @@ import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css"; import Tiptap from './TipTap' import { CustomButton } from '../../App-styles' import CircularProgress from '@mui/material/CircularProgress'; -import { Box, Input } from '@mui/material'; +import { Box, Input, Typography } from '@mui/material'; import { LoadingSnackbar } from '../Snackbar/LoadingSnackbar'; import { getNameInfo } from '../Group/Group'; import { Spacer } from '../../common/Spacer'; @@ -14,14 +14,13 @@ import { CustomizedSnackbars } from '../Snackbar/Snackbar'; import { getBaseApiReactSocket, isMobile, pauseAllQueues, resumeAllQueues } from '../../App'; import { getPublicKey } from '../../background'; import { useMessageQueue } from '../../MessageQueueContext'; -import { executeEvent } from '../../utils/events'; -import zIndex from '@mui/material/styles/zIndex'; +import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from '../../utils/events'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; - -export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDirect, setNewChat, getTimestampEnterChat, myName, balance}) => { +export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDirect, setNewChat, getTimestampEnterChat, myName, balance, close}) => { const { queueChats, addToQueue, } = useMessageQueue(); const [isFocusedParent, setIsFocusedParent] = useState(false); @@ -187,7 +186,16 @@ export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDi }; }; - + const setDirectChatValueFunc = async (e)=> { + setDirectToValue(e.detail.directToValue) + } + useEffect(() => { + subscribeToEvent("setDirectToValueNewChat", setDirectChatValueFunc); + + return () => { + unsubscribeFromEvent("setDirectToValueNewChat", setDirectChatValueFunc); + }; + }, []); useEffect(() => { if (hasInitializedWebsocket.current || isNewChat) return; @@ -327,6 +335,27 @@ console.log('isFocusedParent', isFocusedParent) flexDirection: 'column', width: '100%' }}> + + + Close Direct Chat + {isNewChat && ( <> @@ -375,6 +404,28 @@ console.log('isFocusedParent', isFocusedParent) flexShrink: 0, position: 'relative', }}> + {isFocusedParent && ( + { + if(isSending) return + setIsFocusedParent(false) + clearEditorContent() + // Unfocus the editor + }} + style={{ + marginTop: 'auto', + alignSelf: 'center', + cursor: isSending ? 'default' : 'pointer', + background: 'red', + flexShrink: 0, + padding: isMobile && '5px' + }} + > + + {` Close`} + + + )} { if(isSending) return @@ -404,28 +455,7 @@ console.log('isFocusedParent', isFocusedParent) )} {` Send`} - {isFocusedParent && ( - { - if(isSending) return - setIsFocusedParent(false) - clearEditorContent() - // Unfocus the editor - }} - style={{ - marginTop: 'auto', - alignSelf: 'center', - cursor: isSending ? 'default' : 'pointer', - background: isSending && 'rgba(0, 0, 0, 0.8)', - flexShrink: 0, - padding: isMobile && '5px' - }} - > - - {` Close`} - - )} { flexShrink: 0, position: 'relative', }}> + {isFocusedParent && ( + { + if(isSending) return + setIsFocusedParent(false) + clearEditorContent() + // Unfocus the editor + }} + style={{ + marginTop: 'auto', + alignSelf: 'center', + cursor: isSending ? 'default' : 'pointer', + background: 'red', + flexShrink: 0, + padding: isMobile && '5px' + }} + > + + {` Close`} + + + )} { if(isSending) return @@ -425,28 +447,7 @@ const clearEditorContent = () => { )} {` Send`} - {isFocusedParent && ( - { - if(isSending) return - setIsFocusedParent(false) - clearEditorContent() - // Unfocus the editor - }} - style={{ - marginTop: 'auto', - alignSelf: 'center', - cursor: isSending ? 'default' : 'pointer', - background: isSending && 'rgba(0, 0, 0, 0.8)', - flexShrink: 0, - padding: isMobile && '5px' - }} - > - - {` Close`} - - )} {/* */} diff --git a/src/components/Chat/ChatList.tsx b/src/components/Chat/ChatList.tsx index b4cae82..8c636c1 100644 --- a/src/components/Chat/ChatList.tsx +++ b/src/components/Chat/ChatList.tsx @@ -126,6 +126,7 @@ export const ChatList = ({ initialMessages, myAddress, tempMessages }) => { message={message} onSeen={handleMessageSeen} isTemp={!!message?.isTemp} + myAddress={myAddress} /> diff --git a/src/components/Chat/GroupAnnouncements.tsx b/src/components/Chat/GroupAnnouncements.tsx index 3b11931..15de64e 100644 --- a/src/components/Chat/GroupAnnouncements.tsx +++ b/src/components/Chat/GroupAnnouncements.tsx @@ -301,6 +301,7 @@ export const GroupAnnouncements = ({ } // send chat message } catch (error) { + if(!error) return setInfoSnack({ type: "error", message: error, @@ -542,6 +543,7 @@ export const GroupAnnouncements = ({ disableComment={false} showLoadMore={announcements.length > 0 && announcements.length % 20 === 0} loadMore={loadMore} + myName={myName} /> @@ -591,6 +593,29 @@ export const GroupAnnouncements = ({ flexShrink: 0, position: 'relative', }}> + {isFocusedParent && ( + { + if(isSending) return + setIsFocusedParent(false) + clearEditorContent() + // Unfocus the editor + }} + style={{ + marginTop: 'auto', + alignSelf: 'center', + cursor: isSending ? 'default' : 'pointer', + background: 'red', + flexShrink: 0, + padding: isMobile && '5px', + fontSize: isMobile && '14px', + }} + > + + {` Close`} + + + )} { if (isSending) return; @@ -622,29 +647,7 @@ export const GroupAnnouncements = ({ )} {` Publish Announcement`} - {isFocusedParent && ( - { - if(isSending) return - setIsFocusedParent(false) - clearEditorContent() - // Unfocus the editor - }} - style={{ - marginTop: 'auto', - alignSelf: 'center', - cursor: isSending ? 'default' : 'pointer', - background: isSending && 'rgba(0, 0, 0, 0.8)', - flexShrink: 0, - padding: isMobile && '5px', - fontSize: isMobile && '14px', - }} - > - - {` Close`} - - - )} + )} diff --git a/src/components/Chat/MessageItem.tsx b/src/components/Chat/MessageItem.tsx index d940d69..b3ac3d9 100644 --- a/src/components/Chat/MessageItem.tsx +++ b/src/components/Chat/MessageItem.tsx @@ -10,7 +10,9 @@ import { generateHTML } from "@tiptap/react"; import Highlight from '@tiptap/extension-highlight' import StarterKit from '@tiptap/starter-kit' import Underline from '@tiptap/extension-underline' -export const MessageItem = ({ message, onSeen, isLast, isTemp }) => { +import { executeEvent } from "../../utils/events"; +import { WrapperUserAction } from "../WrapperUserAction"; +export const MessageItem = ({ message, onSeen, isLast, isTemp, myAddress }) => { const { ref, inView } = useInView({ threshold: 0.7, // Fully visible @@ -36,6 +38,7 @@ export const MessageItem = ({ message, onSeen, isLast, isTemp }) => { opacity: isTemp ? 0.5 : 1 }} > + { > {message?.senderName?.charAt(0)} + { width: '100%' }} > + {message?.senderName || message?.sender} + {message?.messageText && ( )} diff --git a/src/components/Group/Forum/GroupMail.tsx b/src/components/Group/Forum/GroupMail.tsx index d1ce85b..3d9d82b 100644 --- a/src/components/Group/Forum/GroupMail.tsx +++ b/src/components/Group/Forum/GroupMail.tsx @@ -54,6 +54,7 @@ import { LoadingSnackbar } from "../../Snackbar/LoadingSnackbar"; import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../../utils/events"; import RefreshIcon from '@mui/icons-material/Refresh'; import { getBaseApiReact } from "../../../App"; +import { WrapperUserAction } from "../../WrapperUserAction"; const filterOptions = ["Recently active", "Newest", "Oldest"]; export const threadIdentifier = "DOCUMENT"; @@ -672,6 +673,7 @@ export const GroupMail = ({ } }} > + {thread?.threadData?.name?.charAt(0)} + + by {thread?.threadData?.name} + {formatTimestamp(thread?.threadData?.createdAt)} diff --git a/src/components/Group/Forum/ShowMessageWithoutModal.tsx b/src/components/Group/Forum/ShowMessageWithoutModal.tsx index c8fb5cb..9a079d6 100644 --- a/src/components/Group/Forum/ShowMessageWithoutModal.tsx +++ b/src/components/Group/Forum/ShowMessageWithoutModal.tsx @@ -19,8 +19,9 @@ import ReadOnlySlate from "./ReadOnlySlate"; import { MessageDisplay } from "../../Chat/MessageDisplay"; import { getBaseApi } from "../../../background"; import { getBaseApiReact } from "../../../App"; +import { WrapperUserAction } from "../../WrapperUserAction"; -export const ShowMessage = ({ message, openNewPostWithQuote }: any) => { +export const ShowMessage = ({ message, openNewPostWithQuote, myName }: any) => { const [expandAttachments, setExpandAttachments] = useState(false); let cleanHTML = ""; @@ -53,13 +54,17 @@ export const ShowMessage = ({ message, openNewPostWithQuote }: any) => { }} > - + {message?.name?.charAt(0)} + + + {message?.name} + {formatTimestampForum(message?.created)} diff --git a/src/components/Group/Forum/Thread.tsx b/src/components/Group/Forum/Thread.tsx index 6dd0dbb..c386da0 100644 --- a/src/components/Group/Forum/Thread.tsx +++ b/src/components/Group/Forum/Thread.tsx @@ -531,6 +531,7 @@ export const Thread = ({ key={message?.identifier} message={fullMessage} openNewPostWithQuote={openNewPostWithQuote} + myName={userInfo?.name} /> ); } else if(message?.tempData){ @@ -539,6 +540,7 @@ export const Thread = ({ key={message?.identifier} message={message?.tempData} openNewPostWithQuote={openNewPostWithQuote} + myName={userInfo?.name} /> ); } diff --git a/src/components/Group/Group.tsx b/src/components/Group/Group.tsx index 642119d..160367f 100644 --- a/src/components/Group/Group.tsx +++ b/src/components/Group/Group.tsx @@ -30,9 +30,9 @@ import MarkUnreadChatAltIcon from "@mui/icons-material/MarkUnreadChatAlt"; import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline"; import CreateIcon from "@mui/icons-material/Create"; import RefreshIcon from "@mui/icons-material/Refresh"; -import AnnouncementsIcon from '@mui/icons-material/Notifications'; -import GroupIcon from '@mui/icons-material/Group'; -import PersonIcon from '@mui/icons-material/Person'; +import AnnouncementsIcon from "@mui/icons-material/Notifications"; +import GroupIcon from "@mui/icons-material/Group"; +import PersonIcon from "@mui/icons-material/Person"; import { AuthenticatedContainerInnerRight, CustomButton, @@ -56,7 +56,7 @@ import { LoadingButton } from "@mui/lab"; import { LoadingSnackbar } from "../Snackbar/LoadingSnackbar"; import { GroupAnnouncements } from "../Chat/GroupAnnouncements"; import HomeIcon from "@mui/icons-material/Home"; -import CloseIcon from '@mui/icons-material/Close'; +import CloseIcon from "@mui/icons-material/Close"; import { ThingsToDoInitial } from "./ThingsToDoInitial"; import { GroupJoinRequests } from "./GroupJoinRequests"; @@ -96,7 +96,6 @@ import { isExtMsg } from "../../background"; // } // }); - interface GroupProps { myAddress: string; isFocused: boolean; @@ -223,8 +222,8 @@ export const getGroupAdimns = async (groupNumber: number) => { ); const groupData = await response.json(); let members: any = []; - let membersAddresses = [] - let both = [] + let membersAddresses = []; + let both = []; // if (groupData && Array.isArray(groupData?.members)) { // for (const member of groupData.members) { // if (member.member) { @@ -243,16 +242,16 @@ export const getGroupAdimns = async (groupNumber: number) => { }); if (name) { members.push(name); - both.push({name, address: member.member}) + both.push({ name, address: member.member }); } - membersAddresses.push(member.member) + membersAddresses.push(member.member); } return true; }); await Promise.all(getMemNames); - return {names: members, addresses: membersAddresses, both}; + return { names: members, addresses: membersAddresses, both }; }; export const getNames = async (listOfMembers) => { @@ -314,7 +313,8 @@ export const Group = ({ isMain, userInfo, balance, - isOpenDrawerProfile, setIsOpenDrawerProfile + isOpenDrawerProfile, + setIsOpenDrawerProfile, }: GroupProps) => { const [secretKey, setSecretKey] = useState(null); const [secretKeyPublishDate, setSecretKeyPublishDate] = useState(null); @@ -355,7 +355,7 @@ export const Group = ({ const [defaultThread, setDefaultThread] = React.useState(null); const [isOpenDrawer, setIsOpenDrawer] = React.useState(false); - const [drawerMode, setDrawerMode] = React.useState('groups'); + const [drawerMode, setDrawerMode] = React.useState("groups"); const isFocusedRef = useRef(true); const selectedGroupRef = useRef(null); const selectedDirectRef = useRef(null); @@ -410,21 +410,20 @@ export const Group = ({ { action: "getGroupDataSingle", payload: { - groupId - } + groupId, + }, }, (response) => { if (!response?.error) { - res(response); - return + return; } rej(response.error); } ); }); } catch (error) { - return {} + return {}; } }; const refreshHomeDataFunc = () => { @@ -526,11 +525,12 @@ export const Group = ({ let hasUnread = false; groups.forEach((group) => { if ( - group?.data && isExtMsg(group?.data) && group?.sender !== myAddress && + group?.data && + isExtMsg(group?.data) && + group?.sender !== myAddress && group?.timestamp && ((!timestampEnterData[group?.groupId] && - Date.now() - group?.timestamp < - timeDifferenceForNotificationChats) || + Date.now() - group?.timestamp < timeDifferenceForNotificationChats) || timestampEnterData[group?.groupId] < group?.timestamp) ) { hasUnread = true; @@ -544,7 +544,7 @@ export const Group = ({ groups.forEach((group) => { if ( groupAnnouncements[group?.groupId] && - !groupAnnouncements[group?.groupId]?.seentimestamp + !groupAnnouncements[group?.groupId]?.seentimestamp ) { hasUnread = true; } @@ -599,15 +599,17 @@ export const Group = ({ try { // setGroupDataLastSet(null) pauseAllQueues(); - let dataFromStorage - let publishFromStorage - let adminsFromStorage - const groupData = await getGroupDataSingle(selectedGroup?.groupId) - if(groupData?.secretKeyData && Date.now() - groupData?.timestampLastSet < 3600000 ){ - - dataFromStorage = groupData.secretKeyData - publishFromStorage = groupData.secretKeyResource - adminsFromStorage = groupData.admins + let dataFromStorage; + let publishFromStorage; + let adminsFromStorage; + const groupData = await getGroupDataSingle(selectedGroup?.groupId); + if ( + groupData?.secretKeyData && + Date.now() - groupData?.timestampLastSet < 3600000 + ) { + dataFromStorage = groupData.secretKeyData; + publishFromStorage = groupData.secretKeyResource; + adminsFromStorage = groupData.admins; // setGroupDataLastSet(groupData.timestampLastSet) } @@ -629,13 +631,15 @@ export const Group = ({ } const prevGroupId = selectedGroupRef.current.groupId; // const validApi = await findUsableApi(); - const {names, addresses, both} = adminsFromStorage || await getGroupAdimns(selectedGroup?.groupId); + const { names, addresses, both } = + adminsFromStorage || (await getGroupAdimns(selectedGroup?.groupId)); setAdmins(addresses); - setAdminsWithNames(both) + setAdminsWithNames(both); if (!names.length) { throw new Error("Network error"); } - const publish = publishFromStorage || await getPublishesFromAdmins(names); + const publish = + publishFromStorage || (await getPublishesFromAdmins(names)); if (prevGroupId !== selectedGroupRef.current.groupId) { if (settimeoutForRefetchSecretKey.current) { @@ -651,18 +655,17 @@ export const Group = ({ return false; } setSecretKeyPublishDate(publish?.updated || publish?.created); - let data - if(dataFromStorage){ - data = dataFromStorage + let data; + if (dataFromStorage) { + data = dataFromStorage; } else { const res = await fetch( `${getBaseApiReact()}/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${ publish.identifier }?encoding=base64` ); - data = await res.text(); + data = await res.text(); } - const decryptedKey: any = await decryptResource(data); @@ -675,17 +678,15 @@ export const Group = ({ setSecretKey(decryptedKeyToObject); lastFetchedSecretKey.current = Date.now(); setMemberCountFromSecretKeyData(decryptedKey.count); - chrome?.runtime?.sendMessage( - { - action: "setGroupData", - payload: { - groupId: selectedGroup?.groupId, - secretKeyData: data, - secretKeyResource: publish, - admins: {names, addresses, both} - }, - } - ); + chrome?.runtime?.sendMessage({ + action: "setGroupData", + payload: { + groupId: selectedGroup?.groupId, + secretKeyData: data, + secretKeyResource: publish, + admins: { names, addresses, both }, + }, + }); if (decryptedKeyToObject) { setTriedToFetchSecretKey(true); setFirstSecretKeyInCreation(false); @@ -915,12 +916,16 @@ export const Group = ({ } catch (error) {} }; useEffect(() => { - if (!initiatedGetMembers.current && selectedGroup?.groupId && secretKey && admins.includes(myAddress)) { - - console.log('goung through', admins) + if ( + !initiatedGetMembers.current && + selectedGroup?.groupId && + secretKey && + admins.includes(myAddress) + ) { + console.log("goung through", admins); // getAdmins(selectedGroup?.groupId); getMembers(selectedGroup?.groupId); - initiatedGetMembers.current = true + initiatedGetMembers.current = true; } }, [selectedGroup?.groupId, secretKey, myAddress, admins]); @@ -998,7 +1003,7 @@ export const Group = ({ .filter((group) => group?.sender !== myAddress) .find((gr) => gr?.groupId === selectedGroup?.groupId); if (!findGroup) return false; - if(!findGroup?.data || !isExtMsg(findGroup?.data)) return false + if (!findGroup?.data || !isExtMsg(findGroup?.data)) return false; return ( findGroup?.timestamp && ((!timestampEnterData[selectedGroup?.groupId] && @@ -1030,7 +1035,7 @@ export const Group = ({ if (findDirect) { setChatMode("directs"); setSelectedDirect(null); - setSelectedGroup(null); + // setSelectedGroup(null); setNewChat(false); @@ -1052,6 +1057,52 @@ export const Group = ({ } }; + const openDirectChatFromInternal = (e) => { + const directAddress = e.detail?.address; + const name = e.detail?.name + const findDirect = directs?.find( + (direct) => direct?.address === directAddress || direct?.name === name + ); + + if (findDirect) { + setChatMode("directs"); + setSelectedDirect(null); + // setSelectedGroup(null); + + setNewChat(false); + + chrome?.runtime?.sendMessage({ + action: "addTimestampEnterChat", + payload: { + timestamp: Date.now(), + groupId: findDirect.address, + }, + }); + + setTimeout(() => { + setSelectedDirect(findDirect); + getTimestampEnterChat(); + }, 200); + + } else { + setChatMode('directs') + setNewChat(true); + setTimeout(() => { + executeEvent("setDirectToValueNewChat", { + directToValue: name || directAddress + }); + }, 500); + } + }; + + useEffect(() => { + subscribeToEvent("openDirectMessageInternal", openDirectChatFromInternal); + + return () => { + unsubscribeFromEvent("openDirectMessageInternal", openDirectChatFromInternal); + }; + }, [directs, selectedDirect]); + useEffect(() => { subscribeToEvent("openDirectMessage", openDirectChatFromNotification); @@ -1106,7 +1157,7 @@ export const Group = ({ isLoadingOpenSectionFromNotification.current = false; setupGroupWebsocketInterval.current = null; settimeoutForRefetchSecretKey.current = null; - initiatedGetMembers.current = false + initiatedGetMembers.current = false; }; const logoutEventFunc = () => { @@ -1275,51 +1326,51 @@ export const Group = ({ setFirstSecretKeyInCreation(true); }; - const goToHome = async ()=> { + const goToHome = async () => { setGroupSection("default"); - clearAllQueues(); - await new Promise((res) => { - setTimeout(() => { - res(null); - }, 200); - }); - setGroupSection("home"); - setSelectedGroup(null); - setNewChat(false); - setSelectedDirect(null); - setSecretKey(null); - lastFetchedSecretKey.current = null; - setSecretKeyPublishDate(null); - setAdmins([]); - setSecretKeyDetails(null); - setAdminsWithNames([]); - setMembers([]); - setMemberCountFromSecretKeyData(null); - setTriedToFetchSecretKey(false); - setFirstSecretKeyInCreation(false); - } + clearAllQueues(); + await new Promise((res) => { + setTimeout(() => { + res(null); + }, 200); + }); + setGroupSection("home"); + setSelectedGroup(null); + setNewChat(false); + setSelectedDirect(null); + setSecretKey(null); + lastFetchedSecretKey.current = null; + setSecretKeyPublishDate(null); + setAdmins([]); + setSecretKeyDetails(null); + setAdminsWithNames([]); + setMembers([]); + setMemberCountFromSecretKeyData(null); + setTriedToFetchSecretKey(false); + setFirstSecretKeyInCreation(false); + }; - const goToAnnouncements = async ()=> { + const goToAnnouncements = async () => { setGroupSection("default"); - await new Promise((res) => { - setTimeout(() => { - res(null); - }, 200); - }); - setGroupSection("announcement"); - chrome?.runtime?.sendMessage({ - action: "addGroupNotificationTimestamp", - payload: { - timestamp: Date.now(), - groupId: selectedGroupRef.current.groupId, - }, - }); - setTimeout(() => { - getGroupAnnouncements(); - }, 200); - } + await new Promise((res) => { + setTimeout(() => { + res(null); + }, 200); + }); + setGroupSection("announcement"); + chrome?.runtime?.sendMessage({ + action: "addGroupNotificationTimestamp", + payload: { + timestamp: Date.now(), + groupId: selectedGroupRef.current.groupId, + }, + }); + setTimeout(() => { + getGroupAnnouncements(); + }, 200); + }; - const goToChat = async ()=> { + const goToChat = async () => { setGroupSection("default"); await new Promise((res) => { setTimeout(() => { @@ -1340,222 +1391,228 @@ export const Group = ({ getTimestampEnterChat(); }, 200); } - } + }; - const renderGroups = ()=> { + const renderGroups = () => { return ( -
-
- {isMobile && ( - { - setIsOpenDrawer(false) - }} sx={{ - cursor: 'pointer', - color: 'white' - }} /> - )} - { - setChatMode((prev) => - prev === "directs" ? "groups" : "directs" - ); - setNewChat(false); - setSelectedDirect(null); - setSelectedGroup(null); - setGroupSection("default"); - }} - > - {chatMode === "groups" && ( - <> - - - )} - {chatMode === "directs" ? "Switch to groups" : "Direct msgs"} - -
- {directs.map((direct: any) => ( - - - // - // - // } - onClick={() => { - setSelectedDirect(null); - setNewChat(false); - setSelectedGroup(null); - setIsOpenDrawer(false) - chrome?.runtime?.sendMessage({ - action: "addTimestampEnterChat", - payload: { - timestamp: Date.now(), - groupId: direct.address, - }, - }); - setTimeout(() => { - setSelectedDirect(direct); - - getTimestampEnterChat(); - }, 200); - }} +
+ {isMobile && ( + - { + setIsOpenDrawer(false); + }} + sx={{ + cursor: "pointer", + color: "white", + }} + /> + + )} + { + setChatMode((prev) => + prev === "directs" ? "groups" : "directs" + ); + // setNewChat(false); + // setSelectedDirect(null); + // setSelectedGroup(null); + // setGroupSection("default"); + }} + > + {chatMode === "groups" && ( + <> + + + )} + {chatMode === "directs" ? "Switch to groups" : "Direct msgs"} + +
+
+ {directs.map((direct: any) => ( + + + // + // + // } + onClick={() => { + setSelectedDirect(null); + setNewChat(false); + // setSelectedGroup(null); + setIsOpenDrawer(false); + chrome?.runtime?.sendMessage({ + action: "addTimestampEnterChat", + payload: { + timestamp: Date.now(), + groupId: direct.address, + }, + }); + setTimeout(() => { + setSelectedDirect(direct); + + getTimestampEnterChat(); + }, 200); + }} sx={{ display: "flex", width: "100%", + flexDirection: "column", + cursor: "pointer", + border: "1px #232428 solid", + padding: "2px", + borderRadius: "2px", + background: + direct?.address === selectedDirect?.address && "white", }} > - - - {(direct?.name || direct?.address)?.charAt(0)} - - - - {direct?.sender !== myAddress && - direct?.timestamp && - ((!timestampEnterData[direct?.address] && - Date.now() - direct?.timestamp < - timeDifferenceForNotificationChats) || - timestampEnterData[direct?.address] < - direct?.timestamp) && ( - + + - )} - - - - ))} -
-
- {groups.map((group: any) => ( - - - // - // - // } - onClick={() => { - clearAllQueues(); - setSelectedDirect(null); + alt={direct?.name || direct?.address} + // src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${groupOwner?.name}/qortal_group_avatar_${group.groupId}?async=true`} + > + {(direct?.name || direct?.address)?.charAt(0)} + + + + {direct?.sender !== myAddress && + direct?.timestamp && + ((!timestampEnterData[direct?.address] && + Date.now() - direct?.timestamp < + timeDifferenceForNotificationChats) || + timestampEnterData[direct?.address] < + direct?.timestamp) && ( + + )} + + + + ))} +
+
+ {groups.map((group: any) => ( + + + // + // + // } + onClick={() => { + clearAllQueues(); + setSelectedDirect(null); - setNewChat(false); - setSelectedGroup(null); - setSecretKey(null); - lastFetchedSecretKey.current = null; - setSecretKeyPublishDate(null); - setAdmins([]); - setSecretKeyDetails(null); - setAdminsWithNames([]); - setMembers([]); - setMemberCountFromSecretKeyData(null); - setTriedToFetchSecretKey(false); - setFirstSecretKeyInCreation(false); - // setGroupSection("announcement"); - setGroupSection("chat"); - setIsOpenDrawer(false) - setTimeout(() => { - setSelectedGroup(group); + setNewChat(false); + setSelectedGroup(null); + setSecretKey(null); + lastFetchedSecretKey.current = null; + setSecretKeyPublishDate(null); + setAdmins([]); + setSecretKeyDetails(null); + setAdminsWithNames([]); + setMembers([]); + setMemberCountFromSecretKeyData(null); + setTriedToFetchSecretKey(false); + setFirstSecretKeyInCreation(false); + // setGroupSection("announcement"); + setGroupSection("chat"); + setIsOpenDrawer(false); + setTimeout(() => { + setSelectedGroup(group); - // getTimestampEnterChat(); - }, 200); + // getTimestampEnterChat(); + }, 200); - chrome?.runtime?.sendMessage({ action: "addTimestampEnterChat", payload: { @@ -1563,148 +1620,147 @@ export const Group = ({ groupId: group.groupId, }, }); - + setTimeout(() => { getTimestampEnterChat(); }, 200); - - // if (groupSectionRef.current === "announcement") { - // chrome?.runtime?.sendMessage({ - // action: "addGroupNotificationTimestamp", - // payload: { - // timestamp: Date.now(), - // groupId: group.groupId, - // }, - // }); - // } + // if (groupSectionRef.current === "announcement") { + // chrome?.runtime?.sendMessage({ + // action: "addGroupNotificationTimestamp", + // payload: { + // timestamp: Date.now(), + // groupId: group.groupId, + // }, + // }); + // } - // setTimeout(() => { - // getGroupAnnouncements(); - // }, 600); - }} - sx={{ - display: "flex", - width: "100%", - flexDirection: "column", - cursor: "pointer", - border: "1px #232428 solid", - padding: "2px", - borderRadius: "2px", - background: - group?.groupId === selectedGroup?.groupId && "white", - }} - > - { + // getGroupAnnouncements(); + // }, 600); + }} sx={{ display: "flex", width: "100%", + flexDirection: "column", + cursor: "pointer", + border: "1px #232428 solid", + padding: "2px", + borderRadius: "2px", + background: + group?.groupId === selectedGroup?.groupId && "white", }} > - - - {group.groupName?.charAt(0)} - - - - {groupAnnouncements[group?.groupId] && - !groupAnnouncements[group?.groupId]?.seentimestamp && ( - + + - )} - {group?.data && isExtMsg(group?.data) && group?.sender !== myAddress && - group?.timestamp && - ((!timestampEnterData[group?.groupId] && - Date.now() - group?.timestamp < - timeDifferenceForNotificationChats) || - timestampEnterData[group?.groupId] < - group?.timestamp) && ( - - )} - - - - ))} -
-
- {chatMode === "groups" && ( - { - setOpenAddGroup(true); - }} - > - + {group.groupName?.charAt(0)} + + + + {groupAnnouncements[group?.groupId] && + !groupAnnouncements[group?.groupId]?.seentimestamp && ( + + )} + {group?.data && + isExtMsg(group?.data) && + group?.sender !== myAddress && + group?.timestamp && + ((!timestampEnterData[group?.groupId] && + Date.now() - group?.timestamp < + timeDifferenceForNotificationChats) || + timestampEnterData[group?.groupId] < + group?.timestamp) && ( + + )} + + + + ))} +
+
+ {chatMode === "groups" && ( + { + setOpenAddGroup(true); }} - /> - Add Group - - )} - {chatMode === "directs" && ( - { - setNewChat(true); - setSelectedDirect(null); - setSelectedGroup(null); - setIsOpenDrawer(false) - }} - > - + + Add Group + + )} + {chatMode === "directs" && ( + { + setNewChat(true); + setSelectedDirect(null); + // setSelectedGroup(null); + setIsOpenDrawer(false); }} - /> - New Chat - - )} + > + + New Chat + + )} +
-
- ) - } + ); + }; return ( <> @@ -1723,12 +1779,17 @@ export const Group = ({ style={{ display: "flex", width: "100%", - height: isMobile ? "calc(100% - 75px)" : "100%", + height: isMobile ? "calc(100% - 75px)" : "100%", flexDirection: "row", alignItems: "flex-start", }} > - {!isMobile && renderGroups()} + {!isMobile && renderGroups()} + {newChat && ( <> + { + setSelectedDirect(null); + + setNewChat(false); + }} /> + )} - {selectedGroup && !newChat && ( + {selectedGroup && ( <> + + + + + { + setSelectedDirect(null); + + setNewChat(false); + }} /> + )} - {!selectedDirect && + { !selectedGroup && - !newChat && groupSection === "home" && ( - {!isLoadingGroups && ( - - - - - - - )} - + {!isLoadingGroups && ( + + + + + + + + )} )} + @@ -2209,124 +2309,225 @@ export const Group = ({ message: "Setting up groups... please wait.", }} /> + - {renderGroups()} - - - - {isMobile && ( - - - {selectedGroup && ( - <> - - - - - - - - - - - - - - )} + + {renderGroups()} + - {/* Second row: Groups, Home, Profile */} - - - - - - - - - - setIsOpenDrawerProfile(true)} - > - - - - - - -)} - + + {selectedGroup && ( + <> + + + + + + + + + + + + + + )} + {/* Second row: Groups, Home, Profile */} + + + + + + + + + + setIsOpenDrawerProfile(true)} + > + + + + + + )} ); }; diff --git a/src/components/Loader.tsx b/src/components/Loader.tsx index fe0a05e..8db908e 100644 --- a/src/components/Loader.tsx +++ b/src/components/Loader.tsx @@ -14,7 +14,7 @@ export const Loader = () => { left:'0px', right: '0px', bottom: '0px', - zIndex: 2, + zIndex: 10, background: 'rgba(0, 0, 0, 0.4)' }}> diff --git a/src/components/WrapperUserAction.tsx b/src/components/WrapperUserAction.tsx new file mode 100644 index 0000000..cfdb82f --- /dev/null +++ b/src/components/WrapperUserAction.tsx @@ -0,0 +1,108 @@ +import React, { useState } from 'react'; +import { Popover, Button, Box } from '@mui/material'; +import { executeEvent } from '../utils/events'; + +export const WrapperUserAction = ({ children, address, name, disabled }) => { + const [anchorEl, setAnchorEl] = useState(null); + + // Handle child element click to open Popover + const handleChildClick = (event) => { + event.stopPropagation(); // Prevent parent onClick from firing + setAnchorEl(event.currentTarget); + }; + + // Handle closing the Popover + const handleClose = () => { + setAnchorEl(null); + }; + + // Determine if the popover is open + const open = Boolean(anchorEl); + const id = open ? address || name : undefined; + + if(disabled){ + return children + } + + return ( + <> + + {/* Render the child without altering dimensions */} + {children} + + + {/* Popover */} + event.stopPropagation(), // Stop propagation inside popover + }, + }} + > + + {/* Option 1: Message */} + + + {/* Option 2: Send QORT */} + + + + + ); +}; diff --git a/src/index.css b/src/index.css index 543bec2..956f995 100644 --- a/src/index.css +++ b/src/index.css @@ -78,6 +78,19 @@ body { border: 4px solid transparent; } +/* Mobile-specific scrollbar styles */ +@media only screen and (max-width: 600px) { + ::-webkit-scrollbar { + width: 8px; /* Narrower scrollbar width on mobile */ + height: 6px; /* Narrower scrollbar height on mobile */ + } + + ::-webkit-scrollbar-thumb { + border-radius: 4px; /* Adjust the radius for a narrower thumb */ + border: 2px solid transparent; /* Narrower thumb border */ + } +} + .group-list::-webkit-scrollbar-thumb:hover { background-color: whitesmoke; }