Skip to content

Commit

Permalink
feat: threads v2 (#2668)
Browse files Browse the repository at this point in the history
* chore: bump stream-chat-js version to latest and fix tsc generation issues

* feat: add useStateStore hook for future use

* feat: add separate tab for threads in SampleApp

* feat: modify thread activation and modify SampleApp

* fix: remove improper activation

* fix: ThreadListItem issues and add click listener

* fix: various upsertion bugs as well as proper activation, channel overrides

* fix: typing and move to different object with new arch

* fix: old threads unloading a full window of replies

* feat: add read state handling to threads

* fix: add channel as a dependency to the hook

* feat: add timestamp and fix keys in sample app

* fix: linter errors

* fix: thread missing load more indicators

* feat: add thread list refresh banner

* fix: ts errors and improvements

* feat: handle loading and empty indicators for thread list

* fix: linter errors

* refactor: move threadlist indicators to already existing ones

* chore: move unread banner to separate component

* feat: add customization capabilities to threads components

* chore: make the banner customizable as well

* feat: add pagination support for thread list

* fix: styles for thread list item component

* chore: move styles in theme where it makes sense

* feat: add unread count badge for threads in sampleapp

* refactor: clean up the badge count a bit

* fix: revert Podfile.lock removal

* chore: remove redundant file

* fix: issue with empty state indicator

* chore: add default translations

* chore: bump stream-chat-js to latest

* fix: lint errors

* fix: move away from checking for thread.activate

* chore: bump stream-chat-js to latest

* chore: threads v2 ui components documentation

* chore: cleanup of redundant code and type fix

* chore: remove redundant TODOs

* fix: replace thread tab icon to the correct one

* feat: translations for languages other than english

* fix: lint issues in docs

* fix: non-initialized channel bug and thread snapshot

* chore: remove redundant console.logs

* chore: add proper title to threads and test ids

* chore: add docs for state management

* fix: parent message deletion handler

* fix: handle reactions and message deletion bugs

* fix: add missing upsert

* feat: add customizable loading next indicator

* chore: add docs for new indicator

* fix: revert not needed change

* fix: linter issues

* chore: try to do a branch release for threads

* fix: own reactions resolution bug

* chore: bump stream-chat-js to latest

* chore: add new users to sample app

* feat: add reactivity to focusing and defocusing

* fix: thread list date time parsing

* fix: dark mode issues

* fix: broken upsertions

* fix: reload on relog as well

* fix: relog issue threads

* chore: docs update

* fix: reconnection flow for thread list

* chore: revert deployment change

* fix: revert .nvmrc change as it is not needed

* chore: bump back sample app version

* fix: revert change as release would do the same

* chore: cleanup
  • Loading branch information
isekovanic committed Sep 25, 2024
1 parent 0a89578 commit 39a2fb3
Show file tree
Hide file tree
Showing 71 changed files with 1,797 additions and 234 deletions.
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20
v20
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
An instance of the [`Thread` class](https://github.com/GetStream/stream-chat-js/blob/master/src/thread.ts) that can be used to either get more data about the thread or pass to `onThreadSelect`.

| Type |
| ------ |
| Thread |
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
An object containing [`FlatListProps`](https://reactnative.dev/docs/flatlist#props) that can be used to override the default ones provided in the `ThreadList`.

| Type |
| ------ |
| object |
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
A boolean indicating if the `ThreadList` is currently in focus or not. Essentially a flag that lets us know whether the component is present in the viewport. Whenever present, it controls when updates to the `ThreadList` are active and when they are not. Best used in conjunction with hooks from popular navigation libraries (such as [`useIsFocused()` from React Navigation](https://reactnavigation.org/docs/use-is-focused/)) for lazy loading purposes.

| Type |
| ------- |
| boolean |

Example:

```tsx
import React from 'react';
import { useIsFocused } from '@react-navigation/native';
import { ThreadList } from 'stream-chat-react-native';

export const ThreadListScreen = () => {
const isFocused = useIsFocused();
return <ThreadList isFocused={isFocused} />;
};
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
A method that will be used as a callback whenever a thread in the list is clicked. As an example, it can be used to navigate to a thread screen displaying the thread.

| Type |
| ------------------------------------ |
| `(thread, channel) => Promise<void>` |

The arguments passed are as follows:

#### `thread`

An object containing two properties, `thread` and `threadInstance`. This entire object can be passed as the [`thread` prop](../core-components/channel#thread) to the `Channel` component.

| Type |
| ------ |
| object |

The `threadInstance` property is an instance of the [`Thread` class](https://github.com/GetStream/stream-chat-js/blob/master/src/thread.ts).

The `thread` property is a reference to the parent message of the thread.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
A custom UI component used to render the empty placeholder if there are no available threads.

| Type | Default |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | [`DefaultThreadListEmptyPlaceholder`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ThreadList/ThreadList.tsx) |
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
A custom UI component used to render the loading indicator when `isLoading` is `true`.

| Type | Default |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | [`DefaultThreadListLoadingIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ThreadList/ThreadList.tsx) |
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
A custom UI component used to render the loading indicator when `isLoadingNext` is `true`.

| Type | Default |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | [`DefaultThreadListLoadingMoreIndicator`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ThreadList/ThreadList.tsx) |
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
A custom UI component used to render the unread threads banner at the top of the list.

| Type | Default |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | [`ThreadListUnreadBanner`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ThreadList/ThreadListUnreadBanner.tsx) |
73 changes: 73 additions & 0 deletions docusaurus/docs/reactnative/contexts/thread-list-item-context.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
id: thread-list-item-context
title: ThreadListItemContext
---

import Channel from '../common-content/ui-components/channel/props/channel.mdx';

import Thread from '../common-content/contexts/thread-list-item-context/thread.mdx';

The `ThreadListItemContext` is provided by the [`ThreadListItem`](../../ui-components/thread-list-item) component. If you are not familiar with React Context API, please read about it on [React docs](https://reactjs.org/docs/context.html).

The `ThreadListItemContext` needs to be used within the [`ThreadList` component](../../ui-components/thread-list) as it depends on the [`ThreadsContext`](../threads-context).

## Basic Usage

The `ThreadListItemContext` can be consumed by any of the child components of `ThreadList` component as following:

```tsx
import { useContext } from 'react';
import { ThreadListItemContext } from 'stream-chat-react-native';

const value = useContext(ThreadListItemContext);
```

Alternatively, you can also use `useThreadListItemContext` hook provided by library to consume `ThreadListItemContext`.

```tsx
import { useThreadListItemContext } from 'stream-chat-react-native';

const value = useThreadListItemContext();
```

## Value

### `channel`

<Channel />

### `dateString`

A formatted date string that can be used as a thread timestamp. The default format is `HH:MM`.

| Type |
| ------ |
| string |

### `lastReply`

A [Message instance](https://github.com/GetStream/stream-chat-react-native/blob/493cdffcb5b2ee915b2f420e359ad685966a0dbe/package/src/components/MessageList/hooks/useMessageList.ts#L35) providing the latest message reply in the thread.

| Type |
| ----------- |
| MessageType |

### `ownUnreadMessageCount`

A number providing the number of unread messages for the particular thread.

| Type |
| ------ |
| number |

### `parentMessage`

A [Message instance](https://github.com/GetStream/stream-chat-react-native/blob/493cdffcb5b2ee915b2f420e359ad685966a0dbe/package/src/components/MessageList/hooks/useMessageList.ts#L35) providing the parent message of the thread.

| Type |
| ----------- |
| MessageType |

### `thread`

<Thread />
145 changes: 145 additions & 0 deletions docusaurus/docs/reactnative/contexts/threads-context.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
id: threads-context
title: ThreadsContext
---

import Channel from '../common-content/ui-components/channel/props/channel.mdx';

import AdditionalFlatListProps from '../common-content/contexts/threads-context/additional-flatlist-props.mdx';
import IsFocused from '../common-content/contexts/threads-context/is-focused.mdx';
import OnThreadSelect from '../common-content/contexts/threads-context/on-thread-select.mdx';
import ThreadListEmptyPlaceholder from '../common-content/contexts/threads-context/thread-list-empty-placeholder.mdx';
import ThreadListLoadingIndicator from '../common-content/contexts/threads-context/thread-list-loading-indicator.mdx';
import ThreadListLoadingMoreIndicator from '../common-content/contexts/threads-context/thread-list-loading-more-indicator.mdx';
import ThreadListUnreadBanner from '../common-content/contexts/threads-context/thread-list-unread-banner.mdx';

The `ThreadsContext` is provided by the [`ThreadList`](../../ui-components/thread-list) component. If you are not familiar with React Context API, please read about it on [React docs](https://reactjs.org/docs/context.html).

The `ThreadsContext` needs to be used within the [`Chat` component](../../core-components/chat) as it depends on the [`ChatContext`](./chat-context).

## Basic Usage

The `ThreadsContext` can be consumed by any of the child components of `Chat` as following:

```tsx
import { useContext } from 'react';
import { ThreadsContext } from 'stream-chat-react-native';

const value = useContext(ThreadsContext);
```

Alternatively, you can also use `useThreadsContext` hook provided by library to consume `ThreadContext`.

```tsx
import { useThreadsContext } from 'stream-chat-react-native';

const value = useThreadsContext();
```

## Value

### `isLoading` \*

A boolean flag that lets us know whether the threads are currently loading or not.

| Type | Default |
| ------- | ------- |
| boolean | false |

### `isLoadingMore` \*

A boolean flag that lets us whether the next page of threads is being loaded or not.

| Type | Default |
| ------- | ------- |
| boolean | false |

### `threads` \*

An array of [Thread](https://github.com/GetStream/stream-chat-js/blob/master/src/thread.ts) instances that are used as input for rendering the `ThreadList`.

| Type |
| ----- |
| array |

### `isFocused`

<IsFocused />

### `additionalFlatListProps`

<AdditionalFlatListProps />

### `loadMore`

A method that can be invoked to load more `threads`. Returns a promise.

| Type |
| --------------------- |
| `() => Promise<void>` |

### `onThreadSelect`

<OnThreadSelect />

#### `channel`

<Channel />

### `ThreadListEmptyPlaceholder`

<ThreadListEmptyPlaceholder />

### `ThreadListItem`

A custom UI component used to render each item within the `ThreadList`. It will override the UI of the [default `ThreadListItem`](./thread-list-item) while still keeping all of the data.

| Type | Default |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| ComponentType | [`ThreadListItem`](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/ThreadList/ThreadListItem.tsx) |

Example usage:

```tsx
import { Text, TouchableOpacity } from 'react-native';
import {
OverlayProvider,
Chat,
ThreadList,
useThreadListItemContext,
useThreadsContext,
} from 'stream-chat-react-native';

const ThreadListItem = () => {
const { parentMessage, thread, channel } = useThreadListItemContext();
const { onThreadSelect } = useThreadsContext();

return (
<TouchableOpacity onPress={() => onThreadSelect(thread, channel)}>
<Text>{parentMessage?.text || 'Text not available !'}</Text>
</TouchableOpacity>
);
};

const App = () => {
return (
<OverlayProvider>
<Chat client={client}>
<ThreadList ThreadListItem={ThreadListItem} />
</Chat>
</OverlayProvider>
);
};
```

### `ThreadListLoadingIndicator`

<ThreadListLoadingIndicator />

### `ThreadListLoadingMoreIndicator`

<ThreadListLoadingMoreIndicator />

### `ThreadListUnreadBanner`

<ThreadListUnreadBanner />
2 changes: 2 additions & 0 deletions docusaurus/docs/reactnative/customization/contexts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ The majority of the contexts within the SDK are established in the higher level
- [`OverlayContext`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/contexts/overlayContext/OverlayContext.tsx)
- [`ThemeContext`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/contexts/themeContext/ThemeContext.tsx)
- [`TranslationContext`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/contexts/translationContext/TranslationContext.tsx)
- [`ThreadListContext`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/contexts/threadsContext/ThreadsContext.tsx)
- [`ThreadListItemContext`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/contexts/threadsContext/ThreadListItemContext.tsx)
- `MessageSimple`
- [`MessageContext`](https://github.com/GetStream/stream-chat-react-native/blob/develop/package/src/contexts/messageContext/MessageContext.tsx)
- For Debugging using Flipper Plugin
Expand Down
Loading

0 comments on commit 39a2fb3

Please sign in to comment.