Skip to content

Commit

Permalink
Step 12.5: Update cache on chat removal
Browse files Browse the repository at this point in the history
  • Loading branch information
Urigo committed May 20, 2020
1 parent 5491cf9 commit 6fe238d
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/components/ChatRoomScreen/ChatNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useCallback } from 'react';
import styled from 'styled-components';
import { History } from 'history';
import { useRemoveChatMutation } from '../../graphql/types';
import { eraseChat } from '../../services/cache.service';

const Container = styled(Toolbar)`
padding: 0;
Expand Down Expand Up @@ -67,6 +68,11 @@ const ChatNavbar: React.FC<ChatNavbarProps> = ({ chat, history }) => {
variables: {
chatId: chat.id,
},
update: (client, { data }) => {
if (data && data.removeChat) {
eraseChat(client, data.removeChat);
}
},
});

const handleRemoveChat = useCallback(() => {
Expand Down
6 changes: 6 additions & 0 deletions src/components/ChatRoomScreen/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import gql from 'graphql-tag';
import React from 'react';
import { useCallback } from 'react';
import { Redirect } from 'react-router-dom';
import styled from 'styled-components';
import ChatNavbar from './ChatNavbar';
import MessageInput from './MessageInput';
Expand Down Expand Up @@ -95,6 +96,11 @@ const ChatRoomScreen: React.FC<ChatRoomScreenParams> = ({
if (loadingChat) return null;
if (chat === null) return null;

// Chat was probably removed from cache by the subscription handler
if (!chat) {
return <Redirect to="/chats" />;
}

return (
<Container>
{chat?.id && <ChatNavbar chat={chat} history={history} />}
Expand Down
7 changes: 7 additions & 0 deletions src/graphql/subscriptions/chatRemoved.subscription.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import gql from 'graphql-tag';

export default gql`
subscription ChatRemoved {
chatRemoved
}
`;
1 change: 1 addition & 0 deletions src/graphql/subscriptions/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as messageAdded } from './messageAdded.subscription';
export { default as chatAdded } from './chatAdded.subscription';
export { default as chatRemoved } from './chatRemoved.subscription';
55 changes: 55 additions & 0 deletions src/services/cache.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ChatsQuery,
ChatFragment,
useChatAddedSubscription,
useChatRemovedSubscription,
} from '../graphql/types';

type Client = Pick<
Expand All @@ -31,6 +32,14 @@ export const useCacheService = () => {
}
},
});

useChatRemovedSubscription({
onSubscriptionData: ({ client, subscriptionData: { data } }) => {
if (data) {
eraseChat(client, data.chatRemoved);
}
},
});
};

export const writeMessage = (client: Client, message: MessageFragment) => {
Expand Down Expand Up @@ -137,3 +146,49 @@ export const writeChat = (client: Client, chat: ChatFragment) => {
data: { chats },
});
};

export const eraseChat = (client: Client, chatId: string) => {
const chatType = {
__typename: 'Chat',
id: chatId,
};

const chatIdFromObject = defaultDataIdFromObject(chatType);
if (chatIdFromObject === null) {
return;
}

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

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

if (!data || !data.chats) return;

const chats = data.chats;

if (!chats) return;

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

if (chatIndex === -1) return;

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

client.writeQuery({
query: queries.chats,
data: { chats: chats },
});
};

0 comments on commit 6fe238d

Please sign in to comment.