FaridSafi / react-native-gifted-chat

💬 The most complete chat UI for React Native

Home Page:https://gifted.chat

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Different Bubble color for each user.

tonnth opened this issue · comments

Issue Description

If more than 2 user in a conversation.
How can I set Bubble color for each user?
Thank you in advance!

Additional Information

  • React Native version: 0.50.3

Yes use the renderBubble prop of the GiftedChat and pass a function like this

renderBubble={this.renderBubble}

there you will return your Custom Bubble.js (Copy the code from the src folder in the node module)

  renderBubble(props) {
    return <Bubble {...props} />;
  }

In Bubble.js you will find the styles. You have to look at the wrapper in left and right and set the backgroundColor you want to.

Thanks @mafiusu
It work with 2 user in a conversation. But i want to set different corlor for each user in leftside like picture below and i dont know how to do that?
nh ch p man hinh 2017-12-20 luc 20 12 38

Yes, I use this pattern to display usernames in different colors. You could use this function:

  getColor(username){
    let sumChars = 0;
    for(let i = 0;i < username.length;i++){
      sumChars += username.charCodeAt(i);
    }

    const colors = [
      '#e67e22', // carrot
      '#2ecc71', // emerald
      '#3498db', // peter river
      '#8e44ad', // wisteria
      '#e74c3c', // alizarin
      '#1abc9c', // turquoise
      '#2c3e50', // midnight blue
    ];
    return colors[sumChars % colors.length];
  }

Then you will pass the backgroundColor style in the Render Method of Bubble.js. You have to decide if it's left or right using this.props.position === 'left' ? DO_Something : something else
You just pass it like backgroundColor: getColor(username)

You saves my life.
Thank you @mafiusu .

I close this issue but create a FAQ in readme to refer it: https://github.com/FaridSafi/react-native-gifted-chat#questions

FYI this is the code example you want:

  renderBubble={props => {
    return (
      <Bubble
        {...props}
        textStyle={{
          right: {
            color: 'yellow',
          },
        }}
        wrapperStyle={{
          left: {
            backgroundColor: 'red',
          },
        }}
      />
    );
  }}

Hey guys, I've been struggling with understanding what you guys mean.

Could you please help me out a little bit more?

This is what my Gifted Chat looks like.

  render() {
    return (
      <GiftedChat
        messages={this.state.messages}
        renderBubble={this.renderBubble}
        onSend={messages => this.onSend(messages)}
        user={{
          _id: 1,
        }}
      />
    )
  }

Here are the two helper functions you guys mentioned. I'm not sure how to use them in order to pass each individual bubble a color in order to get a distinct color. Please advise.

  renderBubble = (props) => {
    let usernames = props.messages.map(message => message.user.full_name)
    let colors = usernames.map(username => this.getColor(username))

    return (
      <Bubble
        {...props}
        textStyle={{
          right: {
            color: 'yellow',
          },
        }}
        wrapperStyle={{
          left: {
            backgroundColor: colors,
          },
        }}
      />
    );
  }

  getColor(username){
    let sumChars = 0;
    for(let i = 0;i < username.length;i++){
      sumChars += username.charCodeAt(i);
    }

    const colors = [
      '#e67e22', // carrot
      '#2ecc71', // emerald
      '#3498db', // peter river
      '#8e44ad', // wisteria
      '#e74c3c', // alizarin
      '#1abc9c', // turquoise
      '#2c3e50', // midnight blue
    ];
    return colors[sumChars % colors.length];
  }

I'm uncertain where I should pass a single user in, because GiftedChat takes an array of messages so I don't know how to pass in a username so that it'll be used accordingly.
Thanks for an awesome library btw. First time using it is today and have had a blast so far =)

Hey Loi,

Inside renderBubble function props, you could actually get the currentMessage and its user, then you could decide on the color of that bubble like below:

renderBubble = props => {
    let username = props.currentMessage.user.name
    let color = this.getColor(username)

    return (
      <Bubble
        {...props}
        textStyle={{
          right: {
            color: 'white'
          }
        }}
        wrapperStyle={{
          left: {
            backgroundColor: color
          }
        }}
      />
    )
  }

@jameshuynh Ohhh, thanks bud!

How would you customize the color of the message timestamp?

This works from 0.5.0 after #942 has been merged

<GiftedChat
  messages={this.state.messages}
  onSend={this.onSend}
  renderCustomView={CustomView}
  keyboardShouldPersistTaps="never"
  user={{ _id: 1 }}
  renderBubble={props => {
    return (
      <Bubble
        {...props}
        timeTextStyle={{
          right: { color: 'red' }
        }}
      />
    );
  }}
  parsePatterns={this.parsePatterns}
/>

Previous comment

i.e.

export default function Time({ position, containerStyle, currentMessage, timeFormat, textStyle }, context) {
return (
<View style={[styles[position].container, containerStyle[position]]}>
<Text style={[styles[position].text, textStyle[position]]}>

This doesn't work:

    <Bubble
        {...props}
        timeProps={{
          textStyle: {
            right: { color: 'black' },
          },
        }}
    />
commented

any luck @gianpaj ?

so, the only way to achieve this behavior is by copying the source code for Bubble, which itself depends on other files in the source folder, as well as outside packages? shouldn't there be a 'getBubbleColor' prop? i mean, this is the first link under the Questions section on the readme, seems like a common enough issue that it warrants a better solution than basically forking the project...

The prop is not being passed down to the Time component. I've made a pull request:

#942

@AndresTIY my PR #942 has been merged to master 🎉. Hopefully, a new release will be out soon 🙏

Just a tiny bit of additional information:
Combining @mafiusu and @gianpaj's answers, you don't actually need to write your own Bubble.js (or scaffold code out of the node_module). You can just import the Bubble component like so:

import { Bubble } from 'react-native-gifted-chat';
...
          renderBubble={props => {
            return (
              <Bubble
                {...props}
                wrapperStyle={{
                  left: {
                    backgroundColor: 'white',
                  },
                }}
              />
            );
          }}

FYI this is the code example you want:

  renderBubble={props => {
    return (
      <Bubble
        {...props}
        textStyle={{
          right: {
            color: 'yellow',
          },
        }}
        wrapperStyle={{
          left: {
            backgroundColor: 'red',
          },
        }}
      />
    );
  }}

how to pass the props in the render
this.renderBubble()----------------------???????

@Nagasai97 renderBubble is a prop of the <GiftedChat> component.

See my updated comment

All props on README.

@gianpaj can i get the code of onSend function for class component...?

Does anyone have an example of how to change the bubble styling when using typescript props?

How is this done with functional component?

How is this done with functional component?

This is the version with Functional Components

const renderBubble = props => { return ( <Bubble {...props} textStyle={{ right: { color: 'yellow', }, }} wrapperStyle={{ left: { backgroundColor: 'red', }, }} /> ); }

And then:

<GiftedChat messages={messages} onSend={messages => onSend(messages)} user={{ _id: 1 }} **renderBubble={renderBubble}** />

A more complete example on how to modify the styles of the text bubbles using functional components: #640 (comment)

const renderTime = (props: TimeProps) => {
return (
<Time
{...props}
timeTextStyle={{
left: {
color: 'black',
},
right: {
color: 'black',
},
}}
/>
);
};

const renderBubble = (props: Bubble["props"]) => {
return (
<Bubble
{...props}
wrapperStyle={{
right: { borderTopRightRadius: 15, backgroundColor: '#ECF6FF' },
left: { borderTopLeftRadius: 15, backgroundColor: '#F6F6F6' },
}}
textStyle={
{
right: { color: '#000000', fontFamily: "Poppins-Regular", },
left: { color: '#000000', fontFamily: "Poppins-Regular", },
}
}
renderTime={renderTime}
/>
);
};