Browse Source

work on pinned messages

unknown 1 year ago
parent
commit
5223dc4116

File diff suppressed because it is too large
+ 1 - 1
.eslintcache


+ 14 - 4
src/components/HomePage/CentralBar/ChatBar/Messages/MessageLeftAudio/index.tsx

@@ -14,6 +14,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
@@ -244,7 +245,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -293,7 +300,8 @@ const MessageLeftAudio = ({ url,createdAt,fullType,caption,emoji,emojiCompanion,
   
   const handleEmojiMenu = ({ target }: any): void => {
     const idEmoji = target.id
-    if (idEmoji === emoji) {updateMessageById(_id,'')  
+    if (idEmoji === emoji) {
+      updateMessageById(_id, '')
     } else updateMessageById(_id,idEmoji)
   } 
 
@@ -331,8 +339,10 @@ const MessageLeftAudio = ({ url,createdAt,fullType,caption,emoji,emojiCompanion,
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem> 
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageLeftFile/index.tsx

@@ -13,6 +13,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
 import { timeStampMessage,copied,emojisArr } from '../../../../../../helpers'
@@ -261,7 +262,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -359,8 +366,10 @@ const MessageLeftFile = ({ url,createdAt,type,caption,emoji,emojiCompanion,pinne
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>       
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageLeftImage/index.tsx

@@ -14,6 +14,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
 import { timeStampMessage, timeStampEU,handleDownload,copied,emojisArr } from '../../../../../../helpers'
@@ -292,7 +293,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -390,8 +397,10 @@ const MessagesLeftImage = ({url,createdAt,color,fullType,caption,emoji,emojiComp
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>         
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageLeftText/index.tsx

@@ -11,6 +11,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
 import { firstLetter,slicedWord,timeStampMessage,copied,emojisArr } from '../../../../../../helpers'
@@ -237,7 +238,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -328,8 +335,10 @@ const MessageLeftText = ({message,name,lastName,createdAt,caption,emoji,emojiCom
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>          
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageLeftVideo/index.tsx

@@ -13,6 +13,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
 import { timeStampMessage,handleDownload,copied,emojisArr } from '../../../../../../helpers'
@@ -248,7 +249,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -333,8 +340,10 @@ const MessageLeftVideo = ({ url,createdAt,fullType,caption,emoji,emojiCompanion,
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>          
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageRightAudio/index.tsx

@@ -14,6 +14,7 @@ import Checkbox from '@mui/material/Checkbox';
 import Menu from '@mui/material/Menu';
 import MenuItem from '@mui/material/MenuItem';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
 import { timeStampMessage,handleDownload,copied,emojisArr } from '../../../../../../helpers'
@@ -243,7 +244,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -330,8 +337,10 @@ const MessageRightAudio = ({ url,createdAt,fullType,caption,_id,emoji,emojiCompa
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>           
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageRightFile/index.tsx

@@ -13,6 +13,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
 import { timeStampMessage,copied,emojisArr } from '../../../../../../helpers'
@@ -261,7 +262,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -361,8 +368,10 @@ const MessageRightFile = ({ url,createdAt,type,caption,emoji,emojiCompanion,pinn
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>           
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageRightImage/index.tsx

@@ -14,6 +14,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
 import { timeStampMessage, timeStampEU,handleDownload,copied,emojisArr } from '../../../../../../helpers'
@@ -292,7 +293,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -389,8 +396,10 @@ const MessageRightImage = ({url,createdAt,color,fullType,caption,emoji,emojiComp
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>           
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageRightText/index.tsx

@@ -11,6 +11,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { firstLetter, slicedWord, timeStampMessage, copied,emojisArr } from '../../../../../../helpers'
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
@@ -237,7 +238,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -326,8 +333,10 @@ const MessageRightText = ({message,name,lastName,createdAt,caption,emoji,emojiCo
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>           
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 12 - 3
src/components/HomePage/CentralBar/ChatBar/Messages/MessageRightVideo/index.tsx

@@ -13,6 +13,7 @@ import Divider from '@mui/material/Divider';
 import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import Checkbox from '@mui/material/Checkbox';
 import PushPinIcon from '@mui/icons-material/PushPin';
+import CloseIcon from '@mui/icons-material/Close';
 import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { removeMessageById,updateMessageById,pinMessageById } from "../../../../../../api-data";
 import { timeStampMessage,handleDownload,copied,emojisArr } from '../../../../../../helpers'
@@ -249,7 +250,13 @@ const useStyles = makeStyles({
 	  '50%': { transform: 'translateY(-4rem) scale(1.5) rotateY(90deg)'},
 	  '80%': {opacity: 0},
 	  '100%': {transform: 'translateY(-8rem) scale(2) rotateY(180deg)',opacity: 0},
-   },  
+  },
+  iconClose: {
+    '&:hover': {
+      transform: 'rotate(180deg)',
+      transition: 'all 250ms ease-out ',
+    }
+  },  
 });
 
 const label = { inputProps: { 'aria-label': 'Checkbox demo' } };
@@ -333,8 +340,10 @@ const MessageRightVideo = ({ url,createdAt,fullType,caption,emoji,emojiCompanion
           pinMessageById(_id, !pinned)
           handleClose(undefined)
         }}>
-            <PushPinIcon />
-             {!pinned?'Pin message' : 'Unpin message'}
+            {pinned ?
+              <CloseIcon className={classes.iconClose} /> :
+              <PushPinIcon />}
+             {pinned?'Unpin message':'Pin message'}
         </MenuItem>            
         <MenuItem onClick={() => {
             handleSelected(_id)

+ 17 - 17
src/components/HomePage/CentralBar/ChatBar/index.tsx

@@ -1,5 +1,5 @@
 import { makeStyles } from "@material-ui/core/styles";
-import { useState, useEffect, useRef, useCallback } from "react";
+import { useState, useEffect, useCallback } from "react";
 import { useSelector,useDispatch } from "react-redux";
 
 import ArrowBack from "./ArrowBack";
@@ -75,13 +75,14 @@ const useStyles = makeStyles({
 });
 
 interface IChatBar {
+  divRef: any | null,
   selectedArr: string[] | [],
   setSelectedArr: React.Dispatch<React.SetStateAction<string[] | []>>,
   isSomeSelected: boolean,
   setIsSomeSelected: React.Dispatch<React.SetStateAction<boolean>>,
 }
 
-const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:IChatBar) => {
+const ChatBar = ({divRef,selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:IChatBar) => {
   const classes = useStyles();
   const dispatch = useDispatch()
   const messages = useSelector(getMessagesMemo)
@@ -90,7 +91,6 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
   const scrollChat = useSelector(getScrollChat)
   const [isArrow, setIsArrow] = useState<boolean>(false)
   const [isNew, setIsNew] = useState<{new:number,mute:boolean}>({new:0,mute:false})
-  const divRef = useRef<any | null>(null)
   let time: any
   const isSelected = (_id: string) => selectedArr.some((el: string) => el === _id)  
   const handleSelected = (_id: string) => {
@@ -99,12 +99,12 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
       setSelectedArr(selectedArr.filter((el:string) => el !== _id))
      else setSelectedArr([...selectedArr,_id])
   }
-  const handleScrollTo = () => {
+  const handleScrollTo = useCallback(() => {
      divRef.current&&divRef.current.scrollTo({
      top: divRef.current.scrollHeight,
      behavior: 'smooth'
      })
-  }
+  },[divRef])
 
   const handleScroll = useCallback(({ target:{scrollHeight,scrollTop,clientHeight}}: any) => {
     const different = scrollHeight - Math.floor(scrollTop)
@@ -120,7 +120,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
       dispatch(asyncGetMessagesById(companionId, handleScrollTo))
       dispatch(actionScrollChat(false))
     }
-  }, [dispatch, scrollChat, companionId])
+  }, [dispatch,handleScrollTo, scrollChat, companionId])
   
   useEffect(() => {
     const handleReset = () => {
@@ -145,7 +145,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
     }
     const idInterval = setInterval(handleReset, refreshAppTime);
     return () => clearInterval(idInterval);
-  }, [total, seen, companionId]);
+  }, [total, seen, divRef,companionId]);
 
   return (
     <div className={classes.container} >
@@ -165,7 +165,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
           }
           const url = `${prodAwsS3}/${message}`
           if (number !== userNumber) {
-            if (type === 'text') return (<div key={createdAt}>
+            if (type === 'text') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}> 
               {isTime&&<MessageTime  message={timeStampFilter(createdAt)}/>}
                <MessageLeftText
                message={message}
@@ -181,7 +181,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                handleSelected={handleSelected}
                _id={_id}
                  /></div>)
-            if (type === 'image') return (<div key={createdAt}>
+            if (type === 'image') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageLeftImage   
                 url={url}
@@ -197,7 +197,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                 handleSelected={handleSelected}                
                 _id={_id}
                   /></div>)
-            if (type === 'audio') return (<div key={createdAt}>
+            if (type === 'audio') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageLeftAudio    
                 url={url}
@@ -212,7 +212,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                 handleSelected={handleSelected}                
                 _id={_id}
                   /></div>)
-            if (type === 'video') return (<div key={createdAt}>
+            if (type === 'video') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageLeftVideo    
                 url={url}
@@ -227,7 +227,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                 handleSelected={handleSelected}              
                 _id={_id}
                   /></div>)
-            if (type) return (<div key={createdAt}>
+            if (type) return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageLeftFile   
                 url={url}
@@ -243,7 +243,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                 _id={_id}
                   /></div>)             
           } else {
-            if (type === 'text') return (<div key={createdAt}>
+            if (type === 'text') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageRightText   
                 message={message}
@@ -259,7 +259,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                 handleSelected={handleSelected}                
                 _id={_id}
                   /></div>)
-            if (type === 'image') return (<div key={createdAt}>
+            if (type === 'image') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageRightImage   
                 url={url}
@@ -275,7 +275,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                 handleSelected={handleSelected}
                 _id={_id}
                   /></div>)
-            if (type === 'audio') return (<div key={createdAt}>
+            if (type === 'audio') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                 <MessageRightAudio    
                 url={url}
@@ -290,7 +290,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                 handleSelected={handleSelected}
                 _id={_id}
                   /></div>)
-            if (type === 'video') return (<div key={createdAt}>
+            if (type === 'video') return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                  <MessageRightVideo  
                  url={url}
@@ -305,7 +305,7 @@ const ChatBar = ({selectedArr,setSelectedArr,isSomeSelected,setIsSomeSelected}:I
                  handleSelected={handleSelected}
                  _id={_id}
                    /></div>)
-            if (type) return (<div key={createdAt}>
+            if (type) return (<div key={createdAt} id={_id} style={{borderRadius: 7}}>
               {isTime&&<MessageTime message={timeStampFilter(createdAt)}/>}
                  <MessageRightFile  
                  url={url}

+ 132 - 20
src/components/HomePage/CentralBar/HeaderBar/PinnedBar/index.tsx

@@ -3,13 +3,25 @@ import IconButton from '@mui/material/IconButton';
 import MenuItem from '@mui/material/MenuItem';
 import ListItemText from '@mui/material/ListItemText';
 import CloseIcon from '@mui/icons-material/Close';
+import MenuOpenIcon from '@mui/icons-material/MenuOpen';
+import Button from '@mui/material/Button';
+import Avatar from '@mui/material/Avatar';
+import ListItemIcon from '@mui/material/ListItemIcon';
+import LibraryMusicIcon from '@mui/icons-material/LibraryMusic';
+import FolderIcon from '@mui/icons-material/Folder';
+import ImageIcon from '@mui/icons-material/Image';
+import ContentCopyIcon from '@mui/icons-material/ContentCopy';
+import VideoLibraryIcon from '@mui/icons-material/VideoLibrary';
+import ListItemAvatar from '@mui/material/ListItemAvatar';
+import { CopyToClipboard } from 'react-copy-to-clipboard';
 import { makeStyles } from '@material-ui/core'
-import { useDispatch,useSelector } from 'react-redux';
+import { useSelector } from 'react-redux';
 import { useState,useEffect} from 'react';
 
 import { TMessages,TMessage } from '../../../../../typescript/redux/messages/types';
 import { getMessagesMemo } from '../../../../../redux/messages/selector';
-import { firstLetter,slicedWord,handleSort } from '../../../../../helpers';
+import { firstLetter,slicedWord,handleSort,prodAwsS3,copied,handleDownload } from '../../../../../helpers';
+import { pinMessageById } from '../../../../../api-data';
 
 const useStyles = makeStyles({
   container: {
@@ -26,49 +38,149 @@ const useStyles = makeStyles({
   },
   listWrapper: {
     background: '#fdfdfd',
-    width: 400,
     padding:0
-  },  
+  },
+  overlay: {
+    position: 'fixed',
+    top: 0,
+    left: 0,
+    width: '100vw',
+    height: '100vh',
+    zIndex: 100,
+    backgroundColor: 'rgba(104, 105, 104, 0.6)',
+    overflowY: 'hidden',
+  },
+  modalUnpin: {
+    background: '#ffffff',
+    position: 'absolute',
+    content:'',
+    width: '20%',
+    height:'auto',
+    left: '40%',
+    bottom: '48.5%',
+    borderRadius: 10,
+    padding: 10,
+    display: 'flex',
+    flexDirection:'column'
+  },
+  folderIcon: {
+    color: '#54b0fc',
+    cursor: 'pointer',
+    '&:hover': {
+      color: '#016cc3'
+    },
+  },
 })
 
-const PinnedBar = () => {
+const PinnedBar = ({divRef}:{divRef: any | null}) => {
   const classes = useStyles()
-  const dispatch = useDispatch()
   const messagesMemo = useSelector(getMessagesMemo)
   const [pinnedArr, setPinnedArr] = useState<TMessages>([])
   const [openedPin, setOpenedPin] = useState<TMessage | null>(null)
-  const [openIndex, setOpenIndex] = useState<number>(0)
-  const handleActivePin = () => setOpenIndex(openIndex => openIndex + 1)
+  const [openedIndex, setOpenedIndex] = useState<number>(0)
+  const [modal, setModal] = useState<boolean>(false)
+  
+  const handleActivePin = () => {
+    const childNodes = divRef.current.childNodes[0].childNodes
+    let toScrollNode:any
+    if (pinnedArr.length - 1 === openedIndex) {
+      setOpenedIndex(0)
+      toScrollNode = [ ...childNodes ].find((el:any) => el.id === pinnedArr[0]._id)
+    } else {
+      setOpenedIndex(prevState => prevState + 1)
+      toScrollNode = [...childNodes].find((el: any) => el.id === pinnedArr[openedIndex + 1]._id)
+    }
+    toScrollNode.style.boxShadow = '0px 0px 6px 0px #555555'
+    toScrollNode.scrollIntoView()
+    setTimeout(() => {
+      toScrollNode.style.boxShadow = 'unset'
+    }, 2000)
+  }
+  const handleUnpin = (e: any) => {
+    const id = e.target.id
+    if (id === 'overlay' || id === 'cancel') return setModal(false)
+    if (id === 'unpin' && openedPin) {
+      pinMessageById(openedPin._id, !openedPin.pinned)
+      setModal(false)
+      if (openedIndex - 1 >= 0) {
+        return setOpenedIndex(prevState => prevState - 1)
+      } else {
+        setOpenedIndex(0)
+      }
+    }
+  } 
   
   useEffect(() => {
     const messages = messagesMemo.filter((el) => el.pinned === true)
-    setPinnedArr(handleSort('updatedAt', messages, true))
+    setPinnedArr(handleSort('updatedAt', messages, false))
   }, [messagesMemo])
 
   useEffect(() => {
-    const pinnedObj = pinnedArr[openIndex]
-    if (pinnedObj) setOpenedPin(pinnedObj)
-    else setOpenIndex(0)
-  }, [openIndex,pinnedArr])   
+    setOpenedPin(pinnedArr[openedIndex])
+  }, [openedIndex, pinnedArr])
 
   return openedPin ?
     <Stack className={classes.container} direction="row">
       <ul className={classes.listWrapper}>
         <MenuItem onClick={handleActivePin}>
-          <ListItemText primary={`${firstLetter(openedPin.name)}${slicedWord(openedPin.name, 15, 1)} 
+          <ListItemIcon >
+            <Avatar alt={openedPin.name} src={openedPin.avatarUrl?`${prodAwsS3}/${openedPin.avatarUrl}`:undefined}
+              sx={{ background: openedPin.color, width: 44, height: 44 }}>
+              {!openedPin.avatarUrl&&`${firstLetter(openedPin.name)}${firstLetter(openedPin.lastName)}`}
+          </Avatar>
+          </ListItemIcon>           
+          <ListItemText style={{marginLeft:20}}
+            primary={`${firstLetter(openedPin.name)}${slicedWord(openedPin.name, 15, 1)}
             ${firstLetter(openedPin.lastName)}${slicedWord(openedPin.lastName, 15, 1)}`}
             primaryTypographyProps={{fontSize:16 }}
-            secondary={slicedWord(openedPin.message, 40, 1)}
+            secondary={slicedWord(openedPin.message, 20, 1)}
             secondaryTypographyProps={{fontSize: 12 }} />
-          <ListItemText primary={`Pinned Message #${openIndex+1}`}
+          <ListItemText style={{marginLeft:20}}
+            primary={`Pinned Message ${openedIndex + 1} of ${pinnedArr.length}`}
             primaryTypographyProps={{ color: "#0379af",fontSize:16 }}
-            secondary={`Type : ${openedPin.type}`}
+            secondary={`Type : ${openedPin.type.toUpperCase()}`}
             secondaryTypographyProps={{ fontSize:16 }}/>          
         </MenuItem>
-      </ul>      
-      <IconButton  aria-label="delete" size="medium">
+      </ul>
+      <ListItemAvatar style={{marginLeft:10}}>
+        {openedPin.type === 'text' &&<CopyToClipboard onCopy={() => copied('Message')} text={openedPin.message}>
+           <ContentCopyIcon className={classes.folderIcon} fontSize='large' />
+        </CopyToClipboard>}
+        {openedPin.type === 'audio' &&<LibraryMusicIcon onClick={() =>
+          handleDownload(`${prodAwsS3}/${openedPin.message}`, openedPin.fullType)}
+          className={classes.folderIcon} fontSize='large' />}
+        {openedPin.type === 'video' &&<VideoLibraryIcon onClick={() =>
+          handleDownload(`${prodAwsS3}/${openedPin.message}`, openedPin.fullType)}
+          className={classes.folderIcon} fontSize='large' />}
+        {openedPin.type === 'image' &&<ImageIcon onClick={() =>
+          handleDownload(`${prodAwsS3}/${openedPin.message}`, openedPin.fullType)}
+          className={classes.folderIcon} fontSize='large' />}
+        {openedPin.type === 'pdf' ?<FolderIcon onClick={() =>
+          handleDownload(`${prodAwsS3}/${openedPin.message}`, openedPin.fullType)}
+          className={classes.folderIcon} fontSize='large' />:null}         
+        {openedPin.type === 'docx' ?<FolderIcon onClick={() =>
+          handleDownload(`${prodAwsS3}/${openedPin.message}`, openedPin.fullType)}
+          className={classes.folderIcon} fontSize='large' />:null}        
+      </ListItemAvatar>
+      <IconButton onClick={() => setModal(true)} aria-label="delete" size="medium">
         <CloseIcon className={classes.iconClose} fontSize='medium'/>
-      </IconButton>          
+      </IconButton>
+      <IconButton aria-label="delete" size="medium">
+        <MenuOpenIcon fontSize='medium'/>
+      </IconButton>
+      {modal &&
+      <div onClick={handleUnpin} className={classes.overlay} id='overlay'>
+        <div className={classes.modalUnpin}>
+          <h3 style={{color: '#2c2c2c'}}>Telegram</h3>
+          <p style={{ color: '#050505' }}>Would you like to unpin this message?</p>
+          <Button id='unpin' variant="text" color="error" style={{fontWeight:500,fontSize:22}}>
+            UNPIN
+          </Button>         
+          <Button id='cancel' variant="text" style={{fontWeight:500,fontSize:22}}>
+             CANCEL
+          </Button>
+        </div>  
+      </div>}        
     </Stack> :
     null
 }

+ 3 - 2
src/components/HomePage/CentralBar/HeaderBar/index.tsx

@@ -52,13 +52,14 @@ const useStyles = makeStyles({
 })
 
 interface IHeaderBar {
+  divRef: any | null,
   selectedArr: string[] | [],
   isSomeSelected: boolean,
   setIsSomeSelected: React.Dispatch<React.SetStateAction<boolean>>,
   handleClearSelect: () => void
 }
 
-const HeaderBar = ({selectedArr,isSomeSelected,setIsSomeSelected,handleClearSelect}:IHeaderBar) => {
+const HeaderBar = ({divRef,selectedArr,isSomeSelected,setIsSomeSelected,handleClearSelect}:IHeaderBar) => {
   const classes = useStyles()
   const { companionId } = useSelector(getChatMemo)
   const [modal, setModal] = useState<boolean>(false)
@@ -82,7 +83,7 @@ const HeaderBar = ({selectedArr,isSomeSelected,setIsSomeSelected,handleClearSele
         <Toolbar className={classes.toolBar}>
           <Credentials/>
           <div className={classes.toolBarRight}>
-            <PinnedBar/>
+            <PinnedBar divRef={divRef}/>
             <Buttons setIsSomeSelected={setIsSomeSelected}/>
           </div>
         </Toolbar>

+ 4 - 3
src/components/HomePage/CentralBar/index.tsx

@@ -1,6 +1,6 @@
 import Grid from '@mui/material/Grid'
 import { makeStyles } from '@material-ui/core'
-import { useState } from 'react'
+import { useState,useRef } from 'react'
 
 import HeaderBar from './HeaderBar'
 import ChatBar from './ChatBar'
@@ -14,6 +14,7 @@ const useStyles = makeStyles({
 
 const CentralBar = ({rightIsOpen}:{rightIsOpen:TRightIsOpen}) => {
   const classes = useStyles()
+  const divRef = useRef<any | null>(null)
   const [selectedArr, setSelectedArr] = useState<string[] | []>([])
   const [isSomeSelected, setIsSomeSelected] = useState<boolean>(false)
   const handleClearSelect = () => {
@@ -24,10 +25,10 @@ const CentralBar = ({rightIsOpen}:{rightIsOpen:TRightIsOpen}) => {
     return ( 
      <Grid item lg={rightIsOpen?8:12}>
         <Grid item lg={12} >
-          <HeaderBar selectedArr={selectedArr} isSomeSelected={isSomeSelected} handleClearSelect={handleClearSelect} setIsSomeSelected={setIsSomeSelected}/>
+          <HeaderBar divRef={divRef} selectedArr={selectedArr} isSomeSelected={isSomeSelected} handleClearSelect={handleClearSelect} setIsSomeSelected={setIsSomeSelected}/>
         </Grid>          
         <Grid item lg={12} className={classes.chatBar}>
-          <ChatBar selectedArr={selectedArr} setSelectedArr={setSelectedArr} isSomeSelected={isSomeSelected} setIsSomeSelected={setIsSomeSelected}/>
+          <ChatBar divRef={divRef} selectedArr={selectedArr} setSelectedArr={setSelectedArr} isSomeSelected={isSomeSelected} setIsSomeSelected={setIsSomeSelected}/>
         </Grid>
       </Grid>
     )