123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- import { makeStyles,Typography } from '@material-ui/core'
- import { useState } from 'react';
- import { styled } from '@mui/material/styles';
- import Menu from '@mui/material/Menu';
- import MenuItem from '@mui/material/MenuItem';
- import NotificationsNoneIcon from '@mui/icons-material/NotificationsNone';
- import VolumeOffIcon from '@mui/icons-material/VolumeOff';
- import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
- import ListItemButton from '@mui/material/ListItemButton';
- import Avatar from '@mui/material/Avatar';
- import ListItemText from '@mui/material/ListItemText';
- import ListItemIcon from '@mui/material/ListItemIcon';
- import Badge from '@mui/material/Badge';
- import DoneAllIcon from '@mui/icons-material/DoneAll';
- import DoneIcon from '@mui/icons-material/Done';
- import PushPinIcon from '@mui/icons-material/PushPin';
- import CloseIcon from '@mui/icons-material/Close';
- import { muteChat,pinChat } from '../../../../../api-data';
- import { TChat } from '../../../../../typescript/redux/chats/types';
- import { firstLetter, slicedWord, timeStampEU,prodAwsS3 } from '../../../../../helpers';
- import DeleteModal from './DeleteModal';
- 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: '8px 8px',
- },
- '& .MuiMenuItem-root': {
- marginBottom: theme.spacing(1),
- '& .MuiSvgIcon-root': {
- fontSize: 21,
- color: theme.palette.text.secondary,
- marginRight: theme.spacing(4),
- }
- },
- },
- }));
- const StyledBadge = styled(Badge)(({ theme }) => ({
- '& .MuiBadge-badge': {
- backgroundColor: '#44b700',
- color: '#44b700',
- boxShadow: `0 0 0 2px ${theme.palette.background.paper}`,
- '&::after': {
- position: 'absolute',
- top: 0,
- left: 0,
- width: '100%',
- height: '100%',
- borderRadius: '50%',
- animation: 'ripple 1.2s infinite ease-in-out',
- border: '1px solid currentColor',
- content: '""',
- },
- },
- '@keyframes ripple': {
- '0%': {
- transform: 'scale(.8)',
- opacity: 1,
- },
- '100%': {
- transform: 'scale(2.4)',
- opacity: 0,
- },
- },
- }));
- const useStyles = makeStyles({
- listItemInnerText: {
- display: 'flex',
- alignContent: 'center',
- alignItems: 'center',
- flexWrap: 'nowrap',
- },
- listItemInnerText__icon: {
- marginLeft: 5,
- },
- listItem_iconAvatar: {
- marginRight:10
- },
- listItem_iconRight: {
- marginRight: 10,
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- alignContent: 'center',
- flexDirection: 'column'
- },
- listItem_iconTimeChecked: {
- display: 'flex',
- flexWrap: 'nowrap',
- alignItems: 'center',
- justifyContent: 'center',
- alignContent: 'center',
- marginBottom:2
- },
- listItem_iconRightBtn: {
- cursor: 'pointer',
- background: '#0ac40a',
- borderRadius: '50%',
- color: '#ffffff',
- border: 'none',
- height: 24,
- width: 24,
- textAlign: 'center',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- alignContent: 'center',
- fontSize: 12,
- marginLeft: 10,
- '&:hover': {
- outline: 'solid 3px #3ee415',
- }
- },
- listItem_iconRightBtnMute: {
- cursor: 'pointer',
- background: '#a7aaa7',
- borderRadius: '50%',
- color: '#ffffff',
- border: 'none',
- height: 24,
- width: 24,
- textAlign: 'center',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- alignContent: 'center',
- fontSize: 12,
- marginLeft: 10,
- '&:hover': {
- outline: 'solid 3px #cccbcb',
- }
- },
- pinnedIcon: {
- transform: 'rotate(45deg)',
- },
- listIconsRightContainer: {
- marginLeft: 'auto',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- alignContent: 'center',
- },
- listItem_icon_time: {
- fontSize: 12,
- marginLeft: 5,
- },
- listItem_typing: {
- animation: 'ripple 4s infinite ease-in-out',
- },
- listItem_dots: {
- fontWeight: 'bold',
- display:'inline-block',
- fontFamily: 'monospace',
- clipPath: 'inset(0 3ch 0 0)',
- animation: `$run 2s steps(5) infinite`,
- },
- '@keyframes run': {
- to: {
- clipPath: 'inset(0 -1ch 0 0)'
- },
- },
- iconClose: {
- '&:hover': {
- transform: 'rotate(180deg)',
- transition: 'all 250ms ease-out ',
- }
- },
- })
- interface IChatItem {
- chat: TChat,
- handleListItemClick: (companionId: string) => void,
- handleNewMsgs: (e: any, companionId: string) => void,
- id: string,
- pinned: boolean,
- selectedCompanionId: string,
- }
- const ChatItem = ({chat,handleListItemClick,handleNewMsgs,id,pinned,selectedCompanionId}:IChatItem) => {
- 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 { name, lastName, avatarUrl, color, companionId, mute, seen, total, watched,
- typing, online, lastMessage, lastMessageCreatedAt, createdAt,seenCompanion } = chat
- const openedChat = companionId === selectedCompanionId
- const handlePin = (id: string, pinned:boolean) => {
- pinChat(id,!pinned)
- handleClose(undefined)
- }
- const handleClose = (type: string | undefined): void => {
- if (type === 'mute') muteChat(companionId)
- if (type === 'delete') setModal(true)
- setAnchorEl(null)
- setSelected(false)
- }
- const handleContextMenu = (e: React.MouseEvent<HTMLDivElement>):void => {
- e.preventDefault()
- setAnchorEl(e.currentTarget)
- setSelected(true)
- }
-
- return (
- <>
- {modal&&<DeleteModal setModal={setModal} chat={chat}/>}
- <ListItemButton
- sx={{backgroundColor: openedChat ? '#26afee' : selected ? 'rgba(0, 0, 0, 0.1)' : 'transparent',
- '&:hover':{backgroundColor:openedChat ? '#26afee':'rgba(0, 0, 0, 0.1)'}}}
- onClick={() => handleListItemClick(companionId)}
- onContextMenu={(e) => handleContextMenu(e)}>
- <ListItemIcon className={classes.listItem_iconAvatar}>
- <StyledBadge overlap="circular" variant={online === 'true'?'dot':'standard'}
- anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}>
- <Avatar alt={name} src={avatarUrl?`${prodAwsS3}/${avatarUrl}`:undefined}
- sx={{ background: color, width: 54, height: 54 }}>
- {!avatarUrl&&`${firstLetter(name)}${firstLetter(lastName)}`}
- </Avatar>
- </StyledBadge>
- </ListItemIcon>
- <ListItemText primaryTypographyProps={{color:openedChat?'#ffffff':'#000000'}} primary={<div className={classes.listItemInnerText}>
- <span>{`${firstLetter(name)}${slicedWord(name, 15, 1)}
- ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}</span>
- {mute && <VolumeOffIcon style={{color:openedChat?'#ffffff':'#959595'}}
- className={classes.listItemInnerText__icon} fontSize='small' />}</div>}
- secondary={typing ? <span style={{color:openedChat?'#ffffff':'#4d4d4d'}}
- className={classes.listItem_typing}>
- typing<span style={{color:openedChat?'#ffffff':'#1b1b1b'}}
- className={classes.listItem_dots}>...</span></span> :
- lastMessage ? slicedWord(lastMessage, 35) :
- `${firstLetter(name)}${slicedWord(name, 8, 1)} joined Telegram`}
- secondaryTypographyProps={{color:openedChat?'#ffffff':'#000000'}}/>
- <ListItemIcon className={classes.listItem_iconRight}>
- <div className={classes.listItem_iconTimeChecked}>
- {watched &&<DoneAllIcon style={{ color: openedChat ? '#ffffff' : '#18bd03' }} fontSize='small' />}
- {!watched&&seenCompanion < total&& <DoneIcon style={{ color: openedChat ? '#ffffff' :'#18bd03' }} fontSize='small' />}
- <Typography className={classes.listItem_icon_time} style={{ color: openedChat ? '#ffffff' : '#1b1b1b' }}
- variant="h6" color="initial">
- {timeStampEU(lastMessageCreatedAt?lastMessageCreatedAt:createdAt)}
- </Typography>
- </div>
- <div className={classes.listIconsRightContainer}>
- {pinned && <PushPinIcon className={classes.pinnedIcon} fontSize='small'
- style={{color:openedChat?'#ffffff':'#959595'}}/>}
- {lastMessage && total > seen &&
- <button onClick={(e) => handleNewMsgs(e, companionId)}
- style={{outline:openedChat?'none':undefined,color:openedChat&&!mute?'#26afee':openedChat?'#ffffff':undefined,backgroundColor:openedChat&&!mute?'#ffffff':openedChat?'#a7aaa7':undefined}}
- className={mute ? classes.listItem_iconRightBtnMute : classes.listItem_iconRightBtn}>
- {total - seen}
- </button>}
- </div>
- </ListItemIcon>
- </ListItemButton>
- <StyledMenu
- id="demo-positioned-menu"
- aria-labelledby="demo-positioned-button"
- anchorEl={anchorEl}
- open={open}
- onClose={handleClose}
- >
- <MenuItem onClick={() => handleClose('mute')}>
- {mute ? <NotificationsNoneIcon /> : <VolumeOffIcon />}
- {mute ? 'Unmute chat':'Mute chat'}
- </MenuItem>
- <MenuItem onClick={() => handlePin(id,pinned)}>
- {pinned ?
- <CloseIcon className={classes.iconClose} /> :
- <PushPinIcon />}
- {pinned?'Unpin chat':'Pin chat'}
- </MenuItem>
- <MenuItem style={{color:'#f02a2a'}} onClick={() => handleClose('delete')}>
- <DeleteOutlineIcon style={{color:'#f02a2a'}}/>
- Delete chat
- </MenuItem>
- </StyledMenu>
- </>
- );
- }
- export default ChatItem
|