index.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { makeStyles } from '@material-ui/core'
  2. import { useSelector } from 'react-redux'
  3. import React, { useState } from 'react'
  4. import List from '@mui/material/List';
  5. import ListItem from '@mui/material/ListItem';
  6. import ListItemText from '@mui/material/ListItemText';
  7. import ListItemAvatar from '@mui/material/ListItemAvatar';
  8. import Avatar from '@mui/material/Avatar';
  9. import Typography from '@mui/material/Typography';
  10. import Divider from '@mui/material/Divider';
  11. import Search from './Search'
  12. import AlertInfo from "../../../reusableComponents/AlertInfo";
  13. import { getMessages } from '../../../../redux/messages/selector'
  14. import { getChat } from '../../../../redux/chat/selector'
  15. import { timeStampEU, timeStampFilter, firstLetter, slicedWord, handleSort,prodAwsS3 } from '../../../../helpers'
  16. import { TMessages } from '../../../../typescript/redux/messages/types';
  17. const useStyles = makeStyles({
  18. container: {
  19. height: '100%',
  20. backgroundColor: '#ffffff'
  21. },
  22. list: {
  23. maxHeight: '93vh',
  24. overflowY: 'scroll',
  25. '&::-webkit-scrollbar': {
  26. width: '0.4em'
  27. },
  28. '&::-webkit-scrollbar-track': {
  29. boxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
  30. webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
  31. backgroundColor: '#eceeec',
  32. },
  33. '&::-webkit-scrollbar-thumb': {
  34. backgroundColor: '#ccc8c8',
  35. },
  36. "&::-webkit-scrollbar-thumb:focus": {
  37. backgroundColor: "#959595",
  38. },
  39. "&::-webkit-scrollbar-thumb:active": {
  40. backgroundColor: "#959595",
  41. },
  42. },
  43. listItem: {
  44. cursor:'pointer',
  45. '&:hover': {
  46. backgroundColor: '#f0f0f0',
  47. }
  48. },
  49. })
  50. const SearchList= ({divRef}:{divRef: any | null}) => {
  51. const classes = useStyles()
  52. const { sort } = useSelector(getChat)
  53. const messages = useSelector(getMessages)
  54. const [value, setValue] = useState<string>('')
  55. const [date, setDate] = useState<any>('');
  56. const handleSearch = (e: React.ChangeEvent<HTMLInputElement>): void => setValue(e.target.value)
  57. const handleScrollToTheMessage = (_id: string) => {
  58. const childNodes = divRef.current.childNodes[0].childNodes
  59. let toScrollNode = [...childNodes].find((el: any) => el.id === _id)
  60. if (toScrollNode) {
  61. toScrollNode = [...toScrollNode.childNodes].slice(-1)[0]
  62. toScrollNode.style.boxShadow = '0px 0px 6px 0px #555555'
  63. toScrollNode.scrollIntoView({ behavior: 'smooth' })
  64. setTimeout(() => {
  65. toScrollNode.style.boxShadow = 'unset'
  66. }, 2000)
  67. }
  68. }
  69. const filteredMessages = (arr:TMessages) => arr.filter((el) => {
  70. if (!date) {
  71. return el.message.toLowerCase().includes(value.toLowerCase())
  72. } else if (el.message.toLowerCase().includes(value.toLowerCase())
  73. && timeStampFilter(date) === timeStampFilter(el.createdAt)) {
  74. return el
  75. }
  76. })
  77. const arr: TMessages = filteredMessages(handleSort('createdAt', messages, sort))
  78. return (
  79. <div className={classes.container}>
  80. <Search handleSearch={handleSearch} value={value}
  81. setDate={setDate} date={date} />
  82. <div className={messages.length > 0 ?classes.list:undefined}>
  83. {messages.length > 0 ? arr.length > 0 ?
  84. <List sx={{ width: '100%' }}>
  85. {arr.map(({ name, lastName, avatarUrl, color, message, createdAt,_id }) =>
  86. <div key={createdAt}>
  87. <ListItem onClick={() => handleScrollToTheMessage(_id)}
  88. alignItems="flex-start" className={classes.listItem}>
  89. <ListItemAvatar>
  90. <Avatar alt={name} src={avatarUrl?`${prodAwsS3}/${avatarUrl}`:undefined}
  91. sx={{ background: color, width: 44, height: 44, marginRight:2 }}>
  92. {!avatarUrl&&`${firstLetter(name)}${firstLetter(lastName)}`}
  93. </Avatar>
  94. </ListItemAvatar>
  95. <ListItemText
  96. primary={`${firstLetter(name)}${slicedWord(name, 15, 1)}
  97. ${firstLetter(lastName)}${slicedWord(lastName, 15, 1)}`}
  98. secondary={<>
  99. <Typography
  100. sx={{ display: 'block',wordBreak:'break-word' }}
  101. component="span"
  102. variant="body2"
  103. color="text.primary"
  104. >
  105. {message}
  106. </Typography>
  107. {timeStampEU(createdAt)}
  108. </>}
  109. />
  110. </ListItem>
  111. <Divider variant="inset"/>
  112. </div>)}
  113. </List> :
  114. <AlertInfo name={`Can not find message by request: ${value}`}/>:
  115. <AlertInfo name='You do not have messages yet!' />}
  116. </div>
  117. </div>
  118. )
  119. }
  120. export default SearchList