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

PollResults.js 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. *
  47. * @param {AnswerInfo} answer - The answer info.
  48. * @returns {React.Node}
  49. */
  50. const renderRow = useCallback((answer: AnswerInfo) => {
  51. const { name, percentage, voters, voterCount } = answer;
  52. if (showDetails) {
  53. return (
  54. <View style = { resultsStyles.answerContainer }>
  55. { renderHeader(name, percentage, voterCount) }
  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. /* eslint-disable react/jsx-no-bind */
  81. return (
  82. <View>
  83. <View>
  84. <Text style = { dialogStyles.question } >{ question }</Text>
  85. </View>
  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. {showDetails ? t('polls.results.hideDetailedResults') : t('polls.results.showDetailedResults')}
  95. </Text>
  96. </TouchableOpacity>
  97. <TouchableOpacity onPress = { changeVote }>
  98. <Text
  99. style = { chatStyles.toggleText }>
  100. {haveVoted ? t('polls.results.changeVote') : t('polls.results.vote')}
  101. </Text>
  102. </TouchableOpacity>
  103. </View>
  104. </View>
  105. );
  106. };
  107. /*
  108. * We apply AbstractPollResults to fill in the AbstractProps common
  109. * to both the web and native implementations.
  110. */
  111. // eslint-disable-next-line new-cap
  112. export default AbstractPollResults(PollResults);