index.tsx 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import List from '@mui/material/List';
  2. import { makeStyles } from '@material-ui/core'
  3. import { useState,useEffect,useRef,useCallback } from 'react';
  4. import { useSelector, useDispatch } from 'react-redux';
  5. import AlertInfo from '../../../reusableComponents/AlertInfo'
  6. import ChatItem from './ChatItem';
  7. import { notification,playNotificationWithoutPermission,sortByRecent } from '../../../../helpers'
  8. import { getStateMemo } from '../../../../redux/chats/selector'
  9. import { getChatMemo } from '../../../../redux/chat/selector'
  10. import { asyncStartChatById } from '../../../../redux/chat/operations'
  11. import { actionRemoveChat } from '../../../../redux/chat/action'
  12. import { actionScroll, actionIsOpen } from '../../../../redux/control/action'
  13. import { getIsOpen } from '../../../../redux/control/selector';
  14. import { TChats,TChat } from '../../../../typescript/redux/chats/types';
  15. import { timeStampFilter,prodBaseURL } from '../../../../helpers';
  16. const useStyles = makeStyles({
  17. list: {
  18. width: '100%',
  19. maxHeight: '93vh',
  20. overflowY: 'scroll',
  21. '&::-webkit-scrollbar': {
  22. width: '0.4em'
  23. },
  24. '&::-webkit-scrollbar-track': {
  25. boxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
  26. webkitBoxShadow: 'inset 0 0 6px rgba(0,0,0,0.00)',
  27. backgroundColor: '#eceeec',
  28. },
  29. '&::-webkit-scrollbar-thumb': {
  30. backgroundColor: '#ccc8c8',
  31. },
  32. "&::-webkit-scrollbar-thumb:focus": {
  33. backgroundColor: "#959595",
  34. },
  35. "&::-webkit-scrollbar-thumb:active": {
  36. backgroundColor: "#959595",
  37. },
  38. },
  39. })
  40. interface IChatsList {
  41. sort: boolean,
  42. }
  43. const ChatsList = ({sort}:IChatsList) => {
  44. const classes = useStyles()
  45. const dispatch = useDispatch()
  46. const chatsRef = useRef<any>(null)
  47. const [sortedChats, setSortedChats] = useState<TChats>([]);
  48. const { total, chats } = useSelector(getStateMemo)
  49. const chat = useSelector(getChatMemo)
  50. const isOpen = useSelector(getIsOpen)
  51. const handleListItemClick = (companionId: string) => {
  52. isOpen&&dispatch(actionIsOpen(''))
  53. dispatch(asyncStartChatById(companionId))
  54. }
  55. const handleNewMsgs = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>, companionId: string) => {
  56. e.stopPropagation()
  57. dispatch(actionScroll(true))
  58. isOpen&&dispatch(actionIsOpen(''))
  59. dispatch(asyncStartChatById(companionId))
  60. }
  61. useEffect(() => {
  62. const handleNotification= (companionId: string) => {
  63. dispatch(asyncStartChatById(companionId))
  64. dispatch(actionScroll(true))
  65. }
  66. setSortedChats(sortByRecent(chats, sort))
  67. if (chat.companionId&&!sortedChats.find((el) => el.companionId === chat.companionId)) dispatch(actionRemoveChat())
  68. if (chatsRef.current) {
  69. chatsRef.current.forEach(({total,seen}: any,i:number) => {
  70. const oldDifferent = total - seen
  71. const chat = sortedChats[i]
  72. if(chat === undefined) return
  73. const newDifferent = chat.total - chat.seen
  74. if (newDifferent > oldDifferent && !chat.mute) {
  75. playNotificationWithoutPermission(`${prodBaseURL}/receive.mp3`)
  76. notification(chat.name,() => handleNotification(chat.companionId))
  77. }
  78. })
  79. }
  80. chatsRef.current = sortedChats
  81. }, [chats, chat,sort,sortedChats, dispatch])
  82. return total !== '0' ? (
  83. <List className={classes.list} component="nav"
  84. aria-label="main mailbox folders">
  85. {sortedChats.map((el) => <ChatItem key={el.number} chat={el}
  86. handleListItemClick={handleListItemClick} handleNewMsgs={handleNewMsgs} />)}
  87. </List>
  88. ):<AlertInfo name='You do not have Chats yet!' />;
  89. }
  90. export default ChatsList