|
@@ -0,0 +1,374 @@
|
|
|
+import { makeStyles } from "@material-ui/core/styles";
|
|
|
+import { styled } from '@mui/material/styles';
|
|
|
+import { useState } from "react";
|
|
|
+import Typography from '@mui/material/Typography';
|
|
|
+import Button from '@mui/material/Button';
|
|
|
+import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
|
|
+import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
|
|
|
+import Menu from '@mui/material/Menu';
|
|
|
+import MenuItem from '@mui/material/MenuItem';
|
|
|
+import Divider from '@mui/material/Divider';
|
|
|
+import CheckBoxIcon from '@mui/icons-material/CheckBox';
|
|
|
+import Checkbox from '@mui/material/Checkbox';
|
|
|
+import PushPinIcon from '@mui/icons-material/PushPin';
|
|
|
+import CloseIcon from '@mui/icons-material/Close';
|
|
|
+import ReplyIcon from '@mui/icons-material/Reply';
|
|
|
+import DoneAllIcon from '@mui/icons-material/DoneAll';
|
|
|
+import DoneIcon from '@mui/icons-material/Done';
|
|
|
+import EditIcon from '@mui/icons-material/Edit';
|
|
|
+import SouthWestIcon from '@mui/icons-material/SouthWest';
|
|
|
+import NorthEastIcon from '@mui/icons-material/NorthEast';
|
|
|
+import PhoneIcon from '@mui/icons-material/Phone';
|
|
|
+import Avatar from '@mui/material/Avatar';
|
|
|
+import { CopyToClipboard } from 'react-copy-to-clipboard';
|
|
|
+import { firstLetter, slicedWord, timeStampMessage, copied,emojisArr,prodAwsS3,getTimeBySeconds } from '../../../../../../helpers'
|
|
|
+import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
|
|
|
+
|
|
|
+const StyledMenu = styled((props:any) => (
|
|
|
+ <Menu
|
|
|
+ elevation={0}
|
|
|
+ anchorOrigin={{
|
|
|
+ vertical: 'top',
|
|
|
+ horizontal: 'right',
|
|
|
+ }}
|
|
|
+ transformOrigin={{
|
|
|
+ vertical: 'bottom',
|
|
|
+ horizontal: 'right',
|
|
|
+ }}
|
|
|
+ {...props}
|
|
|
+ />
|
|
|
+))(({ theme }:any) => ({
|
|
|
+ '& .MuiPaper-root': {
|
|
|
+ borderRadius: 10,
|
|
|
+ marginTop: theme.spacing(0),
|
|
|
+ minWidth: 220,
|
|
|
+ color:
|
|
|
+ theme.palette.mode === 'light' ? 'rgb(55, 65, 81)' : theme.palette.grey[500],
|
|
|
+ boxShadow:
|
|
|
+ 'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px',
|
|
|
+ '& .MuiMenu-list': {
|
|
|
+ padding: '4px 4px',
|
|
|
+ },
|
|
|
+ '& .MuiMenuItem-root': {
|
|
|
+ marginBottom: theme.spacing(1),
|
|
|
+ '& .MuiSvgIcon-root': {
|
|
|
+ fontSize: 21,
|
|
|
+ color: theme.palette.text.secondary,
|
|
|
+ marginRight: theme.spacing(2),
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+}));
|
|
|
+
|
|
|
+const useStyles = makeStyles({
|
|
|
+ container: {
|
|
|
+ display: "flex",
|
|
|
+ alignItems: 'flex-end',
|
|
|
+ alignContent: 'flex-end',
|
|
|
+ flexDirection:'column',
|
|
|
+ borderRadius: 7,
|
|
|
+ position: 'relative',
|
|
|
+ padding:'4px 22px 4px 0px'
|
|
|
+ },
|
|
|
+ wrapper: {
|
|
|
+ position: 'relative',
|
|
|
+ display: 'flex',
|
|
|
+ alignItems: 'start',
|
|
|
+ alignContent: 'start',
|
|
|
+ flexDirection: 'column',
|
|
|
+ maxWidth: 450,
|
|
|
+ minWidth:200,
|
|
|
+ padding: 5,
|
|
|
+ borderRadius: 7,
|
|
|
+ wordBreak:'break-word',
|
|
|
+ textAlign: "left",
|
|
|
+ font: "400 .9em 'Open Sans', sans-serif",
|
|
|
+ },
|
|
|
+ wrapperInner: {
|
|
|
+ display: 'flex',
|
|
|
+ alignItems: 'center',
|
|
|
+ alignContent: 'center',
|
|
|
+ justifyContent: 'space-between',
|
|
|
+ flexWrap: "nowrap",
|
|
|
+ width: '100%',
|
|
|
+ marginBottom:10
|
|
|
+ },
|
|
|
+ informationWrapper: {
|
|
|
+ display: 'flex',
|
|
|
+ alignItems: 'center',
|
|
|
+ alignContent: 'center',
|
|
|
+ justifyContent: 'flex-end',
|
|
|
+ width: '100%',
|
|
|
+ paddingRight:3,
|
|
|
+ },
|
|
|
+ time: {
|
|
|
+ fontSize: ".65em",
|
|
|
+ fontWeight:600,
|
|
|
+ },
|
|
|
+ modalDelete: {
|
|
|
+ background: '#ffffff',
|
|
|
+ position: 'absolute',
|
|
|
+ content:'',
|
|
|
+ width: '20%',
|
|
|
+ height:'auto',
|
|
|
+ left: '40%',
|
|
|
+ bottom: '48.5%',
|
|
|
+ borderRadius: 10,
|
|
|
+ padding: 10,
|
|
|
+ display: 'flex',
|
|
|
+ flexDirection:'column'
|
|
|
+ },
|
|
|
+ overlay: {
|
|
|
+ position: 'fixed',
|
|
|
+ top: 0,
|
|
|
+ left: 0,
|
|
|
+ width: '100vw',
|
|
|
+ height: '100vh',
|
|
|
+ zIndex: 100,
|
|
|
+ backgroundColor: 'rgba(104, 105, 104, 0.6)',
|
|
|
+ overflowY: 'hidden',
|
|
|
+ },
|
|
|
+ emojiTitle: {
|
|
|
+ position: "absolute",
|
|
|
+ fontSize: "1.7em",
|
|
|
+ fontWeight:600,
|
|
|
+ bottom: '0.2rem',
|
|
|
+ left: -40,
|
|
|
+ },
|
|
|
+ emojiCompanionTitle: {
|
|
|
+ position: "absolute",
|
|
|
+ fontSize: "1.7em",
|
|
|
+ fontWeight:600,
|
|
|
+ bottom: '2.2rem',
|
|
|
+ left: -40,
|
|
|
+ },
|
|
|
+ emoji: {
|
|
|
+ cursor: 'pointer',
|
|
|
+ fontSize: '1.7rem',
|
|
|
+ transition: 'all 0.3s',
|
|
|
+ '&:hover': {
|
|
|
+ transform: 'scale(1.5)'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emojiActive: {
|
|
|
+ cursor: 'pointer',
|
|
|
+ fontSize: '1.2rem',
|
|
|
+ animation: `$emoji 0.6s ease-out`,
|
|
|
+ animationDirection: 'forwards',
|
|
|
+ animationIterationCount: 1,
|
|
|
+ },
|
|
|
+ '@keyframes emoji': {
|
|
|
+ '5%': { transform: 'translateY(1rem)'},
|
|
|
+ '10%': { transform: 'translateY(0) scale(1)',opacity: 1},
|
|
|
+ '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
|
|
|
+ '80%': {opacity: 0},
|
|
|
+ '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
|
|
|
+ },
|
|
|
+ iconClose: {
|
|
|
+ '&:hover': {
|
|
|
+ transform: 'rotate(180deg)',
|
|
|
+ transition: 'all 250ms ease-out ',
|
|
|
+ }
|
|
|
+ },
|
|
|
+ checkboxSelect: {
|
|
|
+ position: 'absolute',
|
|
|
+ right: -64,
|
|
|
+ top: -10,
|
|
|
+ pointerEvents: 'auto'
|
|
|
+ },
|
|
|
+ avatarIcon: {
|
|
|
+ position: 'absolute',
|
|
|
+ right: -54,
|
|
|
+ bottom: 0,
|
|
|
+ },
|
|
|
+ tongueOne: {
|
|
|
+ content: "''",
|
|
|
+ position: "absolute",
|
|
|
+ width: "0",
|
|
|
+ height: "0",
|
|
|
+ borderRight: "15px solid transparent",
|
|
|
+ borderLeft: "15px solid transparent",
|
|
|
+ bottom: '0px',
|
|
|
+ right: "-15px",
|
|
|
+},
|
|
|
+tongueTwo: {
|
|
|
+ content: "''",
|
|
|
+ position: "absolute",
|
|
|
+ width: "0",
|
|
|
+ height: "0",
|
|
|
+ borderRight: "16px solid transparent",
|
|
|
+ borderLeft: "16px solid transparent",
|
|
|
+ bottom: "0px",
|
|
|
+ right: "-17px",
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
|
|
|
+
|
|
|
+interface IMessageRightCall {
|
|
|
+ message: string,
|
|
|
+ initiator: boolean,
|
|
|
+ reject: boolean,
|
|
|
+ duration: number,
|
|
|
+ tongue: boolean,
|
|
|
+ watched: boolean,
|
|
|
+ edited: boolean,
|
|
|
+ avatarUrl: string,
|
|
|
+ color: string,
|
|
|
+ name:string,
|
|
|
+ lastName:string,
|
|
|
+ createdAt: string,
|
|
|
+ caption: string,
|
|
|
+ emoji: string,
|
|
|
+ emojiCompanion: string,
|
|
|
+ pinned: boolean,
|
|
|
+ isSomeSelected: boolean,
|
|
|
+ isSelected:(_id:string) => boolean,
|
|
|
+ handleSelected: (_id:string) => void,
|
|
|
+ _id: string,
|
|
|
+ nightMode: boolean,
|
|
|
+ handleReply: (_id: string) => void,
|
|
|
+ handleForward: (_id: string) => void,
|
|
|
+ handleEdit:(_id: string) => void,
|
|
|
+}
|
|
|
+
|
|
|
+const MessageRightCall = ({message,initiator,reject,duration,tongue,watched,edited,avatarUrl,color,name,lastName,createdAt,caption,emoji,emojiCompanion,pinned,isSomeSelected,isSelected,handleSelected,_id,nightMode,handleReply,handleForward,handleEdit}:IMessageRightCall) => {
|
|
|
+ const classes = useStyles();
|
|
|
+ const [anchorEl, setAnchorEl] = useState<any>(null);
|
|
|
+ const [selected, setSelected] = useState<boolean>(false);
|
|
|
+ const [modal,setModal] = useState<boolean>(false)
|
|
|
+ const open = Boolean(anchorEl);
|
|
|
+ const checked = isSelected(_id)
|
|
|
+ const handleClose = (type: string | undefined): void => {
|
|
|
+ if (type === 'copy') copied('Text')
|
|
|
+ if (type === 'delete') setModal(true)
|
|
|
+ setAnchorEl(null)
|
|
|
+ setSelected(false)
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleDeleteModal = (e: any) => {
|
|
|
+ const id = e.target.id
|
|
|
+ if (id === 'overlay' || id === 'cancel') return setModal(false)
|
|
|
+ if (id === 'delete') {
|
|
|
+ removeMessageById(_id)
|
|
|
+ setModal(false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const handleContextMenu = (e: React.MouseEvent<HTMLDivElement>):void => {
|
|
|
+ e.preventDefault()
|
|
|
+ setAnchorEl(e.currentTarget)
|
|
|
+ setSelected(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleEmojiMenu = ({ target }: any): void => {
|
|
|
+ const idEmoji = target.id
|
|
|
+ if (idEmoji === emoji) {updateMessageById(_id,'')
|
|
|
+ } else updateMessageById(_id,idEmoji)
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={classes.container} style={{marginBottom:tongue?12:0}}>
|
|
|
+ <div onContextMenu={(e) => handleContextMenu(e)} className={classes.wrapper}
|
|
|
+ style={{backgroundColor:selected?'#ced8d7':"#deffa9",pointerEvents:isSomeSelected?'none':'auto'}}>
|
|
|
+ <Typography style={{color: "#26afee"}} variant="h6" align="right">
|
|
|
+ {`${firstLetter(name)}${slicedWord(name, 15, 1)}
|
|
|
+ ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}
|
|
|
+ </Typography>
|
|
|
+ <div className={classes.wrapperInner}>
|
|
|
+ <Typography style={{color: "#00b333"}} variant="h6" align="right">
|
|
|
+ {message}
|
|
|
+ </Typography>
|
|
|
+ <PhoneIcon style={{color:'#18bd03'}} fontSize='large' />
|
|
|
+ </div>
|
|
|
+ <div className={classes.informationWrapper}>
|
|
|
+ {!initiator ? <SouthWestIcon style={{ color: reject?'#f02a2a':'#18bd03', marginRight: 5 }} fontSize='small' /> :
|
|
|
+ <NorthEastIcon style={{ color: reject?'#f02a2a':'#18bd03',marginRight:5}} fontSize='small' />}
|
|
|
+ <div className={classes.time} style={{ color: '#18bd03'}}>{`${edited?'edited ':''}${timeStampMessage(createdAt)}${duration?', '+getTimeBySeconds(duration):''}`}</div>
|
|
|
+ {watched ? <DoneAllIcon style={{ color: '#18bd03', marginLeft: 5 }} fontSize='small' /> :
|
|
|
+ <DoneIcon style={{ color: '#18bd03',marginLeft:5}} fontSize='small' />}
|
|
|
+ </div>
|
|
|
+ {tongue&&<div className={classes.avatarIcon}>
|
|
|
+ <Avatar alt={name} src={avatarUrl?`${prodAwsS3}/${avatarUrl}`:undefined}
|
|
|
+ sx={{ background: color, width: 40, height: 40 }}>
|
|
|
+ {!avatarUrl&&`${firstLetter(name)}${firstLetter(lastName)}`}
|
|
|
+ </Avatar>
|
|
|
+ </div>}
|
|
|
+ {tongue&&<span className={classes.tongueOne} style={{borderBottom: `15px solid ${selected?'#ced8d7':'#deffa9'}`}}></span>}
|
|
|
+ {tongue&&<span className={classes.tongueTwo} style={{borderBottom: `17px solid ${selected?'#ced8d7':'#deffa9'}`}}></span>}
|
|
|
+ {emojiCompanion && <div className={classes.emojiCompanionTitle}>{emojisArr[Number(emojiCompanion)]}</div>}
|
|
|
+ {emoji && <div className={classes.emojiTitle}>{emojisArr[Number(emoji)]}</div>}
|
|
|
+ {isSomeSelected && <div className={classes.checkboxSelect}><Checkbox {...label} checked={checked} sx={{ color: nightMode ? '#ffffff' : '#00ff48', '&.Mui-checked': { color: nightMode ? '#ffffff' : '#00ff48' } }}
|
|
|
+ onClick={() => handleSelected(_id)}/></div>}
|
|
|
+ <StyledMenu id="demo-positioned-menu" aria-labelledby="demo-positioned-button"
|
|
|
+ anchorEl={anchorEl} open={open} onClose={handleClose}>
|
|
|
+ <MenuItem onClick={handleEmojiMenu} style={{ cursor: 'none' }} >
|
|
|
+ {emojisArr.map((el:string, i:number) =>
|
|
|
+ <div key={el} className={emoji === String(i)?classes.emojiActive:classes.emoji} id={String(i)}>{el}</div>)}
|
|
|
+ </MenuItem>
|
|
|
+ <Divider />
|
|
|
+ <MenuItem onClick={() => {
|
|
|
+ handleReply(_id)
|
|
|
+ handleClose(undefined)
|
|
|
+ }}>
|
|
|
+ <ReplyIcon />
|
|
|
+ Reply
|
|
|
+ </MenuItem>
|
|
|
+ <MenuItem onClick={() => {
|
|
|
+ handleForward(_id)
|
|
|
+ handleClose(undefined)
|
|
|
+ }}>
|
|
|
+ <ReplyIcon style={{transform :'rotateY(180deg)'}} />
|
|
|
+ Forward
|
|
|
+ </MenuItem>
|
|
|
+ <MenuItem onClick={() => {
|
|
|
+ handleEdit(_id)
|
|
|
+ handleClose(undefined)
|
|
|
+ }}>
|
|
|
+ <EditIcon/>
|
|
|
+ Edit
|
|
|
+ </MenuItem>
|
|
|
+ <CopyToClipboard onCopy={() => handleClose('copy')} text={`${message ? message : ''} ${caption ? caption : ''}`}>
|
|
|
+ <MenuItem>
|
|
|
+ <ContentCopyIcon />
|
|
|
+ Copy Text
|
|
|
+ </MenuItem>
|
|
|
+ </CopyToClipboard>
|
|
|
+ <MenuItem onClick={() => {
|
|
|
+ pinMessageById(_id, !pinned)
|
|
|
+ handleClose(undefined)
|
|
|
+ }}>
|
|
|
+ {pinned ?
|
|
|
+ <CloseIcon className={classes.iconClose} /> :
|
|
|
+ <PushPinIcon />}
|
|
|
+ {pinned?'Unpin':'Pin'}
|
|
|
+ </MenuItem>
|
|
|
+ <MenuItem onClick={() => {
|
|
|
+ handleSelected(_id)
|
|
|
+ handleClose(undefined)
|
|
|
+ }}>
|
|
|
+ <CheckBoxIcon />
|
|
|
+ Select
|
|
|
+ </MenuItem>
|
|
|
+ <MenuItem style={{color:'#f02a2a'}} onClick={() => handleClose('delete')}>
|
|
|
+ <DeleteOutlineIcon style={{color:'#f02a2a'}}/>
|
|
|
+ Delete
|
|
|
+ </MenuItem>
|
|
|
+ </StyledMenu>
|
|
|
+ {modal &&
|
|
|
+ <div onClick={handleDeleteModal} className={classes.overlay} id='overlay'>
|
|
|
+ <div className={classes.modalDelete}>
|
|
|
+ <h3 style={{color: '#2c2c2c'}}>Delete message</h3>
|
|
|
+ <p style={{ color: '#050505' }}>Are you sure you want to delete message?</p>
|
|
|
+ <Button id='delete' variant="text" color="error" style={{fontWeight:500,fontSize:22}}>
|
|
|
+ DELETE MESSAGE
|
|
|
+ </Button>
|
|
|
+ <Button id='cancel' variant="text" style={{fontWeight:500,fontSize:22}}>
|
|
|
+ CANCEL
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </div>}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+)};
|
|
|
+
|
|
|
+export default MessageRightCall
|