Преглед на файлове

added media dispay and sorting

Ivar преди 2 години
родител
ревизия
37684fbdcb
променени са 5 файла, в които са добавени 184 реда и са изтрити 60 реда
  1. 5 2
      src/components/ChatModal.jsx
  2. 109 25
      src/components/MsgList.jsx
  3. 8 2
      src/components/ProfileModal.jsx
  4. 61 30
      src/components/SendingField.jsx
  5. 1 1
      src/reducers/store.js

+ 5 - 2
src/components/ChatModal.jsx

@@ -245,8 +245,11 @@ const ChatModal = ({ minTitle="2", chat, onСonfirm, titleError, myProfile, crea
                      <Button  variant="contained" 
                               disabled={  (title?.length < minTitle) ? true :
                                          ((chat?.owner?._id !== myProfile?._id) && !create) ? true : false }
-                              onClick={() => onСonfirm( "media", img, title, 
-                                                         prepareMembers(members), chat?._id )} >
+                              onClick={() => {
+                                 onСonfirm( "media", img, title, 
+                                                         prepareMembers(members), chat?._id );
+                                 handleClose()
+                              } } >
                         Применить 
                      </Button>
                   </Box>

+ 109 - 25
src/components/MsgList.jsx

@@ -1,4 +1,6 @@
 import React, {useState, useEffect, useRef} from 'react'
+import FileDownloadIcon from '@mui/icons-material/FileDownload';
+import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
 
 import { connect } from 'react-redux'
 import { dateFromStamp, stringColor, backURL } from '../helpers'
@@ -83,7 +85,50 @@ const dateBlock = {
    color: "#555"
 }
 
+const mediaBlock = {
+   marginBottom: "20px"
+}
+const textBlock = {
+}
 
+const imgStyle = { 
+   maxWidth: "100%", 
+   width: "auto",
+   maxHeight: "400px", 
+   height: "auto",
+   margin: "0 5px"
+}
+const downloadStyle = { 
+   display: "flex",
+   maxWidth: "300px",
+   minHeight: "54px",
+   borderRadius: "30px",
+   textDecoration: "none",
+   margin: "5px 0",
+   padding: "10px",
+   backgroundColor: "#eeee"
+}
+const imgDownload = { 
+   alignSelf: "center",
+   borderRadius: "50%",
+   backgroundColor: "#1976d2",
+   height: "45px",
+   width: "45px",
+   display: "flex",
+   justifyContent: "center",
+   alignItems: "center",
+   marginRight: "10px",
+}
+const textDownload = { 
+   alignSelf: "start",
+   // marginTop: "10px",
+   maxWidth: "calc(100% - 55px)",
+   fontSize: 14, 
+   fontWeight: 500,
+   color: "#000",
+   wordWrap: "break-word",
+   overflow: "hidden" 
+}
 
 
 const Msg = ({ msg, prevOwner, prevTime, myProfile }) => {
@@ -104,16 +149,11 @@ const Msg = ({ msg, prevOwner, prevTime, myProfile }) => {
 
             allMedia[objName].push(file)
          } else {
-
             allMedia[objName] = [file]
          }
       }  
    }
 
-   // console.log(media)
-
-
-
    const prOwner = prevOwner.current
    prevOwner.current = owner._id
 
@@ -123,7 +163,6 @@ const Msg = ({ msg, prevOwner, prevTime, myProfile }) => {
    // console.log( prTime - createdAt,  text)
    const nameBlockNew = {...nameBlock, color: stringColor.stringToColor(nick || login)}
    return (
-      <>
          <div 
             style={(myId === owner._id) ? 
                ( (prOwner === owner._id) ? 
@@ -132,6 +171,7 @@ const Msg = ({ msg, prevOwner, prevTime, myProfile }) => {
                      {...msgBlock, marginBottom: "2px"} : {...msgBlock, marginBottom: "15px"})
                }
             >
+
             <div style={avBlock} >
                { (prOwner === owner._id && 
                      prTime - createdAt < 600000) || 
@@ -139,6 +179,7 @@ const Msg = ({ msg, prevOwner, prevTime, myProfile }) => {
                                  <CMyAvatar /> : 
                                        <UserAvatar profile={owner} /> ) }
             </div>
+
             <div style={(myId === owner._id) ? myBodyBlock : bodyBlock} >
 
                <div style={(myId === owner._id) ? nameBlock : nameBlockNew} >
@@ -146,24 +187,68 @@ const Msg = ({ msg, prevOwner, prevTime, myProfile }) => {
                </div>
 
                <div style={contentBlock} >
-
-                  {
-                     (media && media.length !== 0) &&
-                           <div>
-                              {media.map((mediaObj) => <div key={mediaObj.url} 
-                                                            style={{
-                                                            }} >
-                                                         <img key={mediaObj.url}
-                                                            // type={mediaObj.type}
-                                                            style={{ maxWidth: "100%", width: "auto",
-                                                                     maxHeight: "400px", height: "auto" }}
-                                                            src={backURL + mediaObj.url } />
-                                                       </div>                                     
-                                                                                             )}
-                           </div> 
-                  }
-
-                  <pre>
+                  <div style={mediaBlock}>
+                     { Object.keys(allMedia).map((key) => 
+                        <div key={key} > 
+                           {
+                              (key === 'image') &&
+                                    allMedia[key].map((mediaObj) => 
+                                                                  <img 
+                                                                     key={mediaObj.url}
+                                                                     style={imgStyle}
+                                                                     src={backURL + mediaObj.url} 
+                                                                  />
+                                                                                    ) ||
+                                 (key === 'video') &&
+                                       allMedia[key].map((mediaObj) => 
+                                                                     <video 
+                                                                        key={mediaObj.url}
+                                                                        style={imgStyle}
+                                                                        src={backURL + mediaObj.url} 
+                                                                        controls   
+                                                                        preload={'metadata'}                                                                
+                                                                     >
+                                                                     </video>
+                                                                                    ) ||
+                                    (key === 'audio') &&
+                                          allMedia[key].map((mediaObj) => 
+                                                                        <div 
+                                                                           key={mediaObj.url} 
+                                                                        >
+                                                                           <audio 
+                                                                              src={backURL + mediaObj.url}
+                                                                              controls
+                                                                           >
+                                                                           </audio>
+                                                                        </div>                                     
+                                                                                             )  ||
+                                             allMedia[key].map((mediaObj) => 
+                                                                           <a 
+                                                                              key={mediaObj.url} 
+                                                                              href={backURL + mediaObj.url}
+                                                                              download    
+                                                                              style={downloadStyle}                                                                       
+                                                                           >
+                                                                              <div 
+                                                                                 style={imgDownload}>
+                                                                                 <FileDownloadIcon 
+                                                                                    style={{ 
+                                                                                       fontSize: 35, 
+                                                                                       color: "#ddd",
+                                                                                          }} />
+                                                                              </div>
+                                                                              <div 
+                                                                                 style={textDownload} >
+                                                                                 {mediaObj.originalFileName}
+                                                                              </div>
+                                                                           </a>
+                                                                                                )
+                           }
+                        </div> 
+                     )}
+                  </div>
+
+                  <pre style={textBlock}>
                      {text}
                   </pre>
                   
@@ -174,7 +259,6 @@ const Msg = ({ msg, prevOwner, prevTime, myProfile }) => {
                </div>
             </div>
          </div> 
-      </>
    )
 }
 const CMsg = connect( state => ({ myProfile: state.promise.myProfile?.payload || {}}))(Msg)

+ 8 - 2
src/components/ProfileModal.jsx

@@ -167,7 +167,10 @@ const PassModal = ({ onСonfirm, regError}) => {
                         disabled={( passReq.checkPass(pass) && 
                                     pass === pass2 ) ? false : true}
 
-                        onClick={() => onСonfirm(pass)}>
+                        onClick={() => {
+                           onСonfirm(pass);
+                           handleClose()
+                        } }>
                   Изменить 
                </Button>
             </Box>
@@ -339,7 +342,10 @@ const ProfileModal = ({minLog='2', myProfile, onСonfirm, logError}) => {
             <Box sx={{ display: 'flex', justifyContent: 'end', mt: 2}}>
                <Button  variant="contained" 
                         disabled={(login?.length >= minLog) ? false : true}
-                        onClick={() => onСonfirm("media", img, login, nick)}>
+                        onClick={() => {
+                           onСonfirm("media", img, login, nick);
+                           handleClose()
+                        } }>
                   Применить 
                </Button>
             </Box>

+ 61 - 30
src/components/SendingField.jsx

@@ -17,7 +17,6 @@ import {
 } from "../actions"
 
 const containerWrapp = {
-   // width: '80%',
    display: 'flex', 
    flexDirection: 'column',
    padding: '5px',
@@ -30,49 +29,64 @@ const thumbsContainer = {
    flexWrap: 'wrap',
    width: '100%',
    overflow: 'auto',
- };
+ }
  
  const thumb = {
    flexGrow: '0',
-   display: 'inline-flex',
-
-   
+   display: 'inline-flex',   
    borderRadius: 2,
    border: '1px solid #eaeaea',
    marginBottom: 8,
    marginRight: 8,
    width: 100,
-   height: 117,
+   height: 118,
    padding: 4,
    boxSizing: 'border-box',
    position: 'relative',
- };
+   backgroundColor: '#fff'
+ }
  
  const thumbInner = {
-   display: 'flex',
-   flexDirection: 'column',
-   paddingTop: 17,
+   paddingTop: 18,
+   width: "100%",
    minWidth: 0,
    overflow: 'hidden'
- };
+ }
 
  const closeBtn = {
     position: 'absolute',
     right: 0,
-    display: 'flex',
-    justifyContent: 'end',
  }
- 
+
  const img = {
+   margin: '0 auto',
+   display: 'block',
+   objectFit: "cover",
+   maxWidth: 'auto',
+   maxHeight: '100%'
+ }
+
+ const other = {
+   margin: '0 auto',
    display: 'block',
-   width: 'auto',
-   height: '100%'
- };
+   maxWidth: 'auto',
+   maxHeight: '100%',
+   userSelect: 'none',
+ }
+ const othTitle = {
+   fontWeight: 500,
+   fontSize: "14px"
+ }
+ const othContent = {
+   marginTop: "2px",
+   fontWeight: 300,
+   fontSize: "12px"
+}
 
 
 
 
- const SortableItem = sortableElement(({onDelete, index, file}) => (
+ const SortableItem = sortableElement(({onDelete, file}) => (
    <div style={thumb}>         
       <div style={closeBtn}>
          <CloseIcon 
@@ -81,11 +95,34 @@ const thumbsContainer = {
             onClick={onDelete} 
          />
       </div>         
-      <div style={thumbInner}>           
-         <img
-         src={file.preview}
-         style={img}
-         /> 
+      <div style={thumbInner}>  
+      { 
+         (file.type.split('/')[0] === 'image') ? 
+            <img
+               src={file.preview}
+               style={img}
+            />  :
+            
+            (file.type.split('/')[0] === 'video') ?
+               <video 
+                  autoPlay 
+                  muted
+                  loop
+                  // не работает
+                  // playbackrate={'10'}
+                  src={file.preview}
+                  style={img}
+               >
+               </video> :
+
+               <div
+                  style={other}
+               >
+                  <div style={othTitle}>{file.type.split('/')[0]}</div>
+                  <div style={othContent}>{file.name}</div>                  
+               </div>
+      }         
+
       </div>     
    </div>
  ));
@@ -102,8 +139,6 @@ const thumbsContainer = {
 
 
 
-
-
 const MsgDropZone = ({ setText, setFiles, files, text, onEnter }) => {
 
    const {
@@ -113,9 +148,7 @@ const MsgDropZone = ({ setText, setFiles, files, text, onEnter }) => {
    } = useDropzone({
          noKeyboard: true,
          onDrop: async (acceptedFiles) => {
-
-            console.log(acceptedFiles)
-
+            // console.log(acceptedFiles)
             await setFiles([...files, 
                ...acceptedFiles.map(file => Object.assign(file, {
                   preview: URL.createObjectURL(file)
@@ -125,8 +158,6 @@ const MsgDropZone = ({ setText, setFiles, files, text, onEnter }) => {
          }
       });
 
-   // console.log(files)
-
    const onDelete = (i) => {
       setFiles( (files) => files.filter((el, index) => index !== i) )
    }

+ 1 - 1
src/reducers/store.js

@@ -57,7 +57,7 @@ function playAudio(audio) {
 
 
 socket.on('msg', async (msg) => { 
-   console.log('пришло смс', msg)
+   console.log('пришло смс')
    
    const state = store.getState()
    const myId = state.auth.payload?.sub?.id