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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. <Text style = { resultsStyles.answer }>({nbVotes}) {percentage}%</Text>
  36. {/* <Text style = { resultsStyles.answer }>{ answer } - { percentage }%</Text>
  37. <Text style = { resultsStyles.answerVoteCount }>
  38. { t('polls.answer.vote', { count: nbVotes }) }
  39. </Text> */}
  40. </View>
  41. );
  42. /**
  43. * Render voters of and answer
  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. { voters && voterCount > 0
  54. && <View style = { resultsStyles.voters }>
  55. {voters.map(({ id, name: voterName }) =>
  56. <Text key = { id }>{ voterName }</Text>
  57. )}
  58. </View>}
  59. </View>
  60. );
  61. }
  62. // else, we display a simple list
  63. // We add a progress bar by creating an empty view of width equal to percentage.
  64. return (
  65. <View style = { resultsStyles.answerContainer }>
  66. { renderHeader(answer.name, percentage, voterCount) }
  67. <View style = { resultsStyles.barContainer }>
  68. <View style = { [ resultsStyles.bar, { width: `${percentage}%` } ] } />
  69. </View>
  70. </View>
  71. );
  72. }, [ showDetails ]);
  73. /* eslint-disable react/jsx-no-bind */
  74. return (
  75. <View>
  76. <View>
  77. <Text style = { dialogStyles.question } >{ question }</Text>
  78. </View>
  79. <FlatList
  80. data = { answers }
  81. keyExtractor = { (item, index) => index.toString() }
  82. renderItem = { answer => renderRow(answer.item) } />
  83. <View style = { chatStyles.bottomLinks }>
  84. <TouchableOpacity onPress = { toggleIsDetailed }>
  85. <Text
  86. style = { chatStyles.toggleText }>
  87. {showDetails ? t('polls.results.hideDetailedResults') : t('polls.results.showDetailedResults')}
  88. </Text>
  89. </TouchableOpacity>
  90. <TouchableOpacity onPress = { changeVote }>
  91. <Text
  92. style = { chatStyles.toggleText }>
  93. {haveVoted ? t('polls.results.changeVote') : t('polls.results.vote')}
  94. </Text>
  95. </TouchableOpacity>
  96. </View>
  97. </View>
  98. );
  99. };
  100. /*
  101. * We apply AbstractPollResults to fill in the AbstractProps common
  102. * to both the web and native implementations.
  103. */
  104. // eslint-disable-next-line new-cap
  105. export default AbstractPollResults(PollResults);