Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

PollResults.js 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // @flow
  2. import React, { useCallback } from 'react';
  3. import { FlatList, Text, TouchableOpacity, View } from 'react-native';
  4. import { useSelector } from 'react-redux';
  5. import { getLocalParticipant } from '../../../base/participants';
  6. import AbstractPollResults from '../AbstractPollResults';
  7. import type { AbstractProps, AnswerInfo } from '../AbstractPollResults';
  8. import { chatStyles, dialogStyles, resultsStyles } from './styles';
  9. /**
  10. * Component that renders the poll results.
  11. *
  12. * @param {Props} props - The passed props.
  13. * @returns {React.Node}
  14. */
  15. const PollResults = (props: AbstractProps) => {
  16. const {
  17. answers,
  18. changeVote,
  19. haveVoted,
  20. question,
  21. showDetails,
  22. t,
  23. toggleIsDetailed
  24. } = props;
  25. /**
  26. * Render a header summing up answer information.
  27. *
  28. * @param {string} answer - The name of the answer.
  29. * @param {number} percentage - The percentage of voters.
  30. * @param {number} nbVotes - The number of collected votes.
  31. * @returns {React.Node}
  32. */
  33. const renderHeader = (answer: string, percentage: number, nbVotes: number) => (
  34. <View style = { resultsStyles.answerHeader }>
  35. <Text style = { resultsStyles.answer }>{ answer }</Text>
  36. <View>
  37. <Text style = { resultsStyles.answer }>({nbVotes}) {percentage}%</Text>
  38. </View>
  39. </View>
  40. );
  41. /**
  42. * Render voters of and answer.
  43. *
  44. * @param {AnswerInfo} answer - The answer info.
  45. * @returns {React.Node}
  46. */
  47. const renderRow = useCallback((answer: AnswerInfo) => {
  48. const { name, percentage, voters, voterCount } = answer;
  49. if (showDetails) {
  50. return (
  51. <View style = { resultsStyles.answerContainer }>
  52. { renderHeader(name, percentage, voterCount) }
  53. <View style = { resultsStyles.barContainer }>
  54. <View style = { [ resultsStyles.bar, { width: `${percentage}%` } ] } />
  55. </View>
  56. { voters && voterCount > 0
  57. && <View style = { resultsStyles.voters }>
  58. {voters.map(({ id, name: voterName }) =>
  59. (<Text
  60. key = { id }
  61. style = { resultsStyles.voter }>
  62. { voterName }
  63. </Text>)
  64. )}
  65. </View>}
  66. </View>
  67. );
  68. }
  69. // else, we display a simple list
  70. // We add a progress bar by creating an empty view of width equal to percentage.
  71. return (
  72. <View style = { resultsStyles.answerContainer }>
  73. { renderHeader(answer.name, percentage, voterCount) }
  74. <View style = { resultsStyles.barContainer }>
  75. <View style = { [ resultsStyles.bar, { width: `${percentage}%` } ] } />
  76. </View>
  77. </View>
  78. );
  79. }, [ showDetails ]);
  80. const localParticipant = useSelector(getLocalParticipant);
  81. /* eslint-disable react/jsx-no-bind */
  82. return (
  83. <View>
  84. <Text style = { dialogStyles.questionText } >{ question }</Text>
  85. <Text style = { dialogStyles.questionOwnerText } >{ t('polls.by', { name: localParticipant.name }) }</Text>
  86. <FlatList
  87. data = { answers }
  88. keyExtractor = { (item, index) => index.toString() }
  89. renderItem = { answer => renderRow(answer.item) } />
  90. <View style = { chatStyles.bottomLinks }>
  91. <TouchableOpacity onPress = { toggleIsDetailed }>
  92. <Text
  93. style = { chatStyles.toggleText }>
  94. {
  95. showDetails
  96. ? t('polls.results.hideDetailedResults')
  97. : t('polls.results.showDetailedResults')
  98. }
  99. </Text>
  100. </TouchableOpacity>
  101. <TouchableOpacity onPress = { changeVote }>
  102. <Text
  103. style = { chatStyles.toggleText }>
  104. {
  105. haveVoted
  106. ? t('polls.results.changeVote')
  107. : t('polls.results.vote')
  108. }
  109. </Text>
  110. </TouchableOpacity>
  111. </View>
  112. </View>
  113. );
  114. };
  115. /*
  116. * We apply AbstractPollResults to fill in the AbstractProps common
  117. * to both the web and native implementations.
  118. */
  119. // eslint-disable-next-line new-cap
  120. export default AbstractPollResults(PollResults);