update contacts details and styles
Change-Id: I280637469804462531d82e48447cd9fe6a082e46
diff --git a/JamiDaemon.js b/JamiDaemon.js
index bf4ed7d..812574d 100755
--- a/JamiDaemon.js
+++ b/JamiDaemon.js
@@ -258,11 +258,12 @@
JamiDaemon.vectToJs(this.dring.getConversations(accountId)).forEach(conversationId => {
const members = JamiDaemon.vectMapToJs(this.dring.getConversationMembers(accountId, conversationId))
+ console.log("\n\nXMEMBERS: ", members)
members.forEach(member => {
member.contact = account.getContactFromCache(member.uri)
if (!member.contact.isRegisteredNameResolved()) {
if (!member.uri) return
- console.log(`lookupAddress ${accountId} ${member.uri}`)
+ console.log(`lookupAddress ${accountId} ${member.uri}`, member)
member.contact.setRegisteredName(new Promise((resolve, reject) =>
account.lookups.push({address: member.uri, resolve, reject})
).then(result => {
@@ -277,6 +278,7 @@
}
})
const conversation = new Conversation(conversationId, accountId, members)
+ conversation.setInfos(JamiDaemon.mapToJs(this.dring.conversationInfos(accountId, conversationId)))
account.addConversation(conversation)
})
account.setDevices(
diff --git a/client/package.json b/client/package.json
index b2c1c5f..c983456 100644
--- a/client/package.json
+++ b/client/package.json
@@ -29,7 +29,8 @@
"react-i18next": "^11.18.5",
"react-redux": "^8.0.2",
"react-router-dom": "^6.3.0",
- "socket.io-client": "^4.5.1"
+ "socket.io-client": "^4.5.1",
+ "qrcode.react": "^3.1.0"
},
"devDependencies": {
"@babel/core": "^7.18.13",
diff --git a/client/src/components/ConversationListItem.js b/client/src/components/ConversationListItem.js
index 140ede2..4616da6 100644
--- a/client/src/components/ConversationListItem.js
+++ b/client/src/components/ConversationListItem.js
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
import authManager from '../AuthManager'
@@ -7,27 +7,24 @@
import React, { useState } from "react";
import { useNavigate, useParams } from "react-router-dom"
import { Person } from "@mui/icons-material";
-import { ListItem, ListItemAvatar, ListItemText } from '@mui/material'
-import { Button, Stack, Switch, ThemeProvider, Typography } from "@mui/material"
-import { CloseButton } from './buttons';
-import { AudioCallIcon, BlockContactIcon, ContactDetailsIcon, CrossIcon, MessageIcon, RemoveContactIcon, VideoCallIcon } from './svgIcons';
+import { ListItem, ListItemAvatar, ListItemText, Box, Typography } from '@mui/material'
+import { Button, Stack, Switch, ThemeProvider, Typography, Modal as ModalUM } from "@mui/material"
+import { RemoveContactIcon, VideoCallIcon } from './svgIcons';
+import { AudioCallIcon, BlockContactIcon, ContactDetailsIcon, CrossIcon, MessageIcon } from './svgIcons';
+import { styled } from "@mui/material/styles";
+import {QRCodeSVG, QRCodeCanvas} from 'qrcode.react';
const customStyles = {
content: {
- // top: "50%",
- // left: "50%",
// right: "auto",
// bottom: "auto",
// // marginRight: "-50%",
// transform: "translate(-50%, -50%)",
- // borderRadius: "5px 20px 20px 5px",
- // boxShadow; ""
- // fontSize: "12px",
// padding: "16px"
// top: "1364px",
left: "94px",
- width: "164px",
+ width: "180px",
height: "262px",
background: "#FFFFFF 0% 0% no-repeat padding-box",
boxShadow: "3px 3px 7px #00000029",
@@ -35,7 +32,41 @@
opacity: "1",
textAlign: "left",
- font: "normal normal normal 12px/36px Ubuntu",
+ font: "normal normal normal 12px/26px Ubuntu",
+ letterSpacing: "0px",
+ color: "#000000",
+ },
+};
+
+const cancelStyles = {
+ content: {
+ left: "94px",
+ width: "300px",
+ height: "220px",
+ background: "#FFFFFF 0% 0% no-repeat padding-box",
+ boxShadow: "3px 3px 7px #00000029",
+ borderRadius: "20px",
+ opacity: "1",
+
+ textAlign: "left",
+ font: "normal normal normal 12px/26px Ubuntu",
+ letterSpacing: "0px",
+ color: "#000000",
+ },
+};
+
+const contactDetailsStyles = {
+ content: {
+ left: "94px",
+ width: "450px",
+ height: "450px",
+ background: "#FFFFFF 0% 0% no-repeat padding-box",
+ boxShadow: "3px 3px 7px #00000029",
+ borderRadius: "20px",
+ opacity: "1",
+
+ textAlign: "left",
+ font: "normal normal normal 12px/26px Ubuntu",
letterSpacing: "0px",
color: "#000000",
},
@@ -43,13 +74,18 @@
const stackStyles = {
flexDirection: "row",
- marginBottom: "5px",
- // spacing: "10px",
+ marginBottom: "4px",
+ spacing: "40px",
flex: 1,
alignItems: "center",
- // justifyContent: "space-around"
};
+const iconTextStyle = {
+ marginRight: "10px",
+};
+
+const iconColor = "#005699";
+
export default function ConversationListItem(props) {
const { conversationId, contactId } = useParams();
const conversation = props.conversation;
@@ -64,187 +100,341 @@
const isSelected = conversation.getDisplayUri() === pathId;
const navigate = useNavigate();
- let subtitle;
const [modalIsOpen, setIsOpen] = useState(false);
const [modalDetailsIsOpen, setModalDetailsIsOpen] = useState(false);
const [modalDeleteIsOpen, setModalDeleteIsOpen] = useState(false);
+ const [blockOrRemove, setBlockOrRemove] = useState(true);
+ const [userId, setUserId] = useState(
+ conversation.getFirstMember().contact.getUri()
+ );
+ const [isSwarm, setIsSwarm] = useState("true");
- const openModal = () => setIsOpen(true);
+ const openModal = (e) => {
+ e.preventDefault();
+ console.log(e);
+ setIsOpen(true);
+ };
const openModalDetails = () => setModalDetailsIsOpen(true);
const openModalDelete = () => setModalDeleteIsOpen(true);
-
const closeModal = () => setIsOpen(false);
-
const closeModalDetails = () => setModalDetailsIsOpen(false);
const closeModalDelete = () => setModalDeleteIsOpen(false);
+ let subtitle;
function afterOpenModal() {
// references are now sync'd and can be accessed.
subtitle.style.color = "#f00";
}
- const getAccountDetails = (accountId) => {
- // useEffect(() => {
+ const getContactDetails = () => {
const controller = new AbortController();
authManager
- .fetch(`/api/accounts/${conversation.getAccountId()}`, {
- method: "GET",
- headers: {
- Accept: "application/json",
- "Content-Type": "application/json",
- },
- // body: JSON.stringify(newDetails)
- // {
- // uri: conversation.getFirstMember()?.contact?.getUri(),
- // signal: controller.signal,
- // },
- })
- .then((res) => {
- console.log("YYY 0", res);
- res.json();
- })
+ .fetch(
+ `/api/accounts/${conversation.getAccountId()}/contacts/details/${userId}`,
+ {
+ signal: controller.signal,
+ }
+ )
+ .then((res) => res.json())
.then((result) => {
- console.log("YYY 1", result);
+ console.log("CONTACT LIST - DETAILS: ", result);
})
- .catch((e) => console.log("YYY 2", e));
- // return () => controller.abort()
- // }, [accountId])
+ .catch((e) => console.log("ERROR GET CONTACT DETAILS: ", e));
};
- const [userName, setUserName] = useState("User name");
- const [userId, setUserId] = useState("User id");
- const [codeQr, setVodeQr] = useState("QR");
- const [isSwarm, setIsSwarm] = useState(true);
+ const removeOrBlock = (typeOfRemove) => {
+ console.log(typeOfRemove);
+ setBlockOrRemove(false);
+
+ console.log("EEEH", typeOfRemove, conversation.getAccountId(), userId);
+
+ const controller = new AbortController();
+ authManager
+ .fetch(
+ `/api/accounts/${conversation.getAccountId()}/contacts/${typeOfRemove}/${userId}`,
+ {
+ signal: controller.signal,
+ method: "DELETE",
+ }
+ )
+ .then((res) => res.json())
+ .then((result) => {})
+ .catch((e) => console.log(`ERROR ${typeOfRemove}ing CONTACT : `, e));
+ closeModalDelete();
+ setRefresh(!refresh)
+ };
+ const [refresh, setRefresh] = useState(true)
+
+ useEffect(() => {
+ console.log("refresh");
+ }, [refresh]);
+
const uri = conversation.getId()
? `conversation/${conversation.getId()}`
- : `addContact/${conversation.getFirstMember().contact.getUri()}`;
+ : `addContact/${userId}`;
if (conversation instanceof Conversation) {
return (
- <div>
- <button onClick={openModal}>Open Modal</button>
- <Modal
- isOpen={modalIsOpen}
- // onAfterOpen={afterOpenModal}
- onRequestClose={closeModal}
- style={customStyles}
- contentLabel="Example Modal"
- >
- {/* <h2 ref={(_subtitle) => (subtitle = _subtitle)}>Hello</h2> */}
- {/* <button onClick={closeModal}>close</button> */}
- <Stack
- onClick={() => {
- navigate(`/account/${conversation.getAccountId()}/${uri}`);
- closeModal();
- }}
- {...stackStyles}
+ <div onContextMenu={openModal}>
+ <div name="Modal conversation">
+ <Modal
+ isOpen={modalIsOpen}
+ // onAfterOpen={afterOpenModal}
+ onRequestClose={closeModal}
+ style={customStyles}
+ contentLabel="Example Modal"
>
- <div
- style={{
- marginTop: "24px",
+ <Stack
+ onClick={() => {
+ navigate(`/account/${conversation.getAccountId()}/${uri}`);
+ closeModal();
+ }}
+ {...stackStyles}
+ >
+ <div style={{ ...iconTextStyle }}>
+ <MessageIcon style={{ color: iconColor }} />
+ </div>
+ Message
+ </Stack>
+ <Stack {...stackStyles}>
+ <div style={{ ...iconTextStyle }}>
+ <AudioCallIcon style={{ color: iconColor }} />
+ </div>
+ Démarrer appel audio
+ </Stack>
+
+ <Stack {...stackStyles}>
+ <div style={{ ...iconTextStyle }}>
+ <VideoCallIcon style={{ color: iconColor }} />
+ </div>
+ Démarrer appel vidéo
+ </Stack>
+
+ <Stack
+ {...stackStyles}
+ onClick={() => {
+ navigate(`/account/${conversation.getAccountId()}/`);
+ closeModal();
}}
>
- <MessageIcon />
+ <div style={{ ...iconTextStyle }}>
+ <CrossIcon style={{ color: iconColor }} />
+ </div>
+ Fermer la conversation
+ </Stack>
+
+ <Stack
+ onClick={() => {
+ console.log("open details contact for: ");
+ closeModal();
+ openModalDetails();
+ getContactDetails();
+ }}
+ {...stackStyles}
+ >
+ <div style={{ ...iconTextStyle }}>
+ <ContactDetailsIcon style={{ color: iconColor }} />
+ </div>
+ Détails de la conversation
+ </Stack>
+
+ <Stack
+ onClick={() => {
+ setBlockOrRemove(true);
+ closeModal();
+ openModalDelete();
+ }}
+ {...stackStyles}
+ >
+ <div style={{ ...iconTextStyle }}>
+ <BlockContactIcon style={{ color: iconColor }} />
+ </div>
+ Bloquer le contact
+ </Stack>
+
+ <Stack
+ onClick={() => {
+ setBlockOrRemove(false);
+ closeModal();
+ openModalDelete();
+ }}
+ {...stackStyles}
+ >
+ <div style={{ ...iconTextStyle }}>
+ <RemoveContactIcon style={{ color: iconColor }} />
+ </div>
+ Supprimer contact
+ </Stack>
+ </Modal>
+ </div>
+
+ <div name="Contact details">
+ <Modal
+ isOpen={modalDetailsIsOpen}
+ onRequestClose={closeModalDetails}
+ style={contactDetailsStyles}
+ contentLabel="Détails contact"
+ >
+ <Stack direction={"row"} alignContent="flex-end">
+ <Stack direction={"column"}>
+ <div style={{ height: "100px" }}>
+ <ConversationAvatar
+ displayName={conversation.getDisplayNameNoFallback()}
+ />
+ </div>
+
+ <div
+ style={{
+ fontSize: "20px",
+ marginBottom: "20px",
+ height: "20px",
+ }}
+ >
+ Informations
+ </div>
+
+ <Typography variant="caption">Nom d'utilisateur</Typography>
+ <div style={{ height: "20px" }} />
+ <Typography variant="caption">Identifiant </Typography>
+ <div style={{ height: "20px" }} />
+
+ <div
+ style={{
+ flex: 1,
+ height: "150px",
+ direction: "column",
+ flexDirection: "column",
+ // alignSelf: "flex-end",
+ }}
+ >
+ <Typography variant="caption">Code QR</Typography>
+ </div>
+
+ <Typography variant="caption">est un swarm </Typography>
+ </Stack>
+
+ <Stack direction={"column"}>
+ <div
+ style={{
+ fontWeight: "bold",
+ fontSize: "20px",
+ height: "100px",
+ }}
+ >
+ {conversation.getDisplayNameNoFallback() + "(resolved name)"}
+ </div>
+
+ <div
+ style={{
+ height: "40px",
+ }}
+ />
+ <Typography variant="caption">
+ <div style={{ fontWeight: "bold" }}>
+ {conversation.getDisplayNameNoFallback()}
+ </div>
+ </Typography>
+
+ <div style={{ height: "20px" }} />
+
+ <Typography variant="caption">
+ <div style={{ fontWeight: "bold" }}> {userId}</div>
+ </Typography>
+
+ <div style={{ height: "20px" }} />
+
+ <div height={"40px"}>
+ <QRCodeCanvas value={`${userId}`} />
+ </div>
+
+ <Typography variant="caption">
+ <div style={{ fontWeight: "bold" }}> {isSwarm}</div>
+ </Typography>
+ </Stack>
+ </Stack>
+ <div
+ onClick={closeModalDetails}
+ style={{
+ width: "100px",
+ borderStyle: "solid",
+ textAlign: "center",
+ borderRadius: "5px",
+ marginLeft: "150px",
+ marginTop: "10px",
+ }}
+ >
+ <Typography variant="caption">Fermer</Typography>
</div>
- <div>Message</div>
- </Stack>
- <Stack {...stackStyles}>
- <AudioCallIcon />
- <div>
- Démarrer appel audio
+ </Modal>
+ </div>
- </div>
- </Stack>
-
- <Stack {...stackStyles}>
- <VideoCallIcon /> Démarrer appel vidéo
- </Stack>
-
- <Stack {...stackStyles}>
- <CrossIcon /> Fermer la conversation
- </Stack>
-
- <Stack
- onClick={() => {
- console.log("open details contact for: ");
- closeModal();
- openModalDetails();
- getAccountDetails(conversation.getAccountId());
- }}
- {...stackStyles}
+ <div name="Remove or block details">
+ <Modal
+ isOpen={modalDeleteIsOpen}
+ onRequestClose={closeModalDelete}
+ style={cancelStyles}
+ contentLabel="Merci de confirmer"
>
- <ContactDetailsIcon /> Détails de la conversation
- </Stack>
+ <Typography variant="h4">Merci de confirmer</Typography>
+ <Stack
+ direction={"column"}
+ justifyContent="space-around"
+ spacing={"75px"}
+ >
+ <div style={{ textAlign: "center", marginTop: "10%" }}>
+ <Typography variant="body2">
+ Voulez vous vraiment {blockOrRemove ? "bloquer" : "supprimer"}{" "}
+ ce contact?
+ </Typography>
+ </div>
- <Stack
- onClick={() => {
- console.log("open dialog BLOCK: ");
- closeModal();
- openModalDelete();
- }}
- {...stackStyles}
- >
- <BlockContactIcon /> Bloquer le contact
- </Stack>
-
- <Stack
- onClick={() => {
- console.log("open dialog Supprimer: ");
- closeModal();
- openModalDelete();
- }}
- {...stackStyles}
- >
- <RemoveContactIcon /> Supprimer contact
- </Stack>
- </Modal>
-
- <Modal
- isOpen={modalDetailsIsOpen}
- // onAfterOpen={afterOpenModalDetails}
- onRequestClose={closeModalDetails}
- style={customStyles}
- contentLabel="Détails contact"
- >
- <div>
- <Person /> {userName}
- </div>
- <br />
-
- <div>Nom d'utilisateur {userName}</div>
- <br />
-
- <div>Identifiant {userId}</div>
- <br />
-
- <div>Code QR {codeQr}</div>
- <br />
-
- <div>est un swarm {isSwarm}</div>
- <br />
-
- <button onClick={closeModalDetails}>Fermer</button>
- </Modal>
-
- <Modal
- isOpen={modalDeleteIsOpen}
- // onAfterOpen={afterOpenModalDetails}
- onRequestClose={closeModalDelete}
- style={customStyles}
- contentLabel="Merci de confirmer"
- >
- Voulez vous vraiment supprimer ce contact?
- <button onClick={closeModalDelete}>Bloquer</button>
- <button onClick={closeModalDelete}>Annuler</button>
- </Modal>
+ <Stack
+ direction={"row"}
+ top={"25px"}
+ alignSelf="center"
+ spacing={1}
+ >
+ <Box
+ onClick={() => {
+ if (blockOrRemove) removeOrBlock("block");
+ else removeOrBlock("remove");
+ }}
+ style={{
+ width: "100px",
+ textAlign: "center",
+ borderStyle: "solid",
+ borderColor: "red",
+ borderRadius: "10px",
+ color: "red",
+ }}
+ >
+ {blockOrRemove ? "Bloquer" : "Supprimer"}
+ </Box>
+ <Box
+ onClick={closeModalDelete}
+ style={{
+ width: "100px",
+ textAlign: "center",
+ paddingLeft: "12px",
+ paddingRight: "12px",
+ borderStyle: "solid",
+ borderRadius: "10px",
+ }}
+ >
+ Annuler
+ </Box>
+ </Stack>
+ </Stack>
+ </Modal>
+ </div>
<ListItem
button
alignItems="flex-start"
selected={isSelected}
- // onClick={() =>
- // navigate(`/account/${conversation.getAccountId()}/${uri}`)
- // }
+ onClick={() =>
+ navigate(`/account/${conversation.getAccountId()}/${uri}`)
+ }
>
<ListItemAvatar>
<ConversationAvatar
diff --git a/client/src/components/svgIcons.js b/client/src/components/svgIcons.js
index 839a6d1..73275ee 100644
--- a/client/src/components/svgIcons.js
+++ b/client/src/components/svgIcons.js
@@ -184,7 +184,7 @@
export const MessageIcon = (props) => {
return (
<SvgIcon {...props} viewBox="0 0 16 14.554">
- <svg
+ {/* <svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="14.554"
@@ -192,7 +192,7 @@
>
<defs>
<style>.a{"fill:#005699;"}</style>
- </defs>
+ </defs> */}
<g transform="translate(-3.7 -4.4)">
<g transform="translate(3.7 4.4)">
<g transform="translate(0 0)">
@@ -204,7 +204,7 @@
</g>
</g>
</g>
- </svg>
+ {/* </svg> */}
</SvgIcon>
);
};
@@ -212,7 +212,7 @@
export const AudioCallIcon = (props) => {
return (
<SvgIcon {...props} viewBox="0 0 15.338 16">
- <svg
+ {/* <svg
xmlns="http://www.w3.org/2000/svg"
width="15.338"
height="16"
@@ -220,7 +220,7 @@
>
<defs>
<style>.a{"fill:#005699;"}</style>
- </defs>
+ </defs> */}
<g transform="translate(-2.404 -1.956)">
<g transform="translate(2.404 1.956)">
<g transform="translate(0)">
@@ -232,7 +232,7 @@
</g>
</g>
</g>
- </svg>
+ {/* </svg> */}
</SvgIcon>
);
};
@@ -240,7 +240,7 @@
export const VideoCallIcon = (props) => {
return (
<SvgIcon {...props} viewBox="0 0 16 12">
- <svg
+ {/* <svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="12"
@@ -248,7 +248,7 @@
>
<defs>
<style>.a{"fill:#005699;"}</style>
- </defs>
+ </defs> */}
<g transform="translate(-4.4 -6)">
<g transform="translate(4.4 6)">
<path
@@ -258,7 +258,7 @@
/>
</g>
</g>
- </svg>
+ {/* </svg> */}
</SvgIcon>
);
};
@@ -266,7 +266,7 @@
export const ContactDetailsIcon = (props) => {
return (
<SvgIcon {...props} viewBox="0 0 14.647 16">
- <svg
+ {/* <svg
xmlns="http://www.w3.org/2000/svg"
width="14.647"
height="16"
@@ -274,13 +274,13 @@
>
<defs>
<style>.a{"fill:#005699;"}</style>
- </defs>
+ </defs> */}
<path
class="a"
d="M11.258,9.562A3.774,3.774,0,0,0,13.965,5.9,3.79,3.79,0,0,0,10.144,2,3.871,3.871,0,0,0,8.95,9.562,7.806,7.806,0,0,0,2.9,17.443a.557.557,0,1,0,1.114,0c0-3.821,2.786-6.925,6.209-6.925s6.209,3.1,6.209,6.925a.557.557,0,0,0,1.114,0C17.388,13.463,14.681,10.119,11.258,9.562ZM7.278,5.9a2.866,2.866,0,1,1,5.731,0,2.787,2.787,0,0,1-2.866,2.786A2.838,2.838,0,0,1,7.278,5.9Z"
transform="translate(-2.9 -2)"
/>
- </svg>
+ {/* </svg> */}
</SvgIcon>
);
};
@@ -288,10 +288,10 @@
export const BlockContactIcon = (props) => {
return (
<SvgIcon {...props} viewBox="0 0 16 15.52">
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="15.52">
+ {/* <svg xmlns="http://www.w3.org/2000/svg" width="16" height="15.52">
<defs>
<style>.a{"fill:#005699;"}</style>
- </defs>
+ </defs> */}
<g transform="translate(-2 -2.3)">
<path
class="a"
@@ -303,7 +303,7 @@
d="M12,10.94l.56-.32A6.445,6.445,0,0,0,9.92,9.5a3.626,3.626,0,0,0,2.56-3.52A3.555,3.555,0,0,0,8.88,2.3,3.735,3.735,0,0,0,7.76,9.58,7.327,7.327,0,0,0,2,17.02a.547.547,0,0,0,.56.56.547.547,0,0,0,.56-.56c0-3.6,2.64-6.56,5.92-6.56a5.3,5.3,0,0,1,2.88.88A.971.971,0,0,1,12,10.94ZM8.88,8.7A2.68,2.68,0,1,1,11.6,6.06,2.631,2.631,0,0,1,8.88,8.7Z"
/>
</g>
- </svg>
+ {/* </svg> */}
</SvgIcon>
);
};
@@ -311,7 +311,7 @@
export const RemoveContactIcon = (props) => {
return (
<SvgIcon {...props} viewBox="0 0 16 16">
- <svg
+ {/* <svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
@@ -319,7 +319,7 @@
>
<defs>
<style>.a{"fill:#005699;"}</style>
- </defs>
+ </defs> */}
<g transform="translate(-2 -2)">
<g transform="translate(2 2)">
<path
@@ -328,7 +328,7 @@
/>
</g>
</g>
- </svg>
+ {/* </svg> */}
</SvgIcon>
);
};
diff --git a/model/Conversation.js b/model/Conversation.js
index 85fe48f..956b1c9 100644
--- a/model/Conversation.js
+++ b/model/Conversation.js
@@ -6,6 +6,7 @@
this.accountId = accountId
this.members = members || []
this.messages = []
+ this.infos = {}
}
static from(accountId, object) {
@@ -85,6 +86,10 @@
getMessages() {
return this.messages
}
+
+ setInfos(infos){
+ this.infos = infos
+ }
}
export default Conversation;
diff --git a/package-lock.json b/package-lock.json
index abec6d9..47aecb9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -60,6 +60,7 @@
"emoji-picker-react": "^3.6.1",
"framer-motion": "^7.2.1",
"i18next": "^21.9.1",
+ "qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-emoji-render": "^1.2.4",
@@ -9372,6 +9373,15 @@
"node": ">=6"
}
},
+ "node_modules/qrcode.react": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz",
+ "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==",
+ "dev": true,
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/qs": {
"version": "6.10.3",
"license": "BSD-3-Clause",
@@ -16442,6 +16452,7 @@
"html-webpack-plugin": "^5.5.0",
"i18next": "^21.9.1",
"i18next-parser": "^6.0.0",
+ "qrcode.react": "^3.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-emoji-render": "^1.2.4",
@@ -17683,6 +17694,13 @@
"version": "2.1.1",
"dev": true
},
+ "qrcode.react": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz",
+ "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==",
+ "dev": true,
+ "requires": {}
+ },
"qs": {
"version": "6.10.3",
"requires": {