UNPKG

@100mslive/react-native-room-kit

Version:

100ms Room Kit provides simple & easy to use UI components to build Live Streaming & Video Conferencing experiences in your apps.

224 lines (223 loc) 10.5 kB
import * as React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; import { HMSPollQuestionType, HMSPollState, HMSPollType } from '@100mslive/react-native-hms'; import { useHMSInstance, useHMSRoomColorPalette, useHMSRoomStyleSheet } from '../hooks-util'; import { RadioInputRow } from './RadioInputRow'; import { HMSPrimaryButton } from './HMSPrimaryButton'; import { HMSBaseButton } from './HMSBaseButton'; import { addPollQuestionResponse, removePollQuestionResponse, setPollQuestionResponse } from '../redux/actions'; import { PollResponseProgressView } from './PollResponseProgressView'; import { CheckboxInputRow } from './CheckboxInputRow'; import { checkIsCorrectAnswer, checkIsCorrectOption, checkIsSelected, getLabelFromPollQuestionType } from '../utils/functions'; import { CheckIcon, CrossCircleIcon } from '../Icons'; import { QuizEndOptionsView } from './QuizEndOptionsView'; export const PollAndQuizQuestionResponseCard = ({ pollState, totalQuestions, pollId, pollQuestion, containerStyle, onSubmit }) => { var _pollQuestion$options, _pollQuestion$options2, _pollQuestion$options3; const { primary_bright: primaryBrightColor, on_surface_low: onSurfaceLowColor } = useHMSRoomColorPalette(); const hmsRoomStyles = useHMSRoomStyleSheet((theme, typography) => ({ container: { backgroundColor: theme.palette.surface_default, borderColor: theme.palette.surface_default }, surfaceLowSemiBoldText: { color: theme.palette.on_surface_low, fontFamily: `${typography.font_family}-SemiBold` }, surfaceHighRegularText: { color: theme.palette.on_surface_high, fontFamily: `${typography.font_family}-Regular` }, wrongAnswer: { borderColor: theme.palette.alert_error_default }, correctAnswer: { borderColor: theme.palette.alert_success }, wrongAnswerText: { color: theme.palette.alert_error_default }, correctAnswerText: { color: theme.palette.alert_success }, wrongAnswerIcon: { tintColor: theme.palette.alert_error_default }, correctAnswerIcon: { tintColor: theme.palette.alert_success }, skipButton: { borderColor: theme.palette.border_bright, borderWidth: 1, marginRight: 16 }, skipButtonText: { color: theme.palette.on_surface_high, fontFamily: `${typography.font_family}-SemiBold` } })); // variable to save timestamp when the question became visible to user const startTime = React.useRef(null); React.useEffect(() => { startTime.current = Date.now(); }, [pollQuestion.index]); const hmsInstance = useHMSInstance(); const dispatch = useDispatch(); const selectedOptions = useSelector(state => { var _state$polls$pollsRes; return ((_state$polls$pollsRes = state.polls.pollsResponses[pollId]) === null || _state$polls$pollsRes === void 0 ? void 0 : _state$polls$pollsRes[pollQuestion.index]) ?? null; }); const pollType = useSelector(state => { var _state$polls$polls$po; return ((_state$polls$polls$po = state.polls.polls[pollId]) === null || _state$polls$polls$po === void 0 ? void 0 : _state$polls$polls$po.type) ?? HMSPollType.poll; }); const canViewPollResponse = useSelector(state => { var _state$hmsStates$loca, _state$polls$polls$po2; const localPeerRole = (_state$hmsStates$loca = state.hmsStates.localPeer) === null || _state$hmsStates$loca === void 0 ? void 0 : _state$hmsStates$loca.role; const rolesThatCanViewResponses = (_state$polls$polls$po2 = state.polls.polls[pollId]) === null || _state$polls$polls$po2 === void 0 ? void 0 : _state$polls$polls$po2.rolesThatCanViewResponses; return Array.isArray(rolesThatCanViewResponses) && rolesThatCanViewResponses.length > 0 ? localPeerRole && rolesThatCanViewResponses.findIndex(role => role.name === localPeerRole.name) !== -1 : true; }); const handleOptionSelection = (selected, option) => { if (pollQuestion.type === HMSPollQuestionType.singleChoice) { dispatch(setPollQuestionResponse(pollId, pollQuestion.index, option.index)); } else { if (selected) { dispatch(addPollQuestionResponse(pollId, pollQuestion.index, option.index)); } else { dispatch(removePollQuestionResponse(pollId, pollQuestion.index, option.index)); } } }; const handleVotePress = async e => { if (!selectedOptions) { return; } onSubmit === null || onSubmit === void 0 || onSubmit(e); const result = await hmsInstance.interactivityCenter.add({ pollId, pollQuestionIndex: pollQuestion.index, responses: { options: Array.isArray(selectedOptions) ? selectedOptions : [selectedOptions], duration: pollType === HMSPollType.quiz && startTime.current !== null ? Date.now() - startTime.current : undefined } }); console.log(JSON.stringify(result, null, 4)); }; const handleSkipPress = async e => { onSubmit === null || onSubmit === void 0 || onSubmit(e); // TODO: Implement skip API }; const anyOptionSelected = Array.isArray(selectedOptions) ? selectedOptions.length > 0 : selectedOptions !== null; const isVoted = pollQuestion.myResponses.length > 0; const InputComponent = pollQuestion.type === HMSPollQuestionType.singleChoice ? RadioInputRow : pollQuestion.type === HMSPollQuestionType.multipleChoice ? CheckboxInputRow : null; const isCorrectAnswer = checkIsCorrectAnswer(pollQuestion.type, pollQuestion.myResponses, pollQuestion.answer); return /*#__PURE__*/React.createElement(View, { style: [hmsRoomStyles.container, styles.container, pollType === HMSPollType.quiz && isVoted && pollState === HMSPollState.stopped ? isCorrectAnswer ? hmsRoomStyles.correctAnswer : hmsRoomStyles.wrongAnswer : null, containerStyle] }, /*#__PURE__*/React.createElement(View, { style: { flexDirection: 'row' } }, pollType === HMSPollType.quiz && isVoted && pollState === HMSPollState.stopped ? isCorrectAnswer ? /*#__PURE__*/React.createElement(CheckIcon, { type: "in-circle", style: [hmsRoomStyles.correctAnswerIcon, { marginRight: 8, width: 16, height: 16 }] }) : /*#__PURE__*/React.createElement(CrossCircleIcon, { style: [hmsRoomStyles.wrongAnswerIcon, { marginRight: 8, width: 16, height: 16 }] }) : null, /*#__PURE__*/React.createElement(Text, { numberOfLines: 2, style: [styles.tinyText, hmsRoomStyles.surfaceLowSemiBoldText, styles.uppercaseContent, pollType === HMSPollType.quiz && isVoted && pollState === HMSPollState.stopped ? isCorrectAnswer ? hmsRoomStyles.correctAnswerText : hmsRoomStyles.wrongAnswerText : null] }, "Question ", pollQuestion.index, " of ", totalQuestions, ":", ' ', getLabelFromPollQuestionType(pollQuestion.type))), /*#__PURE__*/React.createElement(Text, { style: [hmsRoomStyles.surfaceHighRegularText, styles.regularText, styles.verticalNormalSpacer] }, pollQuestion.text), !InputComponent ? null : /*#__PURE__*/React.createElement(React.Fragment, null, pollType === HMSPollType.poll && canViewPollResponse && (pollQuestion.myResponses.length > 0 || pollState === HMSPollState.stopped) ? /*#__PURE__*/React.createElement(React.Fragment, null, (_pollQuestion$options = pollQuestion.options) === null || _pollQuestion$options === void 0 ? void 0 : _pollQuestion$options.sort((a, b) => a.index - b.index).map((option, _, arr) => { return /*#__PURE__*/React.createElement(PollResponseProgressView, { key: option.index, option: option, totalVotes: arr.reduce((acc, curr) => acc + curr.voteCount, 0) }); })) : pollType === HMSPollType.quiz && pollState === HMSPollState.stopped ? /*#__PURE__*/React.createElement(React.Fragment, null, (_pollQuestion$options2 = pollQuestion.options) === null || _pollQuestion$options2 === void 0 ? void 0 : _pollQuestion$options2.sort((a, b) => a.index - b.index).map(option => { const isSelected = checkIsSelected(pollQuestion, option, null); const isCorrect = checkIsCorrectOption(pollQuestion.type, option, pollQuestion.answer); return /*#__PURE__*/React.createElement(QuizEndOptionsView, { key: option.index, option: option, isSelected: isSelected, isCorrect: isCorrect }); })) : /*#__PURE__*/React.createElement(React.Fragment, null, (_pollQuestion$options3 = pollQuestion.options) === null || _pollQuestion$options3 === void 0 ? void 0 : _pollQuestion$options3.sort((a, b) => a.index - b.index).map(option => { const isSelected = checkIsSelected(pollQuestion, option, selectedOptions); return /*#__PURE__*/React.createElement(InputComponent, { key: option.index, disabled: isVoted, selected: isSelected, radioColor: isVoted ? isSelected ? primaryBrightColor : onSurfaceLowColor : undefined, onChange: selected => handleOptionSelection(selected, option), text: option.text, containerStyle: { marginBottom: 16 } }); }))), isVoted && (pollType === HMSPollType.poll || pollState === HMSPollState.started) ? /*#__PURE__*/React.createElement(Text, { style: [styles.regularText, styles.votedLabel, hmsRoomStyles.surfaceLowSemiBoldText] }, pollType === HMSPollType.quiz ? 'Answered' : 'Voted') : pollState === HMSPollState.started ? /*#__PURE__*/React.createElement(View, { style: { alignSelf: 'flex-end', flexDirection: 'row' } }, pollQuestion.skippable ? /*#__PURE__*/React.createElement(HMSBaseButton, { loading: false, onPress: handleSkipPress, title: "Skip", style: hmsRoomStyles.skipButton, textStyle: hmsRoomStyles.skipButtonText, useTouchableOpacity: true }) : null, /*#__PURE__*/React.createElement(HMSPrimaryButton, { loading: false, disabled: !anyOptionSelected, onPress: handleVotePress, title: pollType === HMSPollType.quiz ? 'Answer' : 'Vote' })) : null); }; const styles = StyleSheet.create({ container: { padding: 16, borderRadius: 8, borderWidth: 1 }, tinyText: { fontSize: 10, lineHeight: 16, letterSpacing: 1.5 }, regularText: { fontSize: 16, lineHeight: 24 }, verticalNormalSpacer: { marginVertical: 16 }, votedLabel: { paddingVertical: 8, alignSelf: 'flex-end' }, uppercaseContent: { textTransform: 'uppercase' } }); //# sourceMappingURL=PollAndQuizQuestionResponseCard.js.map