feat(Polls): Display creator name for polls

This commit is contained in:
Vlad Piersec 2021-11-02 13:01:58 +02:00 committed by vp8x8
parent 8983ea41fd
commit e51655a93a
7 changed files with 39 additions and 2 deletions

View File

@ -21,6 +21,12 @@
margin-bottom: 8px; margin-bottom: 8px;
} }
.poll-creator {
color: #C2C2C2;
font-weight: 600;
margin: 4px 0 16px 0;
}
.poll-answer-container { .poll-answer-container {
background: #3D3D3D; background: #3D3D3D;
border-radius: 3px; border-radius: 3px;
@ -134,7 +140,7 @@ ol.poll-result-list {
.poll-question { .poll-question {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
margin-bottom: 16px; line-height: 26px;
} }
.poll-answer-voters { .poll-answer-voters {

View File

@ -634,6 +634,7 @@
"passwordSetRemotely": "Set by another participant", "passwordSetRemotely": "Set by another participant",
"passwordDigitsOnly": "Up to {{number}} digits", "passwordDigitsOnly": "Up to {{number}} digits",
"polls": { "polls": {
"by": "By {{ name }}",
"create": { "create": {
"addOption": "Add option", "addOption": "Add option",
"answerPlaceholder": "Option {{index}}", "answerPlaceholder": "Option {{index}}",

View File

@ -0,0 +1,13 @@
// @flow
import { useSelector } from 'react-redux';
/**
* Takes a redux selector and binds it to specific values.
*
* @param {Function} selector - The selector function.
* @param {...any} args - The values to bind to.
* @returns {any}
*/
export function useBoundSelector(selector: Function, ...args: any[]) {
return useSelector(state => selector(state, ...args));
}

View File

@ -7,6 +7,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { sendAnalytics, createPollEvent } from '../../analytics'; import { sendAnalytics, createPollEvent } from '../../analytics';
import { getLocalParticipant, getParticipantById } from '../../base/participants'; import { getLocalParticipant, getParticipantById } from '../../base/participants';
import { useBoundSelector } from '../../base/util/hooks';
import { registerVote, setVoteChanging } from '../actions'; import { registerVote, setVoteChanging } from '../actions';
import { COMMAND_ANSWER_POLL } from '../constants'; import { COMMAND_ANSWER_POLL } from '../constants';
import type { Poll } from '../types'; import type { Poll } from '../types';
@ -24,6 +25,7 @@ type InputProps = {
**/ **/
export type AbstractProps = { export type AbstractProps = {
checkBoxStates: Function, checkBoxStates: Function,
creatorName: string,
poll: Poll, poll: Poll,
setCheckbox: Function, setCheckbox: Function,
skipAnswer: Function, skipAnswer: Function,
@ -56,6 +58,7 @@ const AbstractPollAnswer = (Component: AbstractComponent<AbstractProps>) => (pro
return new Array(poll.answers.length).fill(false); return new Array(poll.answers.length).fill(false);
}); });
const participant = useBoundSelector(getParticipantById, poll.senderId);
const setCheckbox = useCallback((index, state) => { const setCheckbox = useCallback((index, state) => {
const newCheckBoxStates = [ ...checkBoxStates ]; const newCheckBoxStates = [ ...checkBoxStates ];
@ -67,7 +70,7 @@ const AbstractPollAnswer = (Component: AbstractComponent<AbstractProps>) => (pro
const dispatch = useDispatch(); const dispatch = useDispatch();
const localParticipant = useSelector(state => getParticipantById(state, localId)); const localParticipant = useBoundSelector(getParticipantById, localId);
const localName: string = localParticipant.name ? localParticipant.name : 'Fellow Jitster'; const localName: string = localParticipant.name ? localParticipant.name : 'Fellow Jitster';
const submitAnswer = useCallback(() => { const submitAnswer = useCallback(() => {
@ -99,6 +102,7 @@ const AbstractPollAnswer = (Component: AbstractComponent<AbstractProps>) => (pro
return (<Component return (<Component
checkBoxStates = { checkBoxStates } checkBoxStates = { checkBoxStates }
creatorName = { participant ? participant.name : '' }
poll = { poll } poll = { poll }
setCheckbox = { setCheckbox } setCheckbox = { setCheckbox }
skipAnswer = { skipAnswer } skipAnswer = { skipAnswer }

View File

@ -6,6 +6,8 @@ import { useTranslation } from 'react-i18next';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { sendAnalytics, createPollEvent } from '../../analytics'; import { sendAnalytics, createPollEvent } from '../../analytics';
import { getParticipantById } from '../../base/participants/functions';
import { useBoundSelector } from '../../base/util/hooks';
import { setVoteChanging } from '../actions'; import { setVoteChanging } from '../actions';
import { getPoll } from '../functions'; import { getPoll } from '../functions';
@ -33,6 +35,7 @@ export type AnswerInfo = {
export type AbstractProps = { export type AbstractProps = {
answers: Array<AnswerInfo>, answers: Array<AnswerInfo>,
changeVote: Function, changeVote: Function,
creatorName: string,
showDetails: boolean, showDetails: boolean,
question: string, question: string,
t: Function, t: Function,
@ -51,6 +54,7 @@ const AbstractPollResults = (Component: AbstractComponent<AbstractProps>) => (pr
const { pollId } = props; const { pollId } = props;
const pollDetails = useSelector(getPoll(pollId)); const pollDetails = useSelector(getPoll(pollId));
const participant = useBoundSelector(getParticipantById, pollDetails.senderId);
const [ showDetails, setShowDetails ] = useState(false); const [ showDetails, setShowDetails ] = useState(false);
const toggleIsDetailed = useCallback(() => { const toggleIsDetailed = useCallback(() => {
@ -105,6 +109,7 @@ const AbstractPollResults = (Component: AbstractComponent<AbstractProps>) => (pr
<Component <Component
answers = { answers } answers = { answers }
changeVote = { changeVote } changeVote = { changeVote }
creatorName = { participant ? participant.name : '' }
haveVoted = { pollDetails.lastVote !== null } haveVoted = { pollDetails.lastVote !== null }
question = { pollDetails.question } question = { pollDetails.question }
showDetails = { showDetails } showDetails = { showDetails }

View File

@ -9,6 +9,7 @@ import type { AbstractProps } from '../AbstractPollAnswer';
const PollAnswer = (props: AbstractProps) => { const PollAnswer = (props: AbstractProps) => {
const { const {
creatorName,
checkBoxStates, checkBoxStates,
poll, poll,
setCheckbox, setCheckbox,
@ -25,6 +26,9 @@ const PollAnswer = (props: AbstractProps) => {
<div className = 'poll-question'> <div className = 'poll-question'>
<span>{ poll.question }</span> <span>{ poll.question }</span>
</div> </div>
<div className = 'poll-creator'>
{ t('polls.by', { name: creatorName }) }
</div>
</div> </div>
<ol className = 'poll-answer-list'> <ol className = 'poll-answer-list'>
{ {

View File

@ -16,6 +16,7 @@ const PollResults = (props: AbstractProps) => {
const { const {
answers, answers,
changeVote, changeVote,
creatorName,
haveVoted, haveVoted,
showDetails, showDetails,
question, question,
@ -29,6 +30,9 @@ const PollResults = (props: AbstractProps) => {
<div className = 'poll-question'> <div className = 'poll-question'>
<strong>{ question }</strong> <strong>{ question }</strong>
</div> </div>
<div className = 'poll-creator'>
{ t('polls.by', { name: creatorName }) }
</div>
</div> </div>
<ol className = 'poll-result-list'> <ol className = 'poll-result-list'>
{answers.map(({ name, percentage, voters, voterCount }, index) => {answers.map(({ name, percentage, voters, voterCount }, index) =>