🗂

react-native-gifted-chatで吹き出しのデザインを細かくカスタマイズする方法

2022/09/28に公開

オンライン家庭教師マナリンク でインターンをしている Yukiです。

React Native製アプリでチャットを実装したい時に使えるライブラリにreact-native-gifted-chat があります。今回はreact-native-gifted-chatでメッセージを入れる吹き出しをカスタマイズする方法を解説します。
具体的には、メッセージを送った際に自分の名前は表示させず、相手の名前のみ表示する方法と自分と相手の吹き出しの色を変更する方法を実際のコードを交え、紹介したいと思います。

動作環境

対象読者

  • 既にreact-native-gifted-chatを知っていて、カスタマイズしたいと思っている方

インストール

  • npm: <code>npm install react-native-gifted-chat</code>
  • yarn: yarn add react-native-gifted-chat

完成イメージ

今回react-native-gifted-chatのデフォルトのスタイルに対して、チャットの吹き出しをカスタマイズした部分はこちらです。

  • 自分と相手の吹き出しの色を変更した
  • 相手の吹き出しの上にのみ相手の名前(ここではmeijin)を表示させるようにした
  • 吹き出し内部のテキストのstyleを変更した
  • 送信時刻がデフォルトだと吹き出し内部に表示させるものを、吹き出しの外に出した

サンプルコード

まずはチャット画面全体のコードを下記に示します。GiftedChatコンポーネントのrenderBubbleプロパティに注目してください。

ChatScreen.tsx
import { MessageBubble } from './MessageBubble';

export const Chat = ({ navigation, route }: Props) => {
    const userId = getUser().id;
    const onSend = /** 中略 */
    const ChatSendButton = /** 中略 */
    const nickname = /** 中略 */
    const icon = /** 中略 */

    const { messages } = getMessages(navigation, route);

    /* 中略 */

    return (
      <GiftedChat
          messages={messages}
          placeholder='メッセージを入力'
          onSend={onSend}
          showUserAvatar
          renderSend={ChatSendButton}
          renderBubble={MessageBubble}
          alwaysShowSend
          user={{
            _id: userId!,
            name: nickname,
            avatar: icon,
          }}
          locale='ja'
          renderAvatarOnTop
      />
  );
};

renderBubbleプロパティを使うことで、チャット画面のメッセージが入った吹き出しをカスタマイズすることが可能です。代入されているMessageBubbleは以下のように実装します。

MessageBubble.tsx
export const MessageBubble = (props: Bubble['props']) => {
  const user = getUser();
  const userId = user?.uid

  const currentUserId = props.currentMessage?.user._id;
  let times = props.currentMessage.createdAt as Date;
  const time = new Date(times)

  return (
    <View style={{ flex: 1 }}>
      {userId !== currentUserId && (
        <Text style={styles.userName}>
          {props.currentMessage.user.name}
        </Text>
      )}
      <Bubble
        {...props}
        textStyle={{
          right: {
            color: 'black'
          },
          left: {
            color: 'white'
          }
        }}
        wrapperStyle={{
          right: {
            backgroundColor: 'white'
          },
          left: {
            backgroundColor: '#3CD9D9'
          }
        }}
        renderTime={() => {
          return null
        }}
        />
        {userId === currentUserId ? (
          <Text style={styles.rightTime}>{time.toLocaleTimeString()}</Text>
        ) : (
          <Text style={styles.leftTime}>{time.toLocaleTimeString()}</Text>
        )}
    </View>
  )
}

完成イメージ画像では相手の名前のみが吹き出しの上部に表示されていると思います。それを実装しているのが下記の部分。

tsx
      {userId !== currentUserId && (
        <Text style={styles.userName}>
          {props.currentMessage.user.name}
        </Text>
      )}

ログインしているユーザーIDと、メッセージデータのユーザーIDを比較し、メッセージを送ったのが自分か自分以外かを判断することが可能です。これを利用して、自分以外がメッセージを送った時のみ名前を表示するようにしています。この部分のstyleを変更することで、名前のstyleを変更することが可能です。
そして、メッセージを入れる吹き出しについてですが、react-native-gifted-chatから提供されているBubbleコンポーネントを使うことで、自分好みの吹き出しに変更することが可能です。

tsx
        textStyle={{
          right: {
            color: 'black'
          },
          left: {
            color: 'white'
          }
        }}
        wrapperStyle={{
          right: {
            backgroundColor: 'white'
          },
          left: {
            backgroundColor: '#3CD9D9'
          }
        }}

また、吹き出し内の色、テキストのstyleを変更したい場合は上記のようにtextStyle, wrapperStyle内に記述することで変更することが可能です。

tsx
        renderTime={() => {
          return null
        }}
        />
        {userId === currentUserId ? (
          <Text style={styles.rightTime}>{time.toLocaleTimeString()}</Text>
        ) : (
          <Text style={styles.leftTime}>{time.toLocaleTimeString()}</Text>
        )}

また、デフォルトだと吹き出しの中に時刻が表示されてしまいます。これが私は見辛いと感じたので、renderTimeに渡す関数ではnullを返すようにして、上記のように吹き出しの下に送信時刻を表示させています。

Tips

上記のBubbleコンポーネントのようにチャット画面内のデフォルトの部品がreact-native-gifted-chatからコンポーネントとして提供されている場合があります(Bubble以外にもAvatarなどがある)ので、「自分でカスタマイズしたい」と感じる方は探してみるといいかもしれません。また、自分のAvatarを表示しないようにするには、GiftedChatコンポーネントのshowUserAvatarをfalseに変更することで、非表示にすることができます。

最後に

今回はreact-native-gifted-chatを少しカスタマイズしたい方向けに書いてみたのですが、いかがだったでしょうか。他にもたとえば、LINEのように+ボタンを押して、下からメニューが出てくるという実装も可能なので、ぜひ調べてみてください。

マナリンク Tech Blog

Discussion