Skip to content

Commit

Permalink
Step 9.2: Use GraphQL Codegen hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
Urigo committed May 20, 2020
1 parent ee4adc1 commit afc9b44
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 53 deletions.
14 changes: 10 additions & 4 deletions src/components/ChatRoomScreen/ChatNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import React from 'react';
import { useCallback } from 'react';
import styled from 'styled-components';
import { History } from 'history';
import { ChatQueryResult } from './index';

const Container = styled(Toolbar)`
padding: 0;
Expand Down Expand Up @@ -37,7 +36,10 @@ const Name = styled.div`

interface ChatNavbarProps {
history: History;
chat: ChatQueryResult;
chat?: {
picture?: string | null;
name?: string | null;
};
}

const ChatNavbar: React.FC<ChatNavbarProps> = ({ chat, history }) => {
Expand All @@ -50,8 +52,12 @@ const ChatNavbar: React.FC<ChatNavbarProps> = ({ chat, history }) => {
<BackButton data-testid="back-button" onClick={navBack}>
<ArrowBackIcon />
</BackButton>
<Picture data-testid="chat-picture" src={chat.picture} />
<Name data-testid="chat-name">{chat.name}</Name>
{chat && chat.picture && chat.name && (
<React.Fragment>
<Picture data-testid="chat-picture" src={chat.picture} />
<Name data-testid="chat-name">{chat.name}</Name>
</React.Fragment>
)}
</Container>
);
};
Expand Down
8 changes: 6 additions & 2 deletions src/components/ChatRoomScreen/MessagesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from 'react';
import { useEffect, useRef } from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';
import { ChatQueryMessage } from './index';

const Container = styled.div`
display: block;
Expand Down Expand Up @@ -62,8 +61,13 @@ const Timestamp = styled.div`
font-size: 12px;
`;

interface Message {
id: string | null;
content: string | null;
createdAt: string | null;
}
interface MessagesListProps {
messages: Array<ChatQueryMessage>;
messages: Array<Message>;
}

const MessagesList: React.FC<MessagesListProps> = ({ messages }) => {
Expand Down
89 changes: 46 additions & 43 deletions src/components/ChatRoomScreen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
import gql from 'graphql-tag';
import React from 'react';
import { useCallback } from 'react';
import { useQuery, useMutation } from '@apollo/react-hooks';
import styled from 'styled-components';
import ChatNavbar from './ChatNavbar';
import MessageInput from './MessageInput';
import MessagesList from './MessagesList';
import { History } from 'history';
import {
ChatsQuery,
useGetChatQuery,
useAddMessageMutation,
} from '../../graphql/types';
import * as queries from '../../graphql/queries';
import * as fragments from '../../graphql/fragments';

Expand All @@ -18,6 +22,7 @@ const Container = styled.div`
height: 100vh;
`;

// eslint-disable-next-line
const getChatQuery = gql`
query GetChat($chatId: ID!) {
chat(chatId: $chatId) {
Expand All @@ -27,6 +32,7 @@ const getChatQuery = gql`
${fragments.fullChat}
`;

// eslint-disable-next-line
const addMessageMutation = gql`
mutation AddMessage($chatId: ID!, $content: String!) {
addMessage(chatId: $chatId, content: $content) {
Expand All @@ -41,21 +47,6 @@ interface ChatRoomScreenParams {
history: History;
}

export interface ChatQueryMessage {
id: string;
content: string;
createdAt: Date;
}

export interface ChatQueryResult {
id: string;
name: string;
picture: string;
messages: Array<ChatQueryMessage>;
}

type OptionalChatQueryResult = ChatQueryResult | null;

interface ChatsResult {
chats: any[];
}
Expand All @@ -64,14 +55,20 @@ const ChatRoomScreen: React.FC<ChatRoomScreenParams> = ({
history,
chatId,
}) => {
const { data } = useQuery<any>(getChatQuery, {
const { data, loading } = useGetChatQuery({
variables: { chatId },
});
const chat = data?.chat;
const [addMessage] = useMutation(addMessageMutation);

const [addMessage] = useAddMessageMutation();

const onSendMessage = useCallback(
(content: string) => {
if (data === undefined) {
return null;
}
const chat = data.chat;
if (chat === null) return null;

addMessage({
variables: { chatId, content },
optimisticResponse: {
Expand All @@ -88,11 +85,10 @@ const ChatRoomScreen: React.FC<ChatRoomScreenParams> = ({
type FullChat = { [key: string]: any };
let fullChat;
const chatIdFromStore = defaultDataIdFromObject(chat);

if (chatIdFromStore === null) {
return;
}

try {
fullChat = client.readFragment<FullChat>({
id: chatIdFromStore,
Expand All @@ -102,53 +98,53 @@ const ChatRoomScreen: React.FC<ChatRoomScreenParams> = ({
} catch (e) {
return;
}

if (fullChat === null ||
fullChat.messages === null ||
data === null ||
data.addMessage === null ||
data.addMessage.id === null) {

if (fullChat === null || fullChat.messages === null) {
return;
}
if (fullChat.messages.some((currentMessage: any) => currentMessage.id === data.addMessage.id)){
if (
fullChat.messages.some(
(currentMessage: any) =>
data.addMessage && currentMessage.id === data.addMessage.id
)
) {
return;
}

fullChat.messages.push(data.addMessage);
fullChat.lastMessage = data.addMessage;

client.writeFragment({
id: chatIdFromStore,
fragment: fragments.fullChat,
fragmentName: 'FullChat',
data: fullChat,
});

let clientChatsData;
let clientChatsData: ChatsQuery | null;
try {
clientChatsData = client.readQuery<ChatsResult>({
clientChatsData = client.readQuery({
query: queries.chats,
});
} catch (e) {
return;
}

if (!clientChatsData || clientChatsData === null) {
return null;
}
if (!clientChatsData.chats || clientChatsData.chats === undefined) {

if (!clientChatsData || !clientChatsData.chats) {
return null;
}
const chats = clientChatsData.chats;

const chatIndex = chats.findIndex((currentChat: any) => currentChat.id === chatId);

const chatIndex = chats.findIndex(
(currentChat: any) => currentChat.id === chatId
);
if (chatIndex === -1) return;
const chatWhereAdded = chats[chatIndex];

// The chat will appear at the top of the ChatsList component
chats.splice(chatIndex, 1);
chats.unshift(chatWhereAdded);

client.writeQuery({
query: queries.chats,
data: { chats: chats },
Expand All @@ -157,15 +153,22 @@ const ChatRoomScreen: React.FC<ChatRoomScreenParams> = ({
},
});
},
[chat, chatId, addMessage]
[data, chatId, addMessage]
);

if (!chat) return null;
if (data === undefined) {
return null;
}
const chat = data.chat;
const loadingChat = loading;

if (loadingChat) return null;
if (chat === null) return null;

return (
<Container>
<ChatNavbar chat={chat} history={history} />
{chat.messages && <MessagesList messages={chat.messages} />}
{chat?.messages && <MessagesList messages={chat.messages} />}
<MessageInput onSendMessage={onSendMessage} />
</Container>
);
Expand Down
7 changes: 3 additions & 4 deletions src/components/ChatsListScreen/ChatsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { List, ListItem } from '@material-ui/core';
import styled from 'styled-components';
import { useCallback } from 'react';
import { History } from 'history';
import { useQuery } from '@apollo/react-hooks';
import * as queries from '../../graphql/queries';
import { useChatsQuery } from '../../graphql/types';

const Container = styled.div`
height: calc(100% - 56px);
Expand Down Expand Up @@ -64,15 +63,15 @@ interface ChatsListProps {
}

const ChatsList: React.FC<ChatsListProps> = ({ history }) => {
const { data } = useQuery<any>(queries.chats);

const navToChat = useCallback(
(chat) => {
history.push(`chats/${chat.id}`);
},
[history]
);

const { data } = useChatsQuery();

if (data === undefined || data.chats === undefined) {
return null;
}
Expand Down

0 comments on commit afc9b44

Please sign in to comment.