MessageVisiblityToggle.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Custom component for AntDesign Button that makes an api call, then displays a confirmation icon upon
  2. import React, { useState, useEffect, FC } from 'react';
  3. import { Button, Tooltip } from 'antd';
  4. import {
  5. EyeOutlined,
  6. EyeInvisibleOutlined,
  7. CheckCircleFilled,
  8. ExclamationCircleFilled,
  9. } from '@ant-design/icons';
  10. import { fetchData, UPDATE_CHAT_MESSGAE_VIZ } from '../utils/apis';
  11. import { MessageType } from '../types/chat';
  12. import { OUTCOME_TIMEOUT } from '../pages/admin/chat/messages';
  13. import { isEmptyObject } from '../utils/format';
  14. export type MessageToggleProps = {
  15. isVisible: boolean;
  16. message: MessageType;
  17. setMessage: (message: MessageType) => void;
  18. };
  19. export const MessageVisiblityToggle: FC<MessageToggleProps> = ({
  20. isVisible,
  21. message,
  22. setMessage,
  23. }) => {
  24. if (!message || isEmptyObject(message)) {
  25. return null;
  26. }
  27. let outcomeTimeout = null;
  28. const [outcome, setOutcome] = useState(0);
  29. const { id: messageId } = message || {};
  30. const resetOutcome = () => {
  31. outcomeTimeout = setTimeout(() => {
  32. setOutcome(0);
  33. }, OUTCOME_TIMEOUT);
  34. };
  35. useEffect(() => () => {
  36. clearTimeout(outcomeTimeout);
  37. });
  38. const updateChatMessage = async () => {
  39. clearTimeout(outcomeTimeout);
  40. setOutcome(0);
  41. const result = await fetchData(UPDATE_CHAT_MESSGAE_VIZ, {
  42. auth: true,
  43. method: 'POST',
  44. data: {
  45. visible: !isVisible,
  46. idArray: [messageId],
  47. },
  48. });
  49. if (result.success && result.message === 'changed') {
  50. setMessage({ ...message, visible: !isVisible });
  51. setOutcome(1);
  52. } else {
  53. setMessage({ ...message, visible: isVisible });
  54. setOutcome(-1);
  55. }
  56. resetOutcome();
  57. };
  58. let outcomeIcon = <CheckCircleFilled style={{ color: 'transparent' }} />;
  59. if (outcome) {
  60. outcomeIcon =
  61. outcome > 0 ? (
  62. <CheckCircleFilled style={{ color: 'var(--ant-success)' }} />
  63. ) : (
  64. <ExclamationCircleFilled style={{ color: 'var(--ant-warning)' }} />
  65. );
  66. }
  67. const toolTipMessage = `Click to ${isVisible ? 'hide' : 'show'} this message`;
  68. return (
  69. <div className={`toggle-switch ${isVisible ? '' : 'hidden'}`}>
  70. <span className="outcome-icon">{outcomeIcon}</span>
  71. <Tooltip title={toolTipMessage} placement="topRight">
  72. <Button
  73. shape="circle"
  74. size="small"
  75. type="text"
  76. icon={isVisible ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  77. onClick={updateChatMessage}
  78. />
  79. </Tooltip>
  80. </div>
  81. );
  82. };