Skip to content

Commit

Permalink
Riley/c 2822 inbox doesnt refetch unreadmessagecount (#55)
Browse files Browse the repository at this point in the history
* save

* fix

Co-authored-by: riley napier <[email protected]>
  • Loading branch information
rileylnapier and riley napier authored Apr 26, 2021
1 parent 8a302b4 commit 4d3eb63
Show file tree
Hide file tree
Showing 13 changed files with 184 additions and 70 deletions.
55 changes: 55 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
## Contributing to `courier-react`

👍🎉 First off, thanks for taking the time to contribute! 🎉👍

# Quick Start

We use `yarn` here at Courier, so please use yarn aswell so we don't have to have conflicting `package.lock` and `yarn.lock` files.

1. `git clone https://github.com/trycourier/courier-react.git`
2. `cd courier-react`
3. `yarn`
4. `yarn start`

After running step #4, we will start a storybook instance and this is where you will do most all of your development.

# Monorepo

This is a monorepo using [Lerna](https://www.lerna.com) and contains many packages that are installed separately while depending on each other. All packages are versioned together.

---

### Development

All commands in a monorepo are run in the `root` of the project. You should never have to navigate into any of the sub-packages to do any development.

### Commands

- `yarn`

There is a postinstall task that will bootstrap the `lerna` project and `symlink` each package to eachother if they have dependencies to other packages in this repo.

- `yarn start`

This will initiate a `storybook` instance inside `packages/storybook`. THis is where all development for these packages should be done.

- `yarn lerna:version`
Bump the packages version, should be done before publishing.

- `yarn publish`

This will publish the packages to `npm` and version them together. This should only be run via `github actions`.

- `yarn typecheck`

Run typechecking on each package

- `yarn build`

Run `babel` and transpile each package to a consumable js `dist` folder.

- `yarn clean`

Cleans all `node_modules` from each package and deletes the root `node_modules`. Sometimes useful if packages have gotten out of date.

---
53 changes: 21 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@
[![stability-beta](https://img.shields.io/badge/stability-beta-33bbff.svg?label=Stability)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#beta)
[![codecov](https://codecov.io/gh/trycourier/courier-react/branch/main/graph/badge.svg?token=NVTDWY9UH4)](https://codecov.io/gh/trycourier/courier-react)

# Courier React Components (CRC)
## What is `courier-react`?

CRC is a monorepo using [Lerna](https://www.lerna.com) and contains many packages that are installed separately while depending on each other.
This repository, also called **In-App**, is a set of features and components that can work inside our customers websites. Courier is a powerful application but integrating all of the features into your frontend manually can be overwhelming and time consuming. This is where In-App steps up and can superpower your application by providing Realtime Messaging (Toast), an Inbox, Notification Preferences, and many more coming soon!

---
## Table of Contents

---
1. [Contributing](https://github.com/trycourier/courier-react/tree/main/CONTRIBUTING.md)
1. [Packages](#packages)

### Packages:

[components](https://github.com/trycourier/courier-react/tree/main/packages/components)

This package imports the other react components and bundles them up using `webpack` and `preact` to create a bundle that can be used to render all of our components in a frontend that does NOT use React.

### Public Packages:
---

[react-provider](https://github.com/trycourier/courier-react/tree/main/packages/react-provider)

Expand All @@ -20,44 +27,26 @@ This package exports a component called `CourierProvider` which creates a [conte

[react-toast](https://github.com/trycourier/courier-react/tree/main/packages/react-toast)

`CourierToast` is a non modal, component used to display brief, optional-expiring windows of information to a user. This can be integrated with a `push` provider or can be triggered manually.
`Toast` is a non modal, component used to display brief, optional-expiring windows of information to a user. This can be integrated with a `push` provider or can be triggered manually.

---

[react-inbox](https://github.com/trycourier/courier-react/tree/main/packages/react-inbox)

`CourierInbox` is a component used to display a history of `read` and `unread` messages to a user.

---
`Inbox` is a component used to display a history of `read` and `unread` messages to a user. If we send a message to a user when they are not logged in, or if they didn't interact with the message before it disappeared, we also have an Inbox to show the history of messages received.

---

### Development

All commands in a monorepo are run in the `root` of the project. You should never have to navigate into any of the sub-packages to do any development.

### Commands
[types](https://github.com/trycourier/courier-react/tree/main/packages/types)

- `yarn`
Utility package to share common Typescript types and interfaces shared between packages

There is a postinstall task that will bootstrap the `lerna` project and `symlink` each package to eachother if they have dependencies to other packages in this repo.

- `yarn start`

This will initiate a `storybook` instance inside `packages/storybook`. THis is where all development for these packages should be done.

- `yarn publish`

This will publish the packages to `npm` and version them together. This should only be run via `github actions`.

- `yarn typecheck`

Run typechecking on each package
---

- `yarn build`
[storybook](https://github.com/trycourier/courier-react/tree/main/packages/storybook)

Run `babel` and transpile each package to a consumable js `dist` folder.
Our development environment. This package depends on all the other packages and imports them into a storybook instance. This allows us to develop in an isolated environment.

- `yarn clean`
---

Cleans all `node_modules` from each package and deletes the root `node_modules`. Sometimes useful if packages have gotten out of date.
---
Empty file added docs/intro.md
Empty file.
2 changes: 1 addition & 1 deletion packages/components/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

<body>
<h1>Treva Homepage</h1>
<courier-toast auto-close="false"></courier-toast>
<courier-toast></courier-toast>
<courier-inbox></courier-inbox>
<div>
<button id="show-toast" onclick="showToastOnClick()" disabled>
Expand Down
6 changes: 5 additions & 1 deletion packages/react-inbox/src/components/Inbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const Inbox: React.FunctionComponent<InboxProps> = (props) => {
currentTab,
getUnreadMessageCount,
} = useInbox();

const tippyProps: TippyProps = {
trigger: props.trigger ?? "click",
placement: props.placement ?? "right",
Expand All @@ -88,9 +89,12 @@ const Inbox: React.FunctionComponent<InboxProps> = (props) => {

useEffect(() => {
registerReducer("inbox", reducer);
getUnreadMessageCount();
}, []);

useEffect(() => {
getUnreadMessageCount();
}, [userId, clientKey]);

useEffect(() => {
if (clientKey && userId) {
const localStorageState = localStorage.getItem(
Expand Down
6 changes: 3 additions & 3 deletions packages/react-inbox/src/components/Messages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ const Messages: React.FunctionComponent<InboxProps> = ({
)}
<TabList />
<MessageList ref={ref} data-testid="messages">
{messages.map((message) =>
{messages?.map((message) =>
renderMessage ? (
renderMessage(message)
) : (
<Message key={message.messageId} {...message} />
)
)}
{isLoading && <Loading />}
{!isLoading && messages.length === 0 && (
{!isLoading && messages?.length === 0 && (
<Empty>You have no notifications at this time</Empty>
)}
{!isLoading && messages.length > 5 && !startCursor && (
{!isLoading && messages?.length > 5 && !startCursor && (
<PaginationEnd title="End Of The Road" />
)}
</MessageList>
Expand Down
7 changes: 4 additions & 3 deletions packages/react-inbox/src/hooks/use-inbox-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ const useInboxActions = () => {
dispatch,
createTrackEvent,
createBatchTrackEvent,
graphQLClient,
} = useCourier();

return {
init: (payload) => {
payload = {
Expand All @@ -36,15 +38,14 @@ const useInboxActions = () => {
fetchMessages: (params: IGetMessagesParams) => {
dispatch({
type: "inbox/FETCH_MESSAGES",
payload: (_, getState) => getMessages(getState().graphQLClient, params),
payload: () => getMessages(graphQLClient, params),
});
},

getUnreadMessageCount: (params) => {
dispatch({
type: "inbox/SET_UNREAD_MESSAGE_COUNT",
payload: (_, getState) =>
getUnreadMessageCount(getState().graphQLClient, params),
payload: () => getUnreadMessageCount(graphQLClient, params),
});
},

Expand Down
4 changes: 2 additions & 2 deletions packages/react-inbox/src/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ export default (state: InboxState = initialState, action) => {
}

case "inbox/FETCH_MESSAGES/DONE": {
const newMessages = action?.payload?.messages.map(makeMessage);
const newMessages = action?.payload?.messages?.map(makeMessage);

return {
...state,
isLoading: false,
startCursor: action?.payload?.startCursor,
messages: action?.payload?.appendMessages
? [...(state.messages ?? []), ...newMessages]
? [...(state?.messages ?? []), ...newMessages]
: newMessages,
};
}
Expand Down
11 changes: 11 additions & 0 deletions packages/react-provider/src/graph-ql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { Client, createClient } from "urql";

export class GraphQLClient {
client: Client;
canRequest: boolean;

constructor({ clientKey, userId, userSignature, apiUrl }) {
this.canRequest = Boolean(clientKey && userId);

this.client = createClient({
url: `${
apiUrl ?? process.env.API_URL ?? `https://api.courier.com`
Expand All @@ -26,10 +30,17 @@ export class GraphQLClient {
}

query(queryString, variables) {
if (!this.canRequest) {
return;
}

return this.client.query(queryString, variables).toPromise();
}

mutate(mutateString, variables) {
if (!this.canRequest) {
return;
}
return this.client.mutation(mutateString, variables).toPromise();
}
}
Expand Down
38 changes: 24 additions & 14 deletions packages/react-provider/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,31 @@ export const CourierProvider: React.FunctionComponent<ICourierContext> = ({
});

useEffect(() => {
if (clientKey && userId) {
dispatch({
type: "root/INIT",
payload: {
apiUrl,
brandId,
graphQLClient,
clientKey,
transport,
userId,
userSignature,
},
});
if (!clientKey || !userId) {
return;
}
}, [apiUrl, clientKey, transport, userId, userSignature, brandId]);

dispatch({
type: "root/INIT",
payload: {
apiUrl,
brandId,
graphQLClient,
clientKey,
transport,
userId,
userSignature,
},
});
}, [
apiUrl,
graphQLClient,
clientKey,
transport,
userId,
userSignature,
brandId,
]);

useEffect(() => {
if (brand) {
Expand Down
3 changes: 2 additions & 1 deletion packages/react-provider/src/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ const rootReducer = (state, action) => {
return {
...state,
apiUrl: action.payload.apiUrl,
brandId: action.payload.brandId,
clientKey: action.payload.clientKey,
graphQLClient: action.payload.graphQLClient,
transport: action.payload.transport,
userId: action.payload.userId,
userSignature: action.payload.userSignature,
brandId: action.payload.brandId,
};
}
case "root/GET_BRAND/DONE": {
Expand Down
11 changes: 11 additions & 0 deletions packages/storybook/stories/introduction.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";

export default {
title: "Introduction",
argTypes: {},
args: {},
};

export const Default = () => {
return <div>hello world</div>;
};
Loading

0 comments on commit 4d3eb63

Please sign in to comment.