react-native-chating-ui-kit
Version:
CometChat React Native UI Kit is a collection of custom UI Components designed to build text , chat and calling features in your application. The UI Kit is developed to keep developers in mind and aims to reduce development efforts significantly
202 lines (201 loc) • 7.37 kB
JavaScript
import { View, Text, TouchableOpacity, StyleSheet, Image } from 'react-native';
import React, { useContext, useLayoutEffect, useRef, useState } from 'react';
import { CometChatContext } from "../../shared/CometChatContext";
import { makeExtentionCall } from '../../shared/utils/CometChatMessageHelper';
import { ICONS } from './resources';
export const PollsBubble = (props) => {
const { pollQuestion, options, pollId, loggedInUser, choosePoll, senderUid, metadata, pollsBubbleStyle, } = props;
const { theme } = useContext(CometChatContext);
const [optionsList, setOptionsList] = useState([]);
const [isResultVisible, setIsResultVisible] = useState(false);
const [result, setResult] = useState({});
const [optionsMetaData, setOptionsMetaData] = useState({});
const [selectedOption, setSelectedOption] = useState({});
const maxScore = useRef(0);
const getResult = (self, metadata) => {
let allOptions = {};
if (metadata.results?.options) {
for (const [key, value] of Object.entries(metadata.results?.options)) {
if (typeof value === 'object') {
if (maxScore.current < value['count'])
maxScore.current = value['count'];
allOptions[key] = {
...value,
percent: self
? (value['count'] / metadata.results.total) * 100
: (value['count'] / (metadata.results.total + 1)) * 100,
};
}
}
setResult(allOptions);
setIsResultVisible(true);
}
};
const handleResult = ({ id }) => {
if (loggedInUser['uid'] == senderUid)
return;
choosePoll && choosePoll(id);
setSelectedOption((prev) => ({ ...prev, [id]: !prev[id] }));
makeExtentionCall('polls', 'POST', 'v2/vote', {
vote: id,
id: pollId ?? optionsMetaData.id,
})
.then((s) => {
console.log('success', s);
getResult(false, optionsMetaData);
})
.catch((error) => {
console.log(error);
});
};
const OptionItem = ({ id, value }) => {
return (<TouchableOpacity key={id} onPress={() => handleResult({ id })} style={[
style.optionItemContainer,
{
backgroundColor: pollsBubbleStyle.pollOptionsBackgroundColor ??
theme.palette.getBackgroundColor(),
},
]}>
{isResultVisible ? (<View style={[
style.resultMask,
{
borderTopRightRadius: result[id]['percent'] > 99 ? 6 : 0,
borderBottomRightRadius: result[id]['percent'] > 99 ? 6 : 0,
backgroundColor: maxScore.current === result[id]['count']
? pollsBubbleStyle.selectedOptionColor ??
'rgba(51, 153, 255,0.2)'
: pollsBubbleStyle.unSelectedOptionColor ??
theme.palette.getAccent200(),
width: result[id] ? `${result[id]['percent']}%` : 0,
},
]}/>) : (<View style={[
style.optionsOption,
{
backgroundColor: pollsBubbleStyle.radioButtonColor ??
theme.palette.getAccent200(),
},
]}>
{selectedOption[id] === true && (<Image source={ICONS.TICK} resizeMode="contain" style={{
height: 14,
tintColor: theme.palette.getAccent(),
}}/>)}
</View>)}
<Text style={[
style.valueText,
{
color: pollsBubbleStyle.pollOptionsTextColor ??
theme.palette.getAccent(),
},
theme.typography.subtitle1,
pollsBubbleStyle.pollOptionsTextStyle,
]}>
{value}
</Text>
</TouchableOpacity>);
};
const getVoters = (metadata) => {
let voters;
if (metadata)
for (const value of Object.values(metadata)) {
if (typeof value === 'object') {
for (const value2 of Object.values(value)) {
for (const value3 of Object.values(value2)) {
if (value3['voters']) {
let votersKey = Object.keys(value3['voters'])[0];
voters = {
...voters,
[votersKey]: true,
};
}
}
}
}
}
return voters;
};
useLayoutEffect(() => {
let allOptions = [];
for (const [key, value] of Object.entries(options)) {
allOptions.push({ id: key, value });
}
setOptionsList(allOptions);
if (metadata) {
setOptionsMetaData(metadata);
loggedInUser['uid'] == senderUid && getResult(true, metadata);
let voters = getVoters(metadata);
if (voters)
voters[loggedInUser['uid']] && getResult(true, metadata);
}
}, []);
return (<View style={[style.container]}>
<Text style={[
theme.typography.subtitle1,
{
color: pollsBubbleStyle.questionTextColor ?? theme.palette.getAccent(),
},
style.questionText,
pollsBubbleStyle.questionTextStyle,
]}>
{pollQuestion}
</Text>
{optionsList.map((item) => (<OptionItem key={item['id']} {...item}/>))}
<Text style={[
theme.typography.subtitle1,
style.voteText,
{
color: pollsBubbleStyle.voteCountTextColor ??
theme.palette.getAccent600(),
},
pollsBubbleStyle.voteCountTextStyle,
]}>
{optionsMetaData.results?.total} people voted
</Text>
</View>);
};
const style = StyleSheet.create({
container: {
borderRadius: 10,
marginBottom: 5,
},
questionText: {
marginHorizontal: 10,
marginVertical: 5,
},
voteText: {
marginHorizontal: 10,
marginVertical: 5,
},
optionItemContainer: {
marginHorizontal: 5,
marginTop: 5,
height: 42,
alignItems: 'center',
borderRadius: 6,
flexDirection: 'row',
},
optionsOption: {
height: 20,
width: 20,
borderRadius: 20,
marginLeft: 10,
alignItems: 'center',
justifyContent: 'center',
},
valueText: {
marginLeft: 10,
},
resultMask: {
alignItems: 'center',
flexDirection: 'row',
position: 'absolute',
height: '100%',
borderTopLeftRadius: 6,
borderBottomLeftRadius: 6,
},
});
PollsBubble.defaultProps = {
options: {},
loggedInUser: {},
pollsBubbleStyle: {},
};
//# sourceMappingURL=PollsBubble.js.map