您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

AbstractPollCreate.js 4.1KB

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