Easy way to understand what is my question play the following video and see what is my problem. https://vimeo.com/315390850
if you dont have a good inernet connection then read the following sentences.
I am going to update bubble messages but i dont know how to update specific message by Id. Example: in html there is and Id for every tag within a list and if we have to update then we select it by id and then update it. So how to make a concept like that for react-native-gifted-chat bubble messages?
I tried to use refs with setNativeProps function but did not work.
render(){
return (
<GiftedChat
extraData={this.state}
messages={this.state.messages}
onSend={messages => this.onSend(messages)}
user={{
_id: this.state.userId,
}}
renderBubble={this.renderBubble}
renderInputToolbar={this.renderInputToolbar.bind(this)}
/>
);
}
renderBubble = props => {
if (props.currentMessage.audio) {
return (
<View style={[{ width: 150, height: 70, backgroundColor: 'lightgray' }, props.position === 'left' ? { left: -41 } : {}]}>
<EIcon
name="google-play"
size={30}
color={this.state.playAudio ? "red" : "blue"}
style={{
left: 90,
position: "relative",
shadowColor: "#000",
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.5,
backgroundColor: "transparent"
}}
onPress={() => {
this.setState({
playAudio: true
});
const sound = new Sound(props.currentMessage.audio, "", error => {
if (error) {
console.log("failed to load the sound", error);
}
const duration = sound.getDuration();
const progressPhase = 1 / duration;
if (duration !== 0) {
this._interval = setInterval(() => {
this.setState({
progress: this.state.progress += progressPhase
});
if (this.state.progress >= 1) {
clearInterval(this._interval);
this.setState({
progress: 0.0,
playAudio: false
});
}
}, 1000);
}
sound.play(success => {
console.log(success, "success play");
if (!success) {
Alert.alert("There was an error playing this audio");
}
});
});
}}
/>
<Progress.Circle progress={this.state.progress} showsText size={35} />
</View>
);
} else {
return (
<Bubble
{...props}
textStyle={{
right: {
color: '#fff',
},
left: {
color: '#fff',
},
}}
wrapperStyle={{
left: {
backgroundColor: "orange",
left: -41
},
right: {
backgroundColor: 'green'
}
}}
/>
);
}
}
Here I have a chatbox when I send multiple audio message for example 3 aduio message: audio message .1, audio message .2, audio message .3 aduio message .1 has came first time. aduio message .3 has came last time.
every audio message has a play icon and a progressbar. When I click on play Icon, then I update the progressbar. here I used interval for one click on play icon, the progressbar gets update multiple time until gets complete.
My Problem is: when i click the play icon of audio message .1 just the last audio message .3 gets updated. I want: if I click on audio message .1 the progressbar of audio message .1 should be update. same for audio message .2 and audio message .3.
I solved my problem by conditional rendering Also I changed following class and I added
this line: next.audio == current.audio ||
export default class Message extends React.Component {
shouldComponentUpdate(nextProps) {
const next = nextProps.currentMessage;
const current = this.props.currentMessage;
const { nextMessage } = this.props;
const nextPropsMessage = nextProps.nextMessage;
return (
next.send !== current.send ||
next.received !== current.received ||
next.pending !== current.pending ||
next.createdAt !== current.createdAt ||
next.text !== current.text ||
next.image !== current.image ||
next.video !== current.video ||
next.audio == current.audio || // this line added by me
nextMessage !== nextPropsMessage
);
}
//..............
}
I add this condition and please please let me know about performance. this tree line, I added to my code:
this.myPro = <Progress.Circle progress={this.state.progress} showsText size={35} />; this.setState({currentPlayedMessage: props.currentMessage._id }); { props.currentMessage._id === this.state.currentPlayedMessage ? this.myPro : null }
All code:
if (props.currentMessage.audio) {
this.myPro = <Progress.Circle progress={this.state.progress} showsText size={35} />; // this line added
return (
<View style={[{ width: 150, height: 70, backgroundColor: 'lightgray' }, props.position === 'left' ? { left: -41 } : {}]}>
<EIcon
name="google-play"
size={30}
color={this.state.playAudio ? "green" : "blue"}
style={{
left: 90,
position: "relative",
shadowColor: "#000",
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.5,
backgroundColor: "transparent"
}}
onPress={() => {
this.setState({
playAudio: true,
currentPlayedMessage: props.currentMessage._id // this line added
});
const sound = new Sound(props.currentMessage.audio, "", error => {
if (error) {
return;
}
const duration = sound.getDuration();
const progressPhase = 1 / duration;
if (duration !== 0) {
this._interval = setInterval(() => {
this.setState({
progress: this.state.progress += progressPhase
});
if (this.state.progress >= 1) {
clearInterval(this._interval);
this.setState({
progress: 0.0,
playAudio: false
});
}
}, 1000);
}
sound.play(success => {
console.log(success, "success play");
if (!success) {
Alert.alert("There was an error playing this audio");
}
});
});
}}
/>
{ props.currentMessage._id === this.state.currentPlayedMessage ? this.myPro : null } // this line added
</View>
);
}