unknown 2 سال پیش
والد
کامیت
564fc07043
24فایلهای تغییر یافته به همراه796 افزوده شده و 152 حذف شده
  1. 1 1
      .eslintcache
  2. 21 0
      package-lock.json
  3. 1 0
      package.json
  4. 77 0
      src/components/AuthPage/Registration/UploadAvatar/index.tsx
  5. 2 3
      src/components/HomePage/LeftBar/ChatsList/index.tsx
  6. 2 3
      src/components/HomePage/LeftBar/ContactsList/index.tsx
  7. 1 2
      src/components/HomePage/LeftBar/SearchLists/ChatListRecent/index.tsx
  8. 50 0
      src/components/HomePage/RightBar/ChatBar/FilesMenu/UploadFile/index.tsx
  9. 21 19
      src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftAudio/index.tsx
  10. 99 0
      src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftFile/index.tsx
  11. 9 9
      src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftImage/index.tsx
  12. 5 5
      src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftText/index.tsx
  13. 102 0
      src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftVideo/index.tsx
  14. 21 16
      src/components/HomePage/RightBar/ChatBar/Messages/MessageRightAudio/index.tsx
  15. 99 0
      src/components/HomePage/RightBar/ChatBar/Messages/MessageRightFile/index.tsx
  16. 9 9
      src/components/HomePage/RightBar/ChatBar/Messages/MessageRightImage/index.tsx
  17. 9 7
      src/components/HomePage/RightBar/ChatBar/Messages/MessageRightText/index.tsx
  18. 99 0
      src/components/HomePage/RightBar/ChatBar/Messages/MessageRightVideo/index.tsx
  19. 35 0
      src/components/HomePage/RightBar/ChatBar/Messages/MessageTime/index.tsx
  20. 83 72
      src/components/HomePage/RightBar/ChatBar/index.tsx
  21. 39 0
      src/components/HomePage/RightBar/HeaderBar/RightLists/SearchList/Search/StaticDatePicker/index.tsx
  22. 1 3
      src/components/HomePage/RightBar/HeaderBar/RightLists/SearchList/index.tsx
  23. 2 3
      src/components/reusableComponents/NotDoneList/index.tsx
  24. 8 0
      src/helpers/index.ts

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
.eslintcache


+ 21 - 0
package-lock.json

@@ -33,6 +33,7 @@
         "lodash.debounce": "^4.0.8",
         "modern-normalize": "^1.0.0",
         "react": "^17.0.1",
+        "react-audio-player": "^0.17.0",
         "react-dom": "^17.0.1",
         "react-dropzone": "^12.0.1",
         "react-js-pagination": "^3.0.3",
@@ -17073,6 +17074,18 @@
         "node": ">=10"
       }
     },
+    "node_modules/react-audio-player": {
+      "version": "0.17.0",
+      "resolved": "https://registry.npmjs.org/react-audio-player/-/react-audio-player-0.17.0.tgz",
+      "integrity": "sha512-aCZgusPxA9HK7rLZcTdhTbBH9l6do9vn3NorgoDZRxRxJlOy9uZWzPaKjd7QdcuP2vXpxGA/61JMnnOEY7NXeA==",
+      "dependencies": {
+        "prop-types": "^15.7.2"
+      },
+      "peerDependencies": {
+        "react": ">=16",
+        "react-dom": ">=16"
+      }
+    },
     "node_modules/react-dev-utils": {
       "version": "11.0.1",
       "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.1.tgz",
@@ -36709,6 +36722,14 @@
         "whatwg-fetch": "^3.4.1"
       }
     },
+    "react-audio-player": {
+      "version": "0.17.0",
+      "resolved": "https://registry.npmjs.org/react-audio-player/-/react-audio-player-0.17.0.tgz",
+      "integrity": "sha512-aCZgusPxA9HK7rLZcTdhTbBH9l6do9vn3NorgoDZRxRxJlOy9uZWzPaKjd7QdcuP2vXpxGA/61JMnnOEY7NXeA==",
+      "requires": {
+        "prop-types": "^15.7.2"
+      }
+    },
     "react-dev-utils": {
       "version": "11.0.1",
       "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.1.tgz",

+ 1 - 0
package.json

@@ -29,6 +29,7 @@
     "lodash.debounce": "^4.0.8",
     "modern-normalize": "^1.0.0",
     "react": "^17.0.1",
+    "react-audio-player": "^0.17.0",
     "react-dom": "^17.0.1",
     "react-dropzone": "^12.0.1",
     "react-js-pagination": "^3.0.3",

+ 77 - 0
src/components/AuthPage/Registration/UploadAvatar/index.tsx

@@ -0,0 +1,77 @@
+import { makeStyles, Typography,InputLabel,ListItem,ListItemText ,ListItemIcon } from '@material-ui/core'
+import FolderIcon from '@mui/icons-material/Folder';
+import { useDropzone } from 'react-dropzone';
+import { useEffect } from 'react';
+
+const useStyles = makeStyles({
+  container: {
+    width: '100%',
+  },
+  dropZone: {
+    display: 'flex',
+    flexDirection: 'column',
+    alignItems: 'center',
+    alignContent: 'center',
+    justifyContent: 'center',
+    width: '100%',
+    padding: '10px',
+    borderRadius: 10,
+    cursor: 'pointer',
+    marginBottom: 20,
+    outline: '2px solid  #959696',
+    '&:hover': {
+      outline: 'dashed  #0040b8',
+    },
+  },
+})
+
+interface IUploadAvatar {
+  setUpload: React.Dispatch<React.SetStateAction<any>>
+}
+const  UploadAvatar = ({ setUpload }: IUploadAvatar) => {
+  
+const {
+    acceptedFiles,
+    getRootProps,
+    getInputProps
+  } = useDropzone({
+    accept: 'image/*',
+  });
+
+    useEffect(() => {
+      setUpload(acceptedFiles[0])
+  }, [setUpload,acceptedFiles])
+
+  const classes = useStyles()
+  const acceptedFileItems = acceptedFiles.map((file: any) => (
+    <ListItem key={file.path}>
+      <ListItemIcon>
+        <FolderIcon/>
+      </ListItemIcon>
+      <ListItemText
+        primary="Avatar uploaded"
+        secondary={`${file.path} -${file.size} bytes`}/>
+   </ListItem>
+  ));
+
+  return (
+    <section className={classes.container} >
+      <div {...getRootProps({ className: classes.dropZone })}>
+        <InputLabel>Drag or drop avatar*</InputLabel>
+        <input {...getInputProps()}/>
+        <img
+          alt='drop zone img'
+          src='https://imagga.com/static/images/upload.svg'
+          width={88}
+          height={72}
+        />
+        <Typography variant="h6" color="initial">image/*</Typography>
+      </div>
+      <aside>
+        <ul>{acceptedFileItems}</ul>
+      </aside>
+    </section>
+  );
+}
+
+export default UploadAvatar

+ 2 - 3
src/components/HomePage/LeftBar/ChatsList/index.tsx

@@ -8,7 +8,6 @@ import Badge from '@mui/material/Badge';
 import VolumeOffIcon from '@mui/icons-material/VolumeOff';
 import { makeStyles, Typography } from '@material-ui/core'
 import { useState,useEffect,useRef } from 'react';
-import shortid from 'shortid';
 import { useSelector, useDispatch } from 'react-redux';
 
 import AlertInfo from '../../../reusableComponents/AlertInfo'
@@ -228,9 +227,9 @@ const ChatsList = () => {
   return total !== '0' ? (
     <List className={classes.list} component="nav"
           aria-label="main mailbox folders">
-      {chats.map(({name, lastName, avatarUrl, updatedAt, color,companionId,mute,seen,total,watched,typing }, i: number) => 
+      {chats.map(({name, lastName, avatarUrl, updatedAt, color,companionId,mute,seen,total,watched,typing,number }, i: number) => 
           <ListItemButton
-          key={shortid.generate()}
+          key={number}
           selected={selectedIndex === i}
           onClick={() => handleListItemClick(i,companionId)}
           >

+ 2 - 3
src/components/HomePage/LeftBar/ContactsList/index.tsx

@@ -5,7 +5,6 @@ import ListItemText from '@mui/material/ListItemText';
 import ListItemIcon from '@mui/material/ListItemIcon';
 import { makeStyles } from '@material-ui/core'
 import { useState,useEffect } from 'react';
-import shortid from 'shortid';
 import { useSelector,useDispatch } from 'react-redux';
 
 import AlertInfo from '../../../reusableComponents/AlertInfo'
@@ -70,9 +69,9 @@ const  ContactsList = ({value} : IContactList) => {
     <List
       className={classes.list} component="nav"
       aria-label="main mailbox folders">
-      {arr.length > 0? arr.map(({name,lastName,avatarUrl,color,createdAt,companionId }, i: number) => 
+      {arr.length > 0? arr.map(({name,lastName,avatarUrl,color,createdAt,companionId,number }, i: number) => 
         <ListItemButton
-          key={shortid.generate()}
+          key={number}
           selected={selectedIndex === i}
           onClick={() => handleListItemClick(i,companionId)}
           >

+ 1 - 2
src/components/HomePage/LeftBar/SearchLists/ChatListRecent/index.tsx

@@ -1,7 +1,6 @@
 import Avatar from '@mui/material/Avatar';
 import Stack from '@mui/material/Stack';
 import { makeStyles, Typography } from '@material-ui/core'
-import shortid from 'shortid';
 
 import {arr} from '../../../../reusableComponents/NotDoneList/arr'
 
@@ -33,7 +32,7 @@ const ChatListRecent = () => {
     const classes = useStyles()
     return (
     <Stack direction="row" className={classes.stack}>
-      {arr && arr.slice(0, 6).map(({ name, avatarUrl,lastName }) => <div key={shortid.generate()} className={classes.stackItem}>
+      {arr && arr.slice(0, 6).map(({ name, avatarUrl,lastName },i:number) => <div key={i} className={classes.stackItem}>
         <Avatar alt={name} src={avatarUrl?avatarUrl:undefined}
               sx={{ background: '#2ab307', width: 54, height: 54 }}>{!avatarUrl&&`${lastName.slice(0,1).toUpperCase()}${lastName.slice(0,1).toUpperCase()}`}</Avatar>
         <Typography variant="h6" className={classes.titleName} >{name.length < 9?name:`${name.slice(0,8)}...`}</Typography>

+ 50 - 0
src/components/HomePage/RightBar/ChatBar/FilesMenu/UploadFile/index.tsx

@@ -0,0 +1,50 @@
+import { makeStyles } from '@material-ui/core'
+import React from 'react';
+import { useDropzone } from 'react-dropzone';
+import { useEffect } from 'react';
+
+const useStyles = makeStyles({
+  container: {
+      width: '100%',
+      position:'relative',
+  },
+    dropZone: {
+        width: '100%',
+        display: 'flex',
+        position:'relative',
+        height: 20,
+        zIndex:10
+  },
+})
+
+interface IUploadFile {
+  children:React.ReactNode,
+  setFile: any,
+  setValue: any,
+  accept: string
+}
+  
+const UploadFile = ({children,setFile,setValue,accept}:IUploadFile) => {
+  const classes = useStyles()
+    const { getRootProps, getInputProps, acceptedFiles } = useDropzone({
+        noDrag: true,
+        accept
+    });
+      useEffect(() => {
+        if (acceptedFiles.slice(-1)[0]) {
+          setValue('')
+          setFile(acceptedFiles.slice(-1)[0])
+        }
+      }, [setFile,setValue, acceptedFiles])
+  
+    return (
+    <div className={classes.container} >
+      {children}
+      <div  {...getRootProps({ className: classes.dropZone })}>
+        <input placeholder='Photo or Video' {...getInputProps()}/>
+      </div>
+    </div>
+  );
+}
+
+export default UploadFile

+ 21 - 19
src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftAudio/index.tsx

@@ -2,9 +2,9 @@ import { makeStyles } from "@material-ui/core/styles";
 import { IconButton } from "@material-ui/core";
 import AudioFileIcon from '@mui/icons-material/AudioFile';
 import FileDownloadIcon from '@mui/icons-material/FileDownload';
-import { useState } from "react";
+import ReactAudioPlayer from 'react-audio-player';
 
-import { timeStamp } from '../../../../../../helpers'
+import { timeStampMessage } from '../../../../../../helpers'
 
 const useStyles = makeStyles({
   container: {
@@ -14,14 +14,13 @@ const useStyles = makeStyles({
       maxWidth: '80%',
       marginBottom:15
   },
-  audioWrapper: {
+  wrapper: {
     position: 'relative',
     display: 'flex',
     justifyContent: 'space-between',
     alignContent: 'center',
     alignItems: 'center',
-    maxWidth: 300,
-    padding: '5px 5px 10px 5px',
+    padding: '12px 5px 12px 5px',
     backgroundColor: '#ffffff',
     borderRadius: 7,
       "&:after": {
@@ -49,24 +48,25 @@ const useStyles = makeStyles({
   },
   bntDownload: {
     backgroundColor: '#ffffff',
-    color:'#54b0fc',
+    color: '#54b0fc',
+    width: 30,
+    height:30,
     '&:hover': {
       backgroundColor: '#54b0fc',
       color:'#deffa9'
     }
   },
-  title: {
-    margin: '0 30px 0 5px',
-    color: '#0e0d0d'
+  player: {
+    margin: '0 5px 0 5px',
+    borderRadius:7
   },
   time: {
       position: "absolute",
       fontSize: ".65em",
       fontWeight:600,
-      bottom: -10,
-      right: -5,
-      color: '#ffffff',
-      backgroundColor: '#3a3a3a',
+      bottom: 0,
+      right: 6,
+      color: '#414141',
       padding: 3,
       borderRadius: 5,
       zIndex:10
@@ -80,20 +80,22 @@ interface IMessageLeftAudio {
 
 const MessageLeftAudio = ({ audioUrl,updatedAt }:IMessageLeftAudio) => {
   const classes = useStyles();
-  const [change, setChange] = useState<boolean>(false)
-  const handleChange = () => setChange(!change)
+
 
   return (
     <div className={classes.container}>
-      <div className={classes.audioWrapper} onMouseEnter={handleChange} onMouseLeave={handleChange}>
-        <AudioFileIcon fontSize='large' style={{ color:'#5f5f5f'}}/>         
-        <span className={classes.title}>Audio File</span>
+      <div className={classes.wrapper}>
+         <AudioFileIcon fontSize='large' style={{ color:'#5f5f5f'}}/>         
+          <ReactAudioPlayer className={classes.player}
+            src={`http://localhost:3000/${audioUrl}`}
+            controls
+          />
         <a href={`http://localhost:3000/${audioUrl}`} target="_blank" rel="noreferrer">
            <IconButton className={classes.bntDownload}  >
              <FileDownloadIcon fontSize='small'/>
            </IconButton>
         </a>
-        <div className={classes.time}>{timeStamp(updatedAt)}</div>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
       </div>
     </div>    
 )};

+ 99 - 0
src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftFile/index.tsx

@@ -0,0 +1,99 @@
+import { makeStyles } from "@material-ui/core/styles";
+import { IconButton } from "@material-ui/core";
+import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
+import FileDownloadIcon from '@mui/icons-material/FileDownload';
+
+import { timeStampMessage } from '../../../../../../helpers'
+
+const useStyles = makeStyles({
+  container: {
+      display: "flex",
+      justifyContent: "flex-end",
+      width:'auto',
+      maxWidth: '80%',
+      marginBottom:15
+  },
+  wrapper: {
+    position: 'relative',
+    display: 'flex',
+    justifyContent: 'space-between',
+    alignContent: 'center',
+    alignItems: 'center',
+    width: 250,
+    padding: '5px 5px 12px 5px',
+    backgroundColor: '#deffa9',
+    borderRadius: 7,
+      "&:after": {
+        content: "''",
+        position: "absolute",
+        width: "0",
+        height: "0",
+        borderBottom: "15px solid #deffa9",
+        borderLeft: "15px solid transparent",
+        borderRight: "15px solid transparent",
+        bottom: "0",
+        right: "-15px"
+      },
+      "&:before": {
+        content: "''",
+        position: "absolute",
+        width: "0",
+        height: "0",
+        borderBottom: "17px solid #deffa9",
+        borderLeft: "16px solid transparent",
+        borderRight: "16px solid transparent",
+        bottom: "0px",
+        right: "-17px"
+      }    
+  },
+  bntDownload: {
+    backgroundColor: '#deffa9',
+    color: '#54b0fc',
+    width: 30,
+    height:30,
+    '&:hover': {
+      backgroundColor: '#54b0fc',
+      color:'#ffffff'
+    }
+  },
+  title: {
+    margin: '0 30px 0 5px',
+    color: '#0e0d0d'
+  },
+  time: {
+      position: "absolute",
+      fontSize: ".65em",
+      fontWeight:600,
+      bottom: 0,
+      right: 6,
+      color: '#414141',
+      padding: 3,
+      borderRadius: 5,
+      zIndex:10
+    },
+});
+
+interface IMessageLeftFile {
+  audioUrl:string,
+  updatedAt: string,
+}
+
+const MessageLeftFile = ({ audioUrl,updatedAt }:IMessageLeftFile) => {
+  const classes = useStyles();
+
+  return (
+    <div className={classes.container}>
+      <div className={classes.wrapper}>
+        <InsertDriveFileIcon fontSize='large' style={{ color:'#5f5f5f'}}/>         
+        <span className={classes.title}>Application File</span>
+        <a href={`http://localhost:3000/${audioUrl}`} target="_blank" rel="noreferrer" download>
+           <IconButton className={classes.bntDownload}  >
+             <FileDownloadIcon fontSize='small'/>
+           </IconButton>
+        </a>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
+      </div>
+    </div>    
+)};
+
+export  default  MessageLeftFile

+ 9 - 9
src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftImage/index.tsx

@@ -1,6 +1,6 @@
 import { makeStyles } from "@material-ui/core/styles";
 
-import { timeStamp } from '../../../../../../helpers'
+import { timeStampMessage } from '../../../../../../helpers'
 
 const useStyles = makeStyles({
     container: {
@@ -10,7 +10,7 @@ const useStyles = makeStyles({
       maxWidth: '80%',
       marginBottom:15
   },
-  imageWrapper: {
+  wrapper: {
     width: 300,
     position:'relative'
   },
@@ -23,12 +23,12 @@ const useStyles = makeStyles({
       position: "absolute",
       fontSize: ".65em",
       fontWeight:600,
-      bottom: -4,
-      right: -4,
+      bottom: 6,
+      right: 6,
       color: '#ffffff',
-      backgroundColor: '#3a3a3a',
-      padding: 3,
-      borderRadius:5
+      padding:'1px 4px 1px 4px',
+      backgroundColor: 'rgba(0, 0, 0, 0.7)',
+      borderRadius: 5,
     },
 });
 
@@ -43,10 +43,10 @@ const MessagesLeftImage = ({imgUrl,updatedAt,color}:IMessagesLeftImage) => {
 
   return (
     <div className={classes.container}>
-      <div className={classes.imageWrapper}>
+      <div className={classes.wrapper}>
         <img className={classes.image} alt='message pic' src={`http://localhost:3000/${imgUrl}`}
         style={{ backgroundColor: imgUrl?'':color }} width='300' height='400' />
-        <div className={classes.time}>{timeStamp(updatedAt)}</div>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
       </div>
     </div>    
 )};

+ 5 - 5
src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftText/index.tsx

@@ -1,7 +1,7 @@
 import { makeStyles } from "@material-ui/core/styles";
 import Avatar from "@material-ui/core/Avatar";
 import ListItemText from '@mui/material/ListItemText';
-import { firstLetter,slicedWord,timeStamp } from '../../../../../../helpers'
+import { firstLetter,slicedWord,timeStampMessage } from '../../../../../../helpers'
 
 const useStyles = makeStyles({
     container: {
@@ -50,14 +50,14 @@ const useStyles = makeStyles({
         left: "-17px"
       }      
     },
-    messageTime: {
+    time: {
       position: "absolute",
       fontSize: ".65em",
       fontWeight:600,
       marginTop: "10px",
-      bottom: "12px",
+      bottom: "10px",
       right: "10px",
-      color: '#4d4c4c'
+      color: '#414141',
     },
 });
 
@@ -87,7 +87,7 @@ const MessageLeftText = ({message,avatarUrl,name,lastName,updatedAt,color}:IMess
           primaryTypographyProps={{color: "#0379af"}}
           secondary={message}
           secondaryTypographyProps={{color: "#0e0d0d"}}/>
-        <div className={classes.messageTime}>{timeStamp(updatedAt)}</div>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
       </div>
     </div>
   );

+ 102 - 0
src/components/HomePage/RightBar/ChatBar/Messages/MessageLeftVideo/index.tsx

@@ -0,0 +1,102 @@
+import { makeStyles } from "@material-ui/core/styles";
+import { IconButton } from "@material-ui/core";
+import VideoFileIcon from '@mui/icons-material/VideoFile';
+import FileDownloadIcon from '@mui/icons-material/FileDownload';
+import { useState } from "react";
+
+import { timeStampMessage } from '../../../../../../helpers'
+
+const useStyles = makeStyles({
+  container: {
+      display: "flex",
+      justifyContent: "flex-start",
+      width:'auto',
+      maxWidth: '80%',
+      marginBottom:15
+  },
+  wrapper: {
+    position: 'relative',
+    display: 'flex',
+    justifyContent: 'space-between',
+    alignContent: 'center',
+    alignItems: 'center',
+    width: 250,
+    padding: '5px 5px 12px 5px',
+    backgroundColor: '#ffffff',
+    borderRadius: 7,
+      "&:after": {
+        content: "''",
+        position: "absolute",
+        width: "0",
+        height: "0",
+        borderBottom: "15px solid #ffffff",
+        borderLeft: "15px solid transparent",
+        borderRight: "15px solid transparent",
+        bottom: '0px',
+        left: "-15px"
+      },
+      "&:before": {
+        content: "''",
+        position: "absolute",
+        width: "0",
+        height: "0",
+        borderBottom: "17px solid #ffffff",
+        borderLeft: "16px solid transparent",
+        borderRight: "16px solid transparent",
+        bottom: "0px",
+        left: "-17px"
+      }    
+  },
+  bntDownload: {
+    backgroundColor: '#ffffff',
+    color: '#54b0fc',
+    width: 30,
+    height:30,
+    '&:hover': {
+      backgroundColor: '#54b0fc',
+      color:'#deffa9'
+    }
+  },
+  title: {
+    margin: '0 30px 0 5px',
+    color: '#0e0d0d'
+  },
+  time: {
+      position: "absolute",
+      fontSize: ".65em",
+      fontWeight:600,
+      bottom: 0,
+      right: 6,
+      color: '#414141',
+      padding: 3,
+      borderRadius: 5,
+      zIndex:10
+    },
+});
+
+interface IMessageLeftVideo {
+  audioUrl:string,
+  updatedAt: string,
+}
+
+const MessageLeftVideo = ({ audioUrl,updatedAt }:IMessageLeftVideo) => {
+  const classes = useStyles();
+  const [change, setChange] = useState<boolean>(false)
+  const handleChange = () => setChange(!change)
+
+  return (
+    <div className={classes.container}>
+      <div className={classes.wrapper} onMouseEnter={handleChange} onMouseLeave={handleChange}>
+        <VideoFileIcon fontSize='large' style={{ color:'#5f5f5f'}}/>         
+        <span className={classes.title}>Video File</span>
+        <a href={`http://localhost:3000/${audioUrl}`} target="_blank" rel="noreferrer">
+           <IconButton className={classes.bntDownload}  >
+             <FileDownloadIcon fontSize='small'/>
+           </IconButton>
+        </a>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
+      </div>
+    </div>    
+)};
+
+export  default  MessageLeftVideo

+ 21 - 16
src/components/HomePage/RightBar/ChatBar/Messages/MessageRightAudio/index.tsx

@@ -2,8 +2,9 @@ import { makeStyles } from "@material-ui/core/styles";
 import { IconButton } from "@material-ui/core";
 import AudioFileIcon from '@mui/icons-material/AudioFile';
 import FileDownloadIcon from '@mui/icons-material/FileDownload';
+import ReactAudioPlayer from 'react-audio-player';
 
-import { timeStamp } from '../../../../../../helpers'
+import { timeStampMessage } from '../../../../../../helpers'
 
 const useStyles = makeStyles({
   container: {
@@ -13,14 +14,13 @@ const useStyles = makeStyles({
       maxWidth: '80%',
       marginBottom:15
   },
-  audioWrapper: {
+  wrapper: {
     position: 'relative',
     display: 'flex',
     justifyContent: 'space-between',
     alignContent: 'center',
     alignItems: 'center',
-    maxWidth: 300,
-    padding: '5px 5px 10px 5px',
+    padding: '12px 5px 12px 5px',
     backgroundColor: '#deffa9',
     borderRadius: 7,
       "&:after": {
@@ -48,24 +48,25 @@ const useStyles = makeStyles({
   },
   bntDownload: {
     backgroundColor: '#deffa9',
-    color:'#54b0fc',
+    color: '#54b0fc',
+    width: 30,
+    height:30,
     '&:hover': {
       backgroundColor: '#54b0fc',
       color:'#ffffff'
     }
   },
-  title: {
-    margin: '0 30px 0 5px',
-    color: '#0e0d0d'
+  player: {
+    margin: '0 5px 0 5px',
+    borderRadius: 7,
   },
   time: {
       position: "absolute",
       fontSize: ".65em",
       fontWeight:600,
-      bottom: -10,
-      left: -5,
-      color: '#ffffff',
-      backgroundColor: '#3a3a3a',
+      bottom: 0,
+      right: 6,
+      color: '#414141',
       padding: 3,
       borderRadius: 5,
       zIndex:10
@@ -80,17 +81,21 @@ interface IMessageRightAudio {
 const MessageRightAudio = ({ audioUrl,updatedAt }:IMessageRightAudio) => {
   const classes = useStyles();
 
+
   return (
     <div className={classes.container}>
-      <div className={classes.audioWrapper}>
+      <div className={classes.wrapper}>
         <AudioFileIcon fontSize='large' style={{ color:'#5f5f5f'}}/>         
-        <span className={classes.title}>Audio File</span>
+        <ReactAudioPlayer className={classes.player} 
+          src={`http://localhost:3000/${audioUrl}`}
+          controls
+         />
         <a href={`http://localhost:3000/${audioUrl}`} target="_blank" rel="noreferrer" download>
            <IconButton className={classes.bntDownload}  >
-             <FileDownloadIcon fontSize='small'/>
+             <FileDownloadIcon fontSize='medium'/>
            </IconButton>
         </a>
-        <div className={classes.time}>{timeStamp(updatedAt)}</div>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
       </div>
     </div>    
 )};

+ 99 - 0
src/components/HomePage/RightBar/ChatBar/Messages/MessageRightFile/index.tsx

@@ -0,0 +1,99 @@
+import { makeStyles } from "@material-ui/core/styles";
+import { IconButton } from "@material-ui/core";
+import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
+import FileDownloadIcon from '@mui/icons-material/FileDownload';
+
+import { timeStampMessage } from '../../../../../../helpers'
+
+const useStyles = makeStyles({
+  container: {
+      display: "flex",
+      justifyContent: "flex-end",
+      width:'auto',
+      maxWidth: '80%',
+      marginBottom:15
+  },
+  wrapper: {
+    position: 'relative',
+    display: 'flex',
+    justifyContent: 'space-between',
+    alignContent: 'center',
+    alignItems: 'center',
+    width: 250,
+    padding: '5px 5px 12px 5px',
+    backgroundColor: '#deffa9',
+    borderRadius: 7,
+      "&:after": {
+        content: "''",
+        position: "absolute",
+        width: "0",
+        height: "0",
+        borderBottom: "15px solid #deffa9",
+        borderLeft: "15px solid transparent",
+        borderRight: "15px solid transparent",
+        bottom: "0",
+        right: "-15px"
+      },
+      "&:before": {
+        content: "''",
+        position: "absolute",
+        width: "0",
+        height: "0",
+        borderBottom: "17px solid #deffa9",
+        borderLeft: "16px solid transparent",
+        borderRight: "16px solid transparent",
+        bottom: "0px",
+        right: "-17px"
+      }    
+  },
+  bntDownload: {
+    backgroundColor: '#deffa9',
+    color: '#54b0fc',
+    width: 30,
+    height:30,
+    '&:hover': {
+      backgroundColor: '#54b0fc',
+      color:'#ffffff'
+    }
+  },
+  title: {
+    margin: '0 30px 0 5px',
+    color: '#0e0d0d'
+  },
+  time: {
+      position: "absolute",
+      fontSize: ".65em",
+      fontWeight:600,
+      bottom: 0,
+      right: 6,
+      color: '#414141',
+      padding: 3,
+      borderRadius: 5,
+      zIndex:10
+    },
+});
+
+interface IMessageRightFile {
+  audioUrl:string,
+  updatedAt: string,
+}
+
+const MessageRightFile = ({ audioUrl,updatedAt }:IMessageRightFile) => {
+  const classes = useStyles();
+
+  return (
+    <div className={classes.container}>
+      <div className={classes.wrapper}>
+        <InsertDriveFileIcon fontSize='large' style={{ color:'#5f5f5f'}}/>         
+        <span className={classes.title}>Application File</span>
+        <a href={`http://localhost:3000/${audioUrl}`} target="_blank" rel="noreferrer" download>
+           <IconButton className={classes.bntDownload}  >
+             <FileDownloadIcon fontSize='small'/>
+           </IconButton>
+        </a>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
+      </div>
+    </div>    
+)};
+
+export  default  MessageRightFile

+ 9 - 9
src/components/HomePage/RightBar/ChatBar/Messages/MessageRightImage/index.tsx

@@ -1,6 +1,6 @@
 import { makeStyles } from "@material-ui/core/styles";
 
-import { timeStamp } from '../../../../../../helpers'
+import { timeStampMessage } from '../../../../../../helpers'
 
 const useStyles = makeStyles({
     container: {
@@ -10,7 +10,7 @@ const useStyles = makeStyles({
       maxWidth: '80%',
       marginBottom:15
   },
-  imageWrapper: {
+  wrapper: {
     width: 300,
     position:'relative'
   },
@@ -23,12 +23,12 @@ const useStyles = makeStyles({
       position: "absolute",
       fontSize: ".65em",
       fontWeight:600,
-      bottom: -4,
-      right: -4,
+      bottom: 6,
+      right: 6,
       color: '#ffffff',
-      backgroundColor: '#3a3a3a',
-      padding: 3,
-      borderRadius:5
+      padding:'1px 4px 1px 4px',
+      backgroundColor: 'rgba(0, 0, 0, 0.7)',
+      borderRadius: 5,
     },
 });
 
@@ -43,10 +43,10 @@ const MessageRightImage = ({imgUrl,updatedAt,color}:IMessageRightImage) => {
 
   return (
     <div className={classes.container}>
-      <div className={classes.imageWrapper}>
+      <div className={classes.wrapper}>
         <img className={classes.image} alt='message pic' src={`http://localhost:3000/${imgUrl}`}
         style={{ backgroundColor: imgUrl?'':color }} width='300' height='400' />
-        <div className={classes.time}>{timeStamp(updatedAt)}</div>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
       </div>
     </div>    
 )};

+ 9 - 7
src/components/HomePage/RightBar/ChatBar/Messages/MessageRightText/index.tsx

@@ -1,7 +1,7 @@
 import { makeStyles } from "@material-ui/core/styles";
 import Avatar from "@material-ui/core/Avatar";
 import ListItemText from '@mui/material/ListItemText';
-import { firstLetter, slicedWord, timeStamp } from '../../../../../../helpers'
+import { firstLetter, slicedWord, timeStampMessage } from '../../../../../../helpers'
 
 const useStyles = makeStyles({
     container: {
@@ -51,14 +51,16 @@ const useStyles = makeStyles({
         right: "-17px"
       }
     },
-    messageTime: {
+  time: {
       position: "absolute",
       fontSize: ".65em",
       fontWeight:600,
-      marginTop: "10px",
-      bottom: "12px",
-      left: 10,
-      color: '#4d4c4c',
+      bottom: 7,
+      right: 46,
+      color: '#414141',
+      padding: 3,
+      borderRadius: 5,
+      zIndex:10
     },
 });
 
@@ -83,7 +85,7 @@ const MessageRightText = ({message,avatarUrl,name,lastName,updatedAt,color}:IMes
           primaryTypographyProps={{color: "#42aee0"}}
           secondary={message}
           secondaryTypographyProps={{ color: "#0e0d0d" }} />
-        <div className={classes.messageTime}>{timeStamp(updatedAt)}</div>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
        <Avatar
           alt='avatar'
           src={avatarUrl ? `http://localhost:3000/${avatarUrl}` : undefined}

+ 99 - 0
src/components/HomePage/RightBar/ChatBar/Messages/MessageRightVideo/index.tsx

@@ -0,0 +1,99 @@
+import { makeStyles } from "@material-ui/core/styles";
+import { IconButton } from "@material-ui/core";
+import VideoFileIcon from '@mui/icons-material/VideoFile';
+import FileDownloadIcon from '@mui/icons-material/FileDownload';
+
+import { timeStampMessage } from '../../../../../../helpers'
+
+const useStyles = makeStyles({
+  container: {
+      display: "flex",
+      justifyContent: "flex-end",
+      width:'auto',
+      maxWidth: '80%',
+      marginBottom:15
+  },
+  wrapper: {
+    position: 'relative',
+    display: 'flex',
+    justifyContent: 'space-between',
+    alignContent: 'center',
+    alignItems: 'center',
+    width: 250,
+    padding: '5px 5px 12px 5px',
+    backgroundColor: '#deffa9',
+    borderRadius: 7,
+      "&:after": {
+        content: "''",
+        position: "absolute",
+        width: "0",
+        height: "0",
+        borderBottom: "15px solid #deffa9",
+        borderLeft: "15px solid transparent",
+        borderRight: "15px solid transparent",
+        bottom: "0",
+        right: "-15px"
+      },
+      "&:before": {
+        content: "''",
+        position: "absolute",
+        width: "0",
+        height: "0",
+        borderBottom: "17px solid #deffa9",
+        borderLeft: "16px solid transparent",
+        borderRight: "16px solid transparent",
+        bottom: "0px",
+        right: "-17px"
+      }    
+  },
+  bntDownload: {
+    backgroundColor: '#deffa9',
+    color: '#54b0fc',
+    width: 30,
+    height:30,
+    '&:hover': {
+      backgroundColor: '#54b0fc',
+      color:'#ffffff'
+    }
+  },
+  title: {
+    margin: '0 30px 0 5px',
+    color: '#0e0d0d'
+  },
+  time: {
+      position: "absolute",
+      fontSize: ".65em",
+      fontWeight:600,
+      bottom: 0,
+      right: 6,
+      color: '#414141',
+      padding: 3,
+      borderRadius: 5,
+      zIndex:10
+    },
+});
+
+interface IMessageRightVideo {
+  audioUrl:string,
+  updatedAt: string,
+}
+
+const MessageRightVideo = ({ audioUrl,updatedAt }:IMessageRightVideo) => {
+  const classes = useStyles();
+
+  return (
+    <div className={classes.container}>
+      <div className={classes.wrapper}>
+        <VideoFileIcon fontSize='large' style={{ color:'#5f5f5f'}}/>         
+        <span className={classes.title}>Video File</span>
+        <a href={`http://localhost:3000/${audioUrl}`} target="_blank" rel="noreferrer" download>
+           <IconButton className={classes.bntDownload}  >
+             <FileDownloadIcon fontSize='small'/>
+           </IconButton>
+        </a>
+        <div className={classes.time}>{timeStampMessage(updatedAt)}</div>
+      </div>
+    </div>    
+)};
+
+export  default  MessageRightVideo

+ 35 - 0
src/components/HomePage/RightBar/ChatBar/Messages/MessageTime/index.tsx

@@ -0,0 +1,35 @@
+import { makeStyles } from "@material-ui/core/styles";
+
+const useStyles = makeStyles({
+  container: {
+      display: "flex",
+      justifyContent: "center",
+      width:'auto',
+      maxWidth: '80%',
+      marginBottom:10
+  },
+  wrapper: {
+    textAlign: 'center',
+    padding: '1px 10px 3px 10px',
+    backgroundColor: 'rgba(104, 105, 104, 0.8)',
+    color:'#ffffff',
+    borderRadius: 7,
+    fontSize: ".85em",
+    fontWeight:600,
+  },
+});
+
+interface IMessageTime {
+  message:string,
+}
+
+const MessageTime = ({ message }:IMessageTime) => {
+  const classes = useStyles();
+
+  return (
+    <div className={classes.container}>
+      <span className={classes.wrapper}>{message}</span>
+    </div>    
+)};
+
+export  default  MessageTime

+ 83 - 72
src/components/HomePage/RightBar/ChatBar/index.tsx

@@ -1,7 +1,6 @@
 import { makeStyles } from "@material-ui/core/styles";
 import { useState, useEffect, useRef, useCallback } from "react";
 import { useSelector,useDispatch } from "react-redux";
-import shortid from 'shortid';
 
 import SendMessage from "./SendMessage";
 import MessageLeftText from './Messages/MessageLeftText'
@@ -14,6 +13,7 @@ import MessageRightImage from './Messages/MessageRightImage'
 import MessageRightAudio from './Messages/MessageRightAudio'
 import MessageRightVideo from './Messages/MessageRightVideo'
 import MessageRightFile from "./Messages/MessageRightFile";
+import MessageTime from "./Messages/MessageTime";
 import AlertInfo from "../../../reusableComponents/AlertInfo";
 import { getMessagesMemo } from '../../../../redux/messages/selector'
 import { getNumber } from '../../../../redux/authorization/selector'
@@ -22,6 +22,7 @@ import { getScroll } from '../../../../redux/control/selector'
 import { actionScroll } from '../../../../redux/control/action'
 import { asyncGetMessagesById } from '../../../../redux/messages/operations'
 import { seenChat } from "../../../../api-data";
+import { timeStampFilter } from "../../../../helpers";
 const debounce = require('lodash.debounce');
 
 const useStyles = makeStyles({   
@@ -53,6 +54,7 @@ const ChatBar = () => {
   const scroll = useSelector(getScroll)
   const [isArrow, setIsArrow] = useState<boolean>(false)
   const divRef = useRef<any | null>(null)
+  let time:any
   const handleScrollTo = () => {
      divRef.current&&divRef.current.scrollTo({
      top: divRef.current.scrollHeight,
@@ -83,79 +85,88 @@ const ChatBar = () => {
   return (
       <div ref={divRef} className={classes.container} onScroll={debouncedHandleScroll}>
         <div  className={classes.messagesBody}>
-        {messages.length > 0 ? messages.map(({message,avatarUrl,name,lastName,color,updatedAt,number,type},i:number) => {
+        {messages.length > 0 ? messages.map(({ message, avatarUrl, name, lastName, color, updatedAt,createdAt, number, type }) => {
+          let isTime
+          if (!time) {
+            isTime = true
+            time = updatedAt
+          } else if (timeStampFilter(time) !== timeStampFilter(updatedAt)) {
+            time = updatedAt
+            isTime = true
+          }
           if (number !== userNumber) {
-            if(type === 'text') return (
-            <MessageLeftText
-            key={shortid.generate()}
-            message={message}
-            updatedAt={updatedAt}
-            avatarUrl={avatarUrl}
-            name={name}
-            lastName={lastName}
-            color={color}
-              />)
-            if(type === 'image') return (
-            <MessageLeftImage
-            key={shortid.generate()}    
-            imgUrl={message}
-            updatedAt={updatedAt}
-            color={color} 
-              />)
-            if(type === 'audio') return (
-            <MessageLeftAudio
-            key={shortid.generate()}    
-            audioUrl={message}
-            updatedAt={updatedAt}  
-              />)
-            if(type === 'video') return (
-            <MessageLeftVideo
-            key={shortid.generate()}    
-            audioUrl={message}
-            updatedAt={updatedAt}  
-              />)
-            if(type === 'file') return (
-            <MessageLeftFile
-            key={shortid.generate()}    
-            audioUrl={message}
-            updatedAt={updatedAt}  
-              />)             
+            if (type === 'text') return (<div key={createdAt}>
+              {isTime&&<MessageTime  message={timeStampFilter(updatedAt)}/>}
+               <MessageLeftText
+               message={message}
+               updatedAt={updatedAt}
+               avatarUrl={avatarUrl}
+               name={name}
+               lastName={lastName}
+               color={color}
+                 /></div>)
+            if (type === 'image') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                <MessageLeftImage   
+                imgUrl={message}
+                updatedAt={updatedAt}
+                color={color} 
+                  /></div>)
+            if (type === 'audio') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                <MessageLeftAudio    
+                audioUrl={message}
+                updatedAt={updatedAt}  
+                  /></div>)
+            if (type === 'video') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                <MessageLeftVideo    
+                audioUrl={message}
+                updatedAt={updatedAt}  
+                  /></div>)
+            if (type === 'file') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                <MessageLeftFile   
+                audioUrl={message}
+                updatedAt={updatedAt}  
+                  /></div>)             
           } else {
-            if(type === 'text') return (
-            <MessageRightText
-            key={shortid.generate()}    
-            message={message}
-            updatedAt={updatedAt}
-            avatarUrl={avatarUrl}
-            name={name}
-            lastName={lastName}
-            color={color}    
-              />)
-            if(type === 'image') return (
-            <MessageRightImage
-            key={shortid.generate()}    
-            imgUrl={message}
-            updatedAt={updatedAt}
-            color={color}    
-              />)
-            if(type === 'audio') return (
-            <MessageRightAudio
-            key={shortid.generate()}    
-            audioUrl={message}
-            updatedAt={updatedAt} 
-              />)
-            if(type === 'video') return (
-            <MessageRightVideo
-            key={shortid.generate()}    
-            audioUrl={message}
-            updatedAt={updatedAt} 
-              />)
-            if(type === 'file') return (
-            <MessageRightFile
-            key={shortid.generate()}    
-            audioUrl={message}
-            updatedAt={updatedAt} 
-              />)            
+            if (type === 'text') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                <MessageRightText   
+                message={message}
+                updatedAt={updatedAt}
+                avatarUrl={avatarUrl}
+                name={name}
+                lastName={lastName}
+                color={color}    
+                  /></div>)
+            if (type === 'image') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                <MessageRightImage   
+                imgUrl={message}
+                updatedAt={updatedAt}
+                color={color}    
+                  /></div>)
+            if (type === 'audio') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                <MessageRightAudio    
+                audioUrl={message}
+                updatedAt={updatedAt} 
+                  /></div>)
+            if (type === 'video') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                 <MessageRightVideo  
+                 audioUrl={message}
+                 updatedAt={updatedAt} 
+                   /></div>)
+            if (type === 'file') return (<div key={createdAt}>
+              {isTime&&<MessageTime message={timeStampFilter(updatedAt)}/>}
+                 <MessageRightFile
+                 key={updatedAt}    
+                 audioUrl={message}
+                 updatedAt={updatedAt} 
+                   /></div>)            
           }
         }) : <AlertInfo name='You do not have messages yet!' />}
       </div>         

+ 39 - 0
src/components/HomePage/RightBar/HeaderBar/RightLists/SearchList/Search/StaticDatePicker/index.tsx

@@ -0,0 +1,39 @@
+import { DatePicker } from "@material-ui/pickers";
+import { makeStyles } from '@material-ui/core'
+
+interface IStaticDatePicker {
+   disabled:boolean,
+   date: Date,
+   changeDate: React.Dispatch<React.SetStateAction<any>>,
+   handleOnOpen: () => void
+}
+
+const useStyles = makeStyles({
+    container: {
+        position: 'absolute',
+        left: 1369,
+        top:1,
+        width: 30,
+        cursor: 'pointer',
+    }
+})
+
+const StaticDatePicker = ({ disabled, date, changeDate,handleOnOpen }: IStaticDatePicker) => {
+    const classes = useStyles()
+return (
+    <DatePicker
+        disabled={disabled}
+        className={classes.container}
+        inputVariant='outlined'
+        orientation="portrait"
+        variant="dialog"
+        openTo="date"
+        autoOk
+        value={date}
+        onOpen={handleOnOpen}
+        onChange={changeDate}
+        />
+  );
+};
+
+export default StaticDatePicker;

+ 1 - 3
src/components/HomePage/RightBar/HeaderBar/RightLists/SearchList/index.tsx

@@ -3,7 +3,6 @@ import { useSelector } from 'react-redux'
 import React, { useState } from 'react'
 import List from '@mui/material/List';
 import ListItem from '@mui/material/ListItem';
-import Divider from '@mui/material/Divider';
 import ListItemText from '@mui/material/ListItemText';
 import ListItemAvatar from '@mui/material/ListItemAvatar';
 import Avatar from '@mui/material/Avatar';
@@ -12,7 +11,6 @@ import Search from './Search'
 import AlertInfo from "../../../../../reusableComponents/AlertInfo";
 import { getMessages } from '../../../../../../redux/messages/selector'
 import { timeStamp,timeStampFilter,firstLetter,slicedWord } from '../../../../../../helpers'
-import shortid from 'shortid';
 
 
 const useStyles = makeStyles({
@@ -59,7 +57,7 @@ return (
       {messages.length > 0 ? arr.length > 0 ?
         <List sx={{ width: '100%' }}>
           {arr.map(({ name, lastName, avatarUrl, color, message, createdAt }) => 
-            <ListItem alignItems="flex-start" className={classes.listItem} key={shortid.generate()}
+            <ListItem alignItems="flex-start" className={classes.listItem} key={createdAt}
               onClick={() => console.log('clicked message in rightList')}>
                    <ListItemAvatar>
                       <Avatar alt={name} src={avatarUrl?`http://localhost:3000/${avatarUrl}`:undefined}

+ 2 - 3
src/components/reusableComponents/NotDoneList/index.tsx

@@ -1,14 +1,13 @@
-import shortid from 'shortid';
 import Alert from '@mui/material/Alert';
 import AlertTitle from '@mui/material/AlertTitle';
 import Stack from '@mui/material/Stack';
 import { arr } from './arr'
 
-const NotDoneList = ({ name }: { name: string }) => {
+const NotDoneList = ({ name }: { name: string },i:number) => {
 return (
   <Stack sx={{ width: '100%' }} spacing={2}>
     {arr.map(() => 
-      <Alert key={shortid.generate()} severity="warning">
+      <Alert key={i} severity="warning">
         <AlertTitle>Warning</AlertTitle>
         The component has not done yet {name}!
       </Alert>)}

+ 8 - 0
src/helpers/index.ts

@@ -15,6 +15,13 @@ const timeStamp = (updatedAt: string) => new Date(updatedAt).toLocaleString("en-
     minute: '2-digit',
 })
 
+const timeStampMessage = (updatedAt: string) => new Date(updatedAt).toLocaleString('en-GB',{
+    timeZone: 'UTC',
+    hour: 'numeric',
+    minute: '2-digit',
+})
+
+
 const timeStampFilter = (updatedAt: string) => new Date(updatedAt).toLocaleString("en-US", {
     year:'numeric',
     month: 'short',
@@ -77,6 +84,7 @@ export {
   firstLetter,
   slicedWord,
   timeStamp,
+  timeStampMessage,
   timeStampFilter,
   playNotification,
   notification,