Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

AbstractPollCreate.tsx 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import React, { ComponentType, FormEvent, useCallback, useState } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { useSelector } from 'react-redux';
  4. import { createPollEvent } from '../../analytics/AnalyticsEvents';
  5. import { sendAnalytics } from '../../analytics/functions';
  6. import { IReduxState } from '../../app/types';
  7. import { COMMAND_NEW_POLL } from '../constants';
  8. import { hasIdenticalAnswers } from '../functions';
  9. /**
  10. * The type of the React {@code Component} props of inheriting component.
  11. */
  12. type InputProps = {
  13. setCreateMode: (mode: boolean) => void;
  14. };
  15. /*
  16. * Props that will be passed by the AbstractPollCreate to its
  17. * concrete implementations (web/native).
  18. **/
  19. export type AbstractProps = InputProps & {
  20. addAnswer: (index?: number) => void;
  21. answers: Array<string>;
  22. isSubmitDisabled: boolean;
  23. onSubmit: (event?: FormEvent<HTMLFormElement>) => void;
  24. question: string;
  25. removeAnswer: (index: number) => void;
  26. setAnswer: (index: number, value: string) => void;
  27. setQuestion: (question: string) => void;
  28. t: Function;
  29. };
  30. /**
  31. * Higher Order Component taking in a concrete PollCreate component and
  32. * augmenting it with state/behavior common to both web and native implementations.
  33. *
  34. * @param {React.AbstractComponent} Component - The concrete component.
  35. * @returns {React.AbstractComponent}
  36. */
  37. const AbstractPollCreate = (Component: ComponentType<AbstractProps>) => (props: InputProps) => {
  38. const { setCreateMode } = props;
  39. const [ question, setQuestion ] = useState('');
  40. const [ answers, setAnswers ] = useState([ '', '' ]);
  41. const setAnswer = useCallback((i, answer) => {
  42. setAnswers(currentAnswers => {
  43. const newAnswers = [ ...currentAnswers ];
  44. newAnswers[i] = answer;
  45. return newAnswers;
  46. });
  47. }, [ answers ]);
  48. const addAnswer = useCallback((i?: number) => {
  49. const newAnswers = [ ...answers ];
  50. sendAnalytics(createPollEvent('option.added'));
  51. newAnswers.splice(typeof i === 'number' ? i : answers.length, 0, '');
  52. setAnswers(newAnswers);
  53. }, [ answers ]);
  54. const removeAnswer = useCallback(i => {
  55. if (answers.length <= 2) {
  56. return;
  57. }
  58. const newAnswers = [ ...answers ];
  59. sendAnalytics(createPollEvent('option.removed'));
  60. newAnswers.splice(i, 1);
  61. setAnswers(newAnswers);
  62. }, [ answers ]);
  63. const conference = useSelector((state: IReduxState) => state['features/base/conference'].conference);
  64. const onSubmit = useCallback(ev => {
  65. if (ev) {
  66. ev.preventDefault();
  67. }
  68. const filteredAnswers = answers.filter(answer => answer.trim().length > 0);
  69. if (filteredAnswers.length < 2) {
  70. return;
  71. }
  72. conference?.sendMessage({
  73. type: COMMAND_NEW_POLL,
  74. pollId: Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36),
  75. question,
  76. answers: filteredAnswers
  77. });
  78. sendAnalytics(createPollEvent('created'));
  79. setCreateMode(false);
  80. }, [ conference, question, answers ]);
  81. // Check if the poll create form can be submitted i.e. if the send button should be disabled.
  82. const isSubmitDisabled
  83. = question.trim().length <= 0 // If no question is provided
  84. || answers.filter(answer => answer.trim().length > 0).length < 2 // If not enough options are provided
  85. || hasIdenticalAnswers(answers); // If duplicate options are provided
  86. const { t } = useTranslation();
  87. return (<Component
  88. addAnswer = { addAnswer }
  89. answers = { answers }
  90. isSubmitDisabled = { isSubmitDisabled }
  91. onSubmit = { onSubmit }
  92. question = { question }
  93. removeAnswer = { removeAnswer }
  94. setAnswer = { setAnswer }
  95. setCreateMode = { setCreateMode }
  96. setQuestion = { setQuestion }
  97. t = { t } />);
  98. };
  99. export default AbstractPollCreate;