message.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import ReactTimeAgo from 'react-time-ago'
  2. import TimeAgo from 'javascript-time-ago'
  3. import ru from 'javascript-time-ago/locale/ru.json'
  4. import { useState } from 'react'
  5. import { Menu, MenuItem } from '@mui/material'
  6. TimeAgo.addLocale(ru)
  7. export const ShortMessage = ({ nick, text, date }) => {
  8. return (
  9. <>
  10. <div className="msg-short">
  11. <span className="msg-nick">Ответ на сообщение {nick}</span>
  12. <span className="msg-text">{text}</span>
  13. <ReactTimeAgo className="msg-date" date={+date} locale="ru" timeStyle="twitter" />
  14. </div>
  15. </>
  16. )
  17. }
  18. export const Message = ({ id, nick, msg, date, media, own = false, replyTo, onMSGEdit, onMSGReply, onMSGForward }) => {
  19. let [isEdit, setIsEdit] = useState(false)
  20. let [messageEdit, setMessageEdit] = useState("" || msg)
  21. const [contextMenu, setContextMenu] = useState(null);
  22. const handleContextMenu = (event) => {
  23. event.preventDefault();
  24. setContextMenu(
  25. contextMenu === null
  26. ? {
  27. mouseX: event.clientX - 2,
  28. mouseY: event.clientY - 4,
  29. }
  30. : // repeated contextmenu when it is already open closes it with Chrome 84 on Ubuntu
  31. // Other native context menus might behave different.
  32. // With this behavior we prevent contextmenu from the backdrop to re-locale existing context menus.
  33. null,
  34. );
  35. };
  36. const handleClose = (e, type, msg_id) => {
  37. if (type === "edit") {
  38. setIsEdit(true)
  39. }
  40. if (type === "reply") {
  41. onMSGReply([true, msg_id])
  42. }
  43. if (type === "forward") {
  44. alert("Сорян пока не работает)")
  45. // onMSGForward([true, ""])
  46. }
  47. setContextMenu(null);
  48. };
  49. let msgEditHandler = () => {
  50. setIsEdit(false)
  51. onMSGEdit(id, messageEdit)
  52. }
  53. return (
  54. <li className={own ? "msg-user" : "msg-someone"} onContextMenu={handleContextMenu} >
  55. <Menu
  56. open={contextMenu !== null}
  57. onClose={handleClose}
  58. anchorReference="anchorPosition"
  59. anchorPosition={
  60. contextMenu !== null
  61. ? { top: contextMenu.mouseY, left: contextMenu.mouseX }
  62. : undefined
  63. }
  64. >
  65. <MenuItem onClick={e => handleClose(e, "reply", id)}>Ответить</MenuItem>
  66. <MenuItem onClick={e => handleClose(e, "forward", id)}>Переслать</MenuItem>
  67. <MenuItem onClick={e => handleClose(e, "edit", id)}>Редактировать</MenuItem>
  68. </Menu>
  69. {/* <ContextMenu message={id} element={el.current} owner={own} onEdit={setIsEdit} onForwardTo={onMSGForward} onReplyTo={onMSGReply} /> */}
  70. {replyTo && <div className="msg-reply">В ответ на сообщение: {replyTo.text}</div>}
  71. <div className="msg">
  72. <span className="msg-nick">{nick}</span>
  73. {isEdit ?
  74. <>
  75. <input value={messageEdit} onChange={(e) => setMessageEdit(e.target.value)} />
  76. <button onClick={() => msgEditHandler()} >Сохранить изменения</button>
  77. </> :
  78. <span className="msg-text">{msg}</span>}
  79. <ReactTimeAgo className="msg-date" date={+date} locale="ru" timeStyle="round" />
  80. {media && media.length > 0 &&
  81. <ul className="msg-media">
  82. {media.map(file => {
  83. return (<li key={file.url}>
  84. {file.type && file.type.includes("audio") &&
  85. <audio className="msg-media-audio" preload="metadata" controls>
  86. <source src={"/" + file.url} type={file.type} />
  87. <a href={"/" + file.url}>Скачать</a>
  88. </audio>
  89. }
  90. {
  91. file.type && file.type.includes("image") &&
  92. <img className="msg-media-img" src={"/" + file.url} alt="media" />
  93. }
  94. {
  95. file.type && file.type.includes("video") &&
  96. <video className="msg-media-video" preload="metadata" controls>
  97. <source src={"/" + file.url} type={file.type} />
  98. <a href={"/" + file.url}>Скачать</a>
  99. </video>
  100. }
  101. </li>)
  102. })}
  103. </ul>}
  104. </div>
  105. </li>
  106. )
  107. }