index.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { useState,useEffect,useMemo } from 'react';
  2. import { useSelector } from 'react-redux';
  3. import { makeStyles } from '@material-ui/core'
  4. import { styled } from '@mui/material/styles';
  5. import Tab from '@mui/material/Tab';
  6. import Tabs from '@mui/material/Tabs';
  7. import Box from '@mui/material/Box';
  8. import AudioList from './AudioList';
  9. import MediaList from './MediaList';
  10. import FilesList from './FilesList';
  11. import TextList from './TextList';
  12. import VideoList from './VideoList'
  13. import { getOpenPinned } from '../../../../../redux/control/selector';
  14. import { getPinnedMessagesMemo } from '../../../../../redux/pinnedMessages/selector';
  15. import { getMessagesMemo } from '../../../../../redux/messages/selector'
  16. import { handleSort,filterBy } from '../../../../../helpers';
  17. import { getChat } from '../../../../../redux/chat/selector'
  18. import { TMessages,TMessage } from '../../../../../typescript/redux/messages/types'
  19. const useStyles = makeStyles({
  20. container: {
  21. height: '7vh',
  22. display: "flex",
  23. alignContent: "end",
  24. alignItems: "end",
  25. width:'100%',
  26. borderBottom: 'solid 2px #dddddd',
  27. },
  28. })
  29. interface StyledTabsProps {
  30. children?: React.ReactNode;
  31. value: number;
  32. onChange: (event: React.SyntheticEvent, newValue: number) => void;
  33. }
  34. const StyledTabs = styled((props: StyledTabsProps) => (
  35. <Tabs
  36. {...props}
  37. TabIndicatorProps={{ children: <span className="MuiTabs-indicatorSpan" /> }}
  38. />
  39. ))({
  40. '& .MuiTabs-flexContainer': {
  41. display: "flex",
  42. width: '100%',
  43. padding:'0px 10px',
  44. justifyContent: "space-between"
  45. },
  46. '& .MuiTabs-indicator': {
  47. height: 0,
  48. backgroundColor: 'transparent',
  49. borderBottom: '3px solid #1976d2',
  50. borderLeft: '3px solid transparent',
  51. borderRight: '3px solid transparent',
  52. },
  53. });
  54. const StyledTab = styled((props:{label: string}) => <Tab disableRipple {...props} />)(
  55. () => ({
  56. fontSize: '1rem',
  57. fontWeight: 550,
  58. textTransform: 'none',
  59. minWidth:'auto'
  60. }),
  61. );
  62. interface IProfileLists {
  63. setDisabled: React.Dispatch<boolean>,
  64. chatDivRef: any | null,
  65. }
  66. const ProfileLists = ({setDisabled,chatDivRef}:IProfileLists) => {
  67. const classes = useStyles()
  68. const { sort } = useSelector(getChat)
  69. const openPinned = useSelector(getOpenPinned)
  70. const messagesMemo = useSelector(getMessagesMemo)
  71. const pinnedMessagesMemo = useSelector(getPinnedMessagesMemo)
  72. const [isActive, setIsActive] = useState<number>(0)
  73. const handleIsActive = (_e:any,newValue: number): void => setIsActive(newValue)
  74. const handleScrollToTheMessage = (_id: string) => {
  75. const childNodes = chatDivRef.current.childNodes[0].childNodes
  76. let toScrollNode = [...childNodes].find((el: any) => el.id === _id)
  77. if (toScrollNode) {
  78. toScrollNode = [...toScrollNode.childNodes].slice(-1)[0]
  79. toScrollNode.style.backgroundColor = 'rgba(70, 70, 70, 0.4)'
  80. toScrollNode.style.boxShadow = '0px 0px 6px 0px #ffffff'
  81. toScrollNode.scrollIntoView({ behavior: 'smooth' })
  82. setTimeout(() => {
  83. toScrollNode.style.backgroundColor = 'unset'
  84. toScrollNode.style.boxShadow = 'unset'
  85. }, 2000)
  86. }
  87. }
  88. const filteredAndSorted: TMessages = useMemo(() => handleSort('createdAt', !openPinned ? messagesMemo : pinnedMessagesMemo, sort)
  89. .filter((el:TMessage) => filterBy[isActive].includes(el.type)),[isActive,messagesMemo,openPinned,pinnedMessagesMemo,sort])
  90. useEffect(() => {
  91. setDisabled(filteredAndSorted.length > 0?false:true)
  92. }, [filteredAndSorted, setDisabled])
  93. return (
  94. <>
  95. <Box className={classes.container}>
  96. <StyledTabs sx={{width:'100%'}} onChange={handleIsActive} value={isActive} aria-label="wrapped label tabs example">
  97. <StyledTab label='Files'/>
  98. <StyledTab label='Media'/>
  99. <StyledTab label='Text'/>
  100. <StyledTab label='Audio'/>
  101. <StyledTab label='Video'/>
  102. </StyledTabs>
  103. </Box>
  104. {isActive === 0 && <FilesList filteredAndSorted={filteredAndSorted} handleScrollToTheMessage={handleScrollToTheMessage} openPinned={openPinned}/>}
  105. {isActive === 1 && <MediaList filteredAndSorted={filteredAndSorted} handleScrollToTheMessage={handleScrollToTheMessage} openPinned={openPinned}/>}
  106. {isActive === 2 && <TextList filteredAndSorted={filteredAndSorted} handleScrollToTheMessage={handleScrollToTheMessage} openPinned={openPinned}/>}
  107. {isActive === 3 && <AudioList filteredAndSorted={filteredAndSorted} handleScrollToTheMessage={handleScrollToTheMessage} openPinned={openPinned}/>}
  108. {isActive === 4 && <VideoList filteredAndSorted={filteredAndSorted} handleScrollToTheMessage={handleScrollToTheMessage} openPinned={openPinned}/>}
  109. </>
  110. )
  111. }
  112. export default ProfileLists