MessageButton.jsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import React from "react";
  2. import { useTranslation } from "react-i18next";
  3. import styled from "styled-components";
  4. import { useMessage } from "react-sync-board";
  5. import useNotify from "../hooks/useNotify";
  6. import Touch from "../ui/Touch";
  7. import SidePanel from "../ui/SidePanel";
  8. import Composer from "./Composer";
  9. import MessageList from "./MessageList";
  10. const StyledChat = styled.div`
  11. height: 100%;
  12. display: flex;
  13. flex-direction: column;
  14. `;
  15. const NotifCount = styled.div`
  16. width: 2em;
  17. height: 2em;
  18. border-radius: 100%;
  19. position: absolute;
  20. top: -5px;
  21. right: 1.8em;
  22. background-color: var(--color-success);
  23. text-align: center;
  24. line-height: 2em;
  25. box-shadow: 3px 3px 6px #000000c0;
  26. `;
  27. export const MessagePanel = ({ onNewMessage, show, setShow }) => {
  28. const { t } = useTranslation();
  29. const { messages, sendMessage } = useMessage(onNewMessage, true);
  30. return (
  31. <SidePanel
  32. open={show}
  33. onClose={() => {
  34. setShow(false);
  35. }}
  36. position="left"
  37. noMargin
  38. title={t("Chat")}
  39. >
  40. <StyledChat>
  41. <MessageList messages={messages} />
  42. <Composer sendMessage={sendMessage} />
  43. </StyledChat>
  44. </SidePanel>
  45. );
  46. };
  47. export const MessageButton = () => {
  48. const { t } = useTranslation();
  49. const { add, reset, count } = useNotify();
  50. const [showPanel, setShowPanel] = React.useState(false);
  51. const onNewMessage = React.useCallback(() => {
  52. if (!showPanel) {
  53. add();
  54. }
  55. }, [add, showPanel]);
  56. React.useEffect(() => {
  57. if (showPanel) {
  58. reset();
  59. }
  60. }, [reset, showPanel]);
  61. const countStr = count > 9 ? "9+" : `${count}`;
  62. return (
  63. <>
  64. <div style={{ position: "relative" }}>
  65. <Touch
  66. onClick={() => setShowPanel((prev) => !prev)}
  67. alt={t("Chat")}
  68. title={t("Chat")}
  69. label={t("Chat")}
  70. icon={"message"}
  71. active={showPanel}
  72. />
  73. {count > 0 && <NotifCount>{countStr}</NotifCount>}
  74. </div>
  75. <MessagePanel
  76. onNewMessage={onNewMessage}
  77. show={showPanel}
  78. setShow={setShowPanel}
  79. />
  80. </>
  81. );
  82. };
  83. export default MessageButton;