You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PollResults.js 4.1KB

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