115 lines
3.7 KiB
TypeScript
115 lines
3.7 KiB
TypeScript
import React, { ComponentType, useCallback, useState } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
|
|
import { createPollEvent } from '../../analytics/AnalyticsEvents';
|
|
import { sendAnalytics } from '../../analytics/functions';
|
|
import { IReduxState } from '../../app/types';
|
|
import { getLocalParticipant, getParticipantById } from '../../base/participants/functions';
|
|
import { useBoundSelector } from '../../base/util/hooks';
|
|
import { registerVote, setVoteChanging } from '../actions';
|
|
import { COMMAND_ANSWER_POLL } from '../constants';
|
|
import { IPoll } from '../types';
|
|
|
|
/**
|
|
* The type of the React {@code Component} props of inheriting component.
|
|
*/
|
|
type InputProps = {
|
|
pollId: string;
|
|
};
|
|
|
|
/*
|
|
* Props that will be passed by the AbstractPollAnswer to its
|
|
* concrete implementations (web/native).
|
|
**/
|
|
export type AbstractProps = {
|
|
checkBoxStates: boolean[];
|
|
creatorName: string;
|
|
poll: IPoll;
|
|
setCheckbox: Function;
|
|
skipAnswer: () => void;
|
|
skipChangeVote: () => void;
|
|
submitAnswer: () => void;
|
|
t: Function;
|
|
};
|
|
|
|
/**
|
|
* Higher Order Component taking in a concrete PollAnswer component and
|
|
* augmenting it with state/behavior common to both web and native implementations.
|
|
*
|
|
* @param {React.AbstractComponent} Component - The concrete component.
|
|
* @returns {React.AbstractComponent}
|
|
*/
|
|
const AbstractPollAnswer = (Component: ComponentType<AbstractProps>) => (props: InputProps) => {
|
|
|
|
const { pollId } = props;
|
|
|
|
const conference: any = useSelector((state: IReduxState) => state['features/base/conference'].conference);
|
|
|
|
const poll: IPoll = useSelector((state: IReduxState) => state['features/polls'].polls[pollId]);
|
|
|
|
const { id: localId } = useSelector(getLocalParticipant) ?? { id: '' };
|
|
|
|
const [ checkBoxStates, setCheckBoxState ] = useState(() => {
|
|
if (poll.lastVote !== null) {
|
|
return [ ...poll.lastVote ];
|
|
}
|
|
|
|
return new Array(poll.answers.length).fill(false);
|
|
});
|
|
const participant = useBoundSelector(getParticipantById, poll.senderId);
|
|
|
|
const setCheckbox = useCallback((index, state) => {
|
|
const newCheckBoxStates = [ ...checkBoxStates ];
|
|
|
|
newCheckBoxStates[index] = state;
|
|
setCheckBoxState(newCheckBoxStates);
|
|
sendAnalytics(createPollEvent('vote.checked'));
|
|
}, [ checkBoxStates ]);
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
const localParticipant = useBoundSelector(getParticipantById, localId);
|
|
const localName: string = localParticipant.name ? localParticipant.name : 'Fellow Jitster';
|
|
|
|
const submitAnswer = useCallback(() => {
|
|
conference.sendMessage({
|
|
type: COMMAND_ANSWER_POLL,
|
|
pollId,
|
|
voterId: localId,
|
|
voterName: localName,
|
|
answers: checkBoxStates
|
|
});
|
|
|
|
sendAnalytics(createPollEvent('vote.sent'));
|
|
dispatch(registerVote(pollId, checkBoxStates));
|
|
|
|
return false;
|
|
}, [ pollId, localId, localName, checkBoxStates, conference ]);
|
|
|
|
const skipAnswer = useCallback(() => {
|
|
dispatch(registerVote(pollId, null));
|
|
sendAnalytics(createPollEvent('vote.skipped'));
|
|
|
|
}, [ pollId ]);
|
|
|
|
const skipChangeVote = useCallback(() => {
|
|
dispatch(setVoteChanging(pollId, false));
|
|
}, [ dispatch, pollId ]);
|
|
|
|
const { t } = useTranslation();
|
|
|
|
return (<Component
|
|
checkBoxStates = { checkBoxStates }
|
|
creatorName = { participant ? participant.name : '' }
|
|
poll = { poll }
|
|
setCheckbox = { setCheckbox }
|
|
skipAnswer = { skipAnswer }
|
|
skipChangeVote = { skipChangeVote }
|
|
submitAnswer = { submitAnswer }
|
|
t = { t } />);
|
|
|
|
};
|
|
|
|
export default AbstractPollAnswer;
|