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

PollResults.js 4.7KB

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