github.com/maeglindeveloper/gqlgen@v0.13.1-0.20210413081235-57808b12a0a0/example/chat/src/Room.js (about)

     1  import React, { useState, useEffect, useRef } from 'react';
     2  import gql from 'graphql-tag';
     3  import { useQuery, useMutation } from '@apollo/react-hooks';
     4  import { Chat, ChatContainer, Message, MessageReceived } from './components/room';
     5  
     6  export const Room = ({ channel, name }) => {
     7      const messagesEndRef = useRef(null)
     8      const [ text, setText ] = useState('');
     9  
    10      const [ addMessage ] = useMutation(MUTATION, {
    11          onCompleted: () => {
    12              setText('');
    13          }
    14      });
    15  
    16      const { loading, error, data, subscribeToMore } = useQuery(QUERY, {
    17          variables: {
    18              channel
    19          },
    20      });
    21  
    22      // subscribe to more messages
    23      useEffect(() => {
    24          const subscription = subscribeToMore({
    25              document: SUBSCRIPTION,
    26              variables: {
    27                  channel,
    28              },
    29              updateQuery: (prev, { subscriptionData }) => {
    30  
    31                  if (!subscriptionData.data) {
    32                      return prev;
    33                  }
    34                  const newMessage = subscriptionData.data.messageAdded;
    35  
    36                  if (prev.room.messages.find((msg) => msg.id === newMessage.id)) {
    37                      return prev
    38                  }
    39  
    40                  return Object.assign({}, prev, {
    41                      room: Object.assign({}, prev.room, {
    42                          messages: [...prev.room.messages, newMessage],
    43                      })
    44                  });
    45              },
    46          });
    47  
    48  
    49          return () => subscription();
    50  
    51      }, [subscribeToMore, channel]);
    52  
    53      // auto scroll down
    54      useEffect(() => {
    55          messagesEndRef && messagesEndRef.current && messagesEndRef.current.scrollIntoView({ behavior: 'smooth' })
    56      }, [messagesEndRef, data]);
    57  
    58      if (loading) {
    59          return <div>loading</div>
    60      }
    61  
    62      if (error) {
    63          return <div>error</div>
    64      }
    65  
    66      return (<>
    67          <Chat>
    68              <ChatContainer>
    69                  {data.room.messages.map((msg) =>
    70                      msg.createdBy === name ? <Message key={msg.id}>
    71                          {msg.text}
    72                      </Message> : <MessageReceived key={msg.id}>
    73                          <span>{msg.createdBy}</span>
    74                          {msg.text}
    75                      </MessageReceived>
    76                  )}
    77              </ChatContainer>
    78              <div ref={messagesEndRef} />
    79          </Chat>
    80  
    81          <input value={text} onChange={(e) => setText(e.target.value)} />
    82  
    83          <p>
    84              <button
    85                  onClick={() => addMessage({
    86                      variables: {
    87                          text: text,
    88                          channel: channel,
    89                          name: name,
    90                      }
    91                      })
    92                  } >
    93                  send
    94              </button>
    95          </p>
    96      </>);
    97  
    98  }
    99  
   100  const SUBSCRIPTION = gql`
   101      subscription MoreMessages($channel: String!) {
   102          messageAdded(roomName:$channel) {
   103              id
   104              text
   105              createdBy
   106          }
   107      }
   108  `;
   109  
   110  const QUERY = gql`
   111      query Room($channel: String!) {
   112          room(name: $channel) {
   113              messages { id text createdBy }
   114          }
   115      }
   116  `;
   117  
   118  const MUTATION = gql`
   119      mutation sendMessage($text: String!, $channel: String!, $name: String!) {
   120          post(text:$text, roomName:$channel, username:$name) { id }
   121      }
   122  `;