2 Commits 28b90eaf33 ... 470246bc4b

Autore SHA1 Messaggio Data
  Ivar 470246bc4b added socket actions 2 anni fa
  Ivar 86b1a00276 reducer updated, fixed chat modal 2 anni fa

+ 16 - 43
src/actions/chatsActions.js

@@ -42,56 +42,29 @@ const actionUpdateChat = (title, members, chatId) => (
    }`, { chat: {_id: chatId, title, members} }))
 )
 
-// const actionUpdateChatAvatar = (avatarId, chatId) => (
-//    actionPromise('updateChatAvatar', gql(`mutation updateChatAvatar($chat:ChatInput) {
-//       ChatUpsert(chat:$chat) {
-//          _id
-//          title
-//          avatar {
-//             _id
-//             url
-//          }
-//          owner {
-//             _id
-//             login
-//             avatar {
-//                _id
-//                url
-//             }
-//          }
-//          members {
-//             _id
-//             login
-//             nick
-//             avatar {
-//                _id
-//                url
-//             }
-//          }
-//          lastModified    
-//       }
-//    }`, { chat: {_id: chatId,  avatar: {_id: avatarId} } }))
-// )
 
 // MediaUpsert нужен только для добавления данных для загруженного файла
 // и дальнейшего отображения его через эти данные (через аватары, сообщения)
-// const actionUpdateChatAvatar = (mediaId) => (
-//     actionPromise('uploadFile', gql(`mutation uploadFile($media: MediaInput) {  
-//         MediaUpsert(media: $media) {
-//         }
-//     }`, { media: {} }
-//     ))
-//  )
+const actionUpdateChatAvatar = (mediaId, chatId) => (
+    actionPromise('uploadFile', gql(`mutation uploadFile($media: MediaInput) {  
+        MediaUpsert(media: $media) {
+            _id
+            url   
+        }
+    }`, { media: { _id: mediaId, chatAvatars: {_id: chatId} } }
+    ))
+ )
+
 
 export const actionSetChatInfo = (name, file, title, members, chatId) => (
    async (dispatch) => {
+      let chat = await dispatch(actionUpdateChat(title, members, chatId))         
 
-      await dispatch(actionUpdateChat(title, members, chatId))         
-
-      // let fileObj
-      // if (file) {
-      //    fileObj = await dispatch(actionUploadFile(name, file))
-      // } 
+      if (file && chat._id) {
+        let fileObj = await dispatch(actionUploadFile(name, file))
+         let chatAvatar = await dispatch(actionUpdateChatAvatar(fileObj?._id, chat._id))
+         await dispatch(actionChatOne({_id: chat._id, avatar: chatAvatar}))
+      } 
    }
 )
 

+ 2 - 1
src/actions/index.js

@@ -19,6 +19,7 @@ import {
    actionMsgsCount,
    actionSendMsg,
    actionGetAllLastMsg,
+   actionGetMsgById,
 
    actionFullMsgsByChat,
 } from './msgActions'
@@ -31,7 +32,6 @@ import {
 
 
 
-
 export {
    actionFullLogout,
    actionFullLogin, 
@@ -52,6 +52,7 @@ export {
    actionMsgsCount,
    actionSendMsg,
    actionGetAllLastMsg,
+   actionGetMsgById,
 
    actionFullMsgsByChat,
 }

+ 47 - 0
src/actions/msgActions.js

@@ -160,6 +160,53 @@ export const actionMsgsCount = (chatId) => (
 
 
 
+
+export const actionGetMsgById = (msgId) => (
+   actionPromise('msgById', gql(`query msgById($q: String) {
+      MessageFindOne (query: $q){
+         _id
+         createdAt
+         owner {
+            _id
+            login
+            nick
+            avatar {
+               url
+            }
+         }
+         text
+         chat {
+            _id
+         }
+         media {
+            _id
+            url
+            type
+            originalFileName            
+         }
+
+         forwardWith {
+            _id
+         }
+         replies {
+            _id
+         }
+
+         replyTo {
+            _id
+         }
+         forwarded {
+            _id
+         }
+      }     
+   }`, { 
+         q: JSON.stringify([ { _id: msgId } ])
+      }
+   ))
+)
+
+
+
 const actionUpdateMsg = (chatId, text, media, msgId) => (
    actionPromise('updateMsg', gql(`mutation updateMsg($msg: MessageInput) {
       MessageUpsert(message: $msg) {

+ 8 - 6
src/components/ChatModal.jsx

@@ -7,7 +7,6 @@ import Typography from '@mui/material/Typography';
 import TextField from '@mui/material/TextField';
 import CloseIcon from '@mui/icons-material/Close';
 import List from '@mui/material/List';
-import Divider from '@mui/material/Divider';
 
 import {ReactComponent as KickLogo} from '../assets/kick.svg'
 
@@ -43,7 +42,7 @@ const DelBtn = ({ onEvent }) => (
    </IconButton>
 )
 
-const ChatModal = ({ minTitle="2", chat, onСonfirm, titleError, create, render }) => {
+const ChatModal = ({ minTitle="2", chat, onСonfirm, titleError, myProfile, create, render }) => {
 
    const [open, setOpen] = useState(false)
    const handleOpen = () =>  setOpen(true) 
@@ -117,7 +116,8 @@ const ChatModal = ({ minTitle="2", chat, onСonfirm, titleError, create, render
 
                <Box sx={{ display: 'flex', justifyContent: 'start' }}>
                   <Typography variant="h6">
-                    {create ? 'Создание чата' : 'Редактирование чата' } 
+                    {((chat?.owner?._id !== myProfile?._id) && !create) ?
+                                 'Информация (редактирование запрещено)' : create ? 'Создание чата' : 'Редактирование чата' } 
                   </Typography>
                </Box>
 
@@ -218,6 +218,7 @@ const ChatModal = ({ minTitle="2", chat, onСonfirm, titleError, create, render
                         <List
                            sx={{ maxWidth: '100%', bgcolor: 'background.paper' }}
                            >
+                           {/* { create && <UserCard key={'iAm'} user={myProfile} /> } */}
                            { members.map((member, i) => <UserCard key={member._id} user={member} 
                                                                   render={DelBtn}  onAction={() => onDelMember(i)} />)}
                         </List>
@@ -242,13 +243,13 @@ const ChatModal = ({ minTitle="2", chat, onСonfirm, titleError, create, render
       
                   <Box sx={{ display: 'flex', justifyContent: 'center'}}>
                      <Button  variant="contained" 
-                              disabled={(title?.length >= minTitle) ? false : true}
+                              disabled={  (title?.length < minTitle) ? true :
+                                         ((chat?.owner?._id !== myProfile?._id) && !create) ? true : false }
                               onClick={() => onСonfirm( "media", img, title, 
                                                          prepareMembers(members), chat?._id )} >
                         Применить 
                      </Button>
                   </Box>
-
             </Box>
 
  
@@ -257,6 +258,7 @@ const ChatModal = ({ minTitle="2", chat, onСonfirm, titleError, create, render
      </>
    )
  }
- export const CChatModal = connect(  state => ( { chatError: state.promise.updateChat || {} }), 
+ export const CChatModal = connect(  state => ( {  chatError: state.promise.updateChat || {},
+                                                   myProfile: state.promise.myProfile?.payload || {} }), 
                                         { onСonfirm: actionSetChatInfo })(ChatModal)
  

+ 39 - 14
src/reducers/chatsReducer.js

@@ -46,6 +46,10 @@
       return newMsgState
     }
 
+    // перебрать, проверить, что везде есть ключи, если где то нет, использовать те что есть
+    // function refreshMembers(newMembers, oldMembers) {
+    // }
+
 
     function sortChats(unsortedChats) {
       return Object.fromEntries(
@@ -69,20 +73,41 @@
 
           const oldChats = {...state}
 
+          // перебираем новые чаты
           for (const chat of payload) {
-
-            const oldMsgs = oldChats[chat._id]?.messages
-            const newMsgs = chat?.messages
-
-            oldChats[chat._id] = chat
-
-            if (oldMsgs && newMsgs) {
-              
-              oldChats[chat._id].messages = refreshMsgs(newMsgs, oldMsgs)
-
-            } else if (oldMsgs) {
-
-              oldChats[chat._id].messages = oldMsgs
+            // находим старый чат с ид нового
+            const oldChat = oldChats[chat._id]
+            // если его еще нет, то просто записываем
+            if (!oldChat) {
+              oldChats[chat._id] = chat //-----------------------------------------
+              // если есть, то идем по свойствам нового чата
+            } else for (const key in chat) {
+              // записываем значение свойства нового и старого чата 
+              const oldValue = oldChat[key]
+              const newValue = chat[key]
+              // проверяем наличие значений
+              // если оба значения есть, переходим к проверке на массив (на объект вроде не надо)
+              if (oldValue && newValue) {
+                // если массив, то выясняем какой и вызываем соответствующие функции слияния
+                if (Array.isArray(newValue)) {
+                  if (key === 'messages') {
+                    oldChats[chat._id][key] = refreshMsgs(newValue, oldValue)
+                  }
+                  if (key === 'members') {
+                    oldChats[chat._id][key] = newValue
+                  }
+                  // если не массив, то перезаписываем новым значением
+                } else {
+                  oldChats[chat._id][key] = newValue //-----------------------------------
+                }
+
+                // если есть только новое, записать новое
+              } else if (newValue) {
+                oldChats[chat._id][key] = newValue //-------------------------------------
+                // если есть только старое, записать старое (можно ничего не делать)
+              } else {
+                oldChats[chat._id][key] = oldValue //-------------------------------------
+              }
             }
 
           }
@@ -139,7 +164,7 @@
         {type: 'CHAT_LEFT', payload: chat}
   )
 
-  // добавить id чата
+  // добавить id чата ?
   export const actionMsgList = (msgs) => (
         {type: 'MSGS', payload: msgs}
   )

+ 37 - 18
src/reducers/store.js

@@ -9,12 +9,13 @@ import { actionAboutMe } from './findUserActions'
 import { 
    actionMsgOne, 
    actionChatOne, 
-   actionChatLeft 
+   actionChatLeft
 } from './chatsReducer'
 
 import {   
+   actionGetMsgById,
    actionGetChatById, 
-   actionFullLogout
+   actionFullLogout,
 } from '../actions'
 
 import msgSound from '../assets/msgSound.ogg'
@@ -49,47 +50,65 @@ socket.on('jwt_fail', (error) => {
 })
 
 
+function playAudio(audio) {
+   const newAudio = new Audio(audio)
+   newAudio.play()
+}
+
+
 socket.on('msg', async (msg) => { 
-   console.log('пришло смс')
+   console.log('пришло смс', msg)
    
    const state = store.getState()
    const myId = state.auth.payload?.sub?.id
    const ownerId = msg.owner?._id
    if (myId !== ownerId) {
-      const inputMsgAudio = new Audio(msgSound)
-      inputMsgAudio.play()
+      playAudio(msgSound)
    }
 
    const chatId = msg.chat?._id
 
    await store.dispatch(actionMsgOne(msg)) 
 
-   if (chatId) {
-      console.log('ZASHLO')
-      let chatUpdated = await store.dispatch(actionGetChatById(chatId))
-      await store.dispatch(actionChatOne(chatUpdated))
-   }
+   let msgFull = await store.dispatch(actionGetMsgById(msg._id))
+   await store.dispatch(actionMsgOne(msgFull)) 
+
+   let chatUpdated = await store.dispatch(actionGetChatById(chatId))
+   await store.dispatch(actionChatOne(chatUpdated))
 })
 
-socket.on('chat', (chat) => { 
+socket.on('chat', async (chat) => { 
    console.log('нас добавили в чат')
-   const inputChatAudio = new Audio(chatSound)
-   inputChatAudio.play()
+
+   const state = store.getState()
+   const myId = state.auth.payload?.sub?.id
+   const ownerId = state.chats[chat._id]?.owner?._id
+
+   if (myId !== ownerId) {
+      playAudio(chatSound)
+   }
 
    store.dispatch(actionChatOne(chat)) 
+
+   let chatFull = await store.dispatch(actionGetChatById(chat._id))
+   await store.dispatch(actionChatOne(chatFull))
 })
 
-socket.on('chat_left', (chat) => { 
+socket.on('chat_left', async (chat) => { 
    console.log('нас выкинули из чата')
 
    const state = store.getState()
    const myId = state.auth.payload?.sub?.id
-   const ownerId = chat.owner?._id
+   const ownerId = state.chats[chat._id]?.owner?._id
 
-   const chatKickAudio = new Audio(chatSound)
-   chatKickAudio.play()
+   if (myId !== ownerId) {
+      playAudio(chatSound)
+      store.dispatch(actionChatLeft(chat)) 
+   }
+   store.dispatch(actionChatOne(chat)) 
 
-   store.dispatch(actionChatLeft(chat)) 
+   let chatFull = await store.dispatch(actionGetChatById(chat._id))
+   await store.dispatch(actionChatOne(chatFull))
 })