Skip to content

Commit

Permalink
Merge branch 'master' into feat/pass-channel-to-doSendMessageRequest-…
Browse files Browse the repository at this point in the history
…doUpdateMessageRequest

# Conflicts:
#	src/components/Channel/Channel.tsx
  • Loading branch information
MartinCupela committed Nov 27, 2023
2 parents b8dc1f1 + f87de16 commit a833f76
Show file tree
Hide file tree
Showing 38 changed files with 2,491 additions and 1,802 deletions.
34 changes: 34 additions & 0 deletions .babelrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// The content of babel.config.js copied here. This is due to the bug in jest - https://github.com/jestjs/jest/issues/11741
// The bug has been resolved with jest 30 - https://github.com/jestjs/jest/commit/983274ac08c67d2a445e111b2dfaf81020f912b2
module.exports = {
env: {
production: {
presets: [
[
'@babel/env',
{
modules: false,
},
],
],
},
test: {
plugins: ['transform-es2015-modules-commonjs'],
presets: [
[
'@babel/preset-env',
{
modules: 'commonjs',
},
],
],
},
},
ignore: ['src/@types/*'],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-transform-runtime',
'babel-plugin-dynamic-import-node',
],
presets: ['@babel/preset-typescript', '@babel/env', '@babel/preset-react'],
};
45 changes: 0 additions & 45 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,51 +23,6 @@ jobs:
- name: 🧪 tsc
run: yarn types --noEmit

e2e:
runs-on: ubuntu-latest
name: End-to-end tests
steps:
- uses: actions/checkout@v3

- name: 💾 Cache Dependencies
uses: actions/cache@v3
with:
path: ./node_modules
key: ${{ runner.os }}-${{ matrix.node }}-modules-${{ hashFiles('**/yarn.lock') }}

- name: 🔨 Install Dependencies
run: yarn install --frozen-lockfile --ignore-engines --ignore-scripts

- name: ⚗️ End-to-end tests
run: |
npx playwright install
npx playwright install-deps
yarn e2e-fixtures
# running with --browser=all causes failures
yarn e2e --browser=chromium
yarn e2e --browser=webkit
yarn e2e --browser=firefox
env:
E2E_JUMP_TO_MESSAGE_CHANNEL: jump-to-message
E2E_ADD_MESSAGE_CHANNEL: add-message
E2E_TEST_USER_1: test-user-1
E2E_TEST_USER_2: test-user-2
E2E_APP_KEY: ${{ secrets.E2E_APP_KEY }}
E2E_APP_SECRET: ${{ secrets.E2E_APP_SECRET }}
E2E_TEST_USER_1_TOKEN: ${{ secrets.E2E_TEST_USER_1_TOKEN }}
E2E_TEST_USER_2_TOKEN: ${{ secrets.E2E_TEST_USER_2_TOKEN }}
E2E_ADDITIONAL_CHANNELS: mr-channel-1, mr-channel-2, edit-message-channel, pin-message-channel
E2E_LONG_MESSAGE_LISTS_CHANNEL: navigate-long-message-lists
E2E_ATTACHMENT_SIZING_CHANNEL: attachment-sizing

- name: 🎥 Upload Artifacts
uses: actions/upload-artifact@v3
if: ${{ always() }}
with:
name: E2E_Artifacts
path: ./test-results
retention-days: 1

test:
runs-on: ubuntu-latest
strategy:
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: E2E

on: [push]

jobs:
e2e:
runs-on: ubuntu-latest
name: End-to-end tests
steps:
- uses: actions/checkout@v3

- name: 💾 Cache Dependencies
uses: actions/cache@v3
with:
path: ./node_modules
key: ${{ runner.os }}-${{ matrix.node }}-modules-${{ hashFiles('**/yarn.lock') }}

- name: 🔨 Install Dependencies
run: yarn install --frozen-lockfile --ignore-engines --ignore-scripts

- name: ⚗️ End-to-end tests
run: |
npx playwright install
npx playwright install-deps
yarn e2e-fixtures
# running with --browser=all causes failures
yarn e2e --browser=chromium
yarn e2e --browser=webkit
yarn e2e --browser=firefox
env:
E2E_JUMP_TO_MESSAGE_CHANNEL: jump-to-message
E2E_ADD_MESSAGE_CHANNEL: add-message
E2E_TEST_USER_1: test-user-1
E2E_TEST_USER_2: test-user-2
E2E_APP_KEY: ${{ secrets.E2E_APP_KEY }}
E2E_APP_SECRET: ${{ secrets.E2E_APP_SECRET }}
E2E_TEST_USER_1_TOKEN: ${{ secrets.E2E_TEST_USER_1_TOKEN }}
E2E_TEST_USER_2_TOKEN: ${{ secrets.E2E_TEST_USER_2_TOKEN }}
E2E_ADDITIONAL_CHANNELS: mr-channel-1, mr-channel-2, edit-message-channel, pin-message-channel
E2E_LONG_MESSAGE_LISTS_CHANNEL: navigate-long-message-lists
E2E_ATTACHMENT_SIZING_CHANNEL: attachment-sizing

- name: 🎥 Upload Artifacts
uses: actions/upload-artifact@v3
if: ${{ always() }}
with:
name: E2E_Artifacts
path: ./test-results
retention-days: 1
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
## [10.20.1](https://github.com/GetStream/stream-chat-react/compare/v10.20.0...v10.20.1) (2023-11-20)


### Bug Fixes

* calculate pagination stop from custom channel query message limit ([#2180](https://github.com/GetStream/stream-chat-react/issues/2180)) ([8374af1](https://github.com/GetStream/stream-chat-react/commit/8374af1048b81c307d0687d7730df6a96633b7e6))

## [10.20.0](https://github.com/GetStream/stream-chat-react/compare/v10.19.0...v10.20.0) (2023-11-16)


### Bug Fixes

* lift notifications above modal overlay ([#2175](https://github.com/GetStream/stream-chat-react/issues/2175)) ([17d98f4](https://github.com/GetStream/stream-chat-react/commit/17d98f40eaea0a134a501deea14605b71d965871))


### Features

* allow to configure channel query options ([#2177](https://github.com/GetStream/stream-chat-react/issues/2177)) ([4f91d9a](https://github.com/GetStream/stream-chat-react/commit/4f91d9a65e752f4bcab2000f5d633b57ae4d6b0e))

## [10.19.0](https://github.com/GetStream/stream-chat-react/compare/v10.18.0...v10.19.0) (2023-11-14)


Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
> building chat applications.
[![NPM](https://img.shields.io/npm/v/stream-chat-react.svg)](https://www.npmjs.com/package/stream-chat-react)
[![build](https://github.com/GetStream/stream-chat-react/workflows/test/badge.svg)](https://github.com/GetStream/stream-chat-react/actions)
[![build](https://github.com/GetStream/stream-chat-react/actions/workflows/ci.yml/badge.svg)](https://github.com/GetStream/stream-chat-react/actions)
[![Component Reference](https://img.shields.io/badge/docs-component%20reference-blue.svg)](https://getstream.io/chat/docs/sdk/react/)
[![codecov](https://codecov.io/gh/GetStream/stream-chat-react/branch/master/graph/badge.svg)](https://codecov.io/gh/GetStream/stream-chat-react)

Expand Down
33 changes: 33 additions & 0 deletions docusaurus/docs/React/components/core-components/channel.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,39 @@ Custom UI component to display a user's avatar.
| --------- | ---------------------------------------------------------- |
| component | <GHComponentLink text='Avatar' path='/Avatar/Avatar.tsx'/> |

### channelQueryOptions

Optional configuration parameters used for the initial channel query. Applied only if the value of `channel.initialized` is false. If the channel instance has already been initialized (channel has been queried), then the channel query will be skipped and channelQueryOptions will not be applied.

In the example below, we specify, that the first page of messages when a channel is queried should have 20 messages (the default is 100). Note that the `channel` prop has to be passed along `channelQueryOptions`.

```tsx
import {ChannelQueryOptions} from "stream-chat";
import {Channel, useChatContext} from "stream-chat-react";

const channelQueryOptions: ChannelQueryOptions = {
messages: { limit: 20 },
};

type ChannelRendererProps = {
id: string;
type: string;
};

const ChannelRenderer = ({id, type}: ChannelRendererProps) => {
const { client } = useChatContext();
return (
<Channel channel={client.channel(type, id)} channelQueryOptions={channelQueryOptions}>
{/* Channel children */}
</Channel>
);
}
```

| Type |
|-----------------------|
| `ChannelQueryOptions` |

### CooldownTimer

Custom UI component to display the slow mode cooldown timer.
Expand Down
109 changes: 36 additions & 73 deletions docusaurus/docs/React/components/core-components/message-list.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,42 @@ const App = () => (
);
```

#### Custom element rendering

If you feel like the default output is sufficient, but you'd like to adjust how certain [ReactMarkdown components](https://github.com/remarkjs/react-markdown#appendix-b-components) look like (like `strong` element generated by typing \*\*strong\*\*) you can do so by passing down options to a third argument of the default `renderText` function:

:::note
Types `mention` and `emoji` are special case component types generated by our SDK's custom rehype plugins.
:::

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

const StrongComponent = ({ children }) => <b className='custom-strong-class-name'>{children}</b>;

const MentionComponent = ({ children, node: { mentionedUser } }) => (
<a data-user-id={mentionedUser.id} href={`/user-profile/${mentionedUser.id}`}>
{children}
</a>
);

const App = () => (
<Chat client={client}>
<Channel>
<Window>
<MessageList
renderText={(text, mentionedUsers) =>
renderText(text, mentionedUsers, {
customMarkDownRenderers: { strong: StrongComponent, mention: MentionComponent },
})
}
/>
</Window>
</Channel>
</Chat>
);
```

#### Custom remark and rehype plugins

If you would like to extend the array of plugins used to parse the markdown, you can provide your own lists of remark resp. rehype plugins. The logic that determines what plugins are used and in which order can be specified in custom `getRehypePlugins` and `getRemarkPlugins` functions. These receive the default array of rehype and remark plugins for further customization. Both custom functions ought to be passed to the third `renderText()` parameter. An example follows:
Expand Down Expand Up @@ -182,79 +218,6 @@ const CustomMessageList = () => (
);
```

#### Optional remark and rehype plugins

The SDK provides the following plugins that are not applied to the text parsing by the default `renderText()` implementation. However, these can be included by simply overriding the defaults with `getRemarkPlugins` and `getRehypePlugins` parameters as described in [the section about custom plugins](#custom-remark-and-rehype-plugins).

Currently, there are the following optional remark plugins available in the SDK:

- `htmlToTextPlugin` - keeps the HTML tags in the resulting text string.
- `keepLineBreaksPlugin` - replaces empty lines in text with line breaks ([according to the CommonMark Markdown specification](https://spec.commonmark.org/0.30/#hard-line-breaks), the empty lines - meaning newline characters `\n` - are not transformed to `<br/>` elements).

These can be plugged in as follows:

```tsx
import { UserResponse } from 'stream-chat';
import {
htmlToTextPlugin,
keepLineBreaksPlugin,
MessageList,
MessageListProps,
renderText,
RenderTextPluginConfigurator,
} from 'stream-chat-react';

const getRemarkPlugins: RenderTextPluginConfigurator = (plugins) => [
htmlToTextPlugin,
keepLineBreaksPlugin,
...plugins,
];

function customRenderText(text?: string, mentionedUsers?: UserResponse[]) {
return renderText(text, mentionedUsers, { getRemarkPlugins });
}

export const CustomMessageList = (props: MessageListProps) => (
<MessageList {...props} renderText={customRenderText} />
);
```

#### Custom element rendering

If you feel like the default output is sufficient, but you'd like to adjust how certain [ReactMarkdown components](https://github.com/remarkjs/react-markdown#appendix-b-components) look like (like `strong` element generated by typing \*\*strong\*\*) you can do so by passing down options to a third argument of the default `renderText` function:

:::note
Types `mention` and `emoji` are special case component types generated by our SDK's custom rehype plugins.
:::

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

const StrongComponent = ({ children }) => <b className='custom-strong-class-name'>{children}</b>;

const MentionComponent = ({ children, node: { mentionedUser } }) => (
<a data-user-id={mentionedUser.id} href={`/user-profile/${mentionedUser.id}`}>
{children}
</a>
);

const App = () => (
<Chat client={client}>
<Channel>
<Window>
<MessageList
renderText={(text, mentionedUsers) =>
renderText(text, mentionedUsers, {
customMarkDownRenderers: { strong: StrongComponent, mention: MentionComponent },
})
}
/>
</Window>
</Channel>
</Chat>
);
```

## Props

### additionalMessageInputProps
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
id: message-text-rendering-v11
sidebar_position: 3
title: Message text rendering 11.0.0
keywords: [migration guide, upgrade, message, text rendering, breaking changes, v11]
---

Optional remark plugins `htmlToTextPlugin`, `keepLineBreaksPlugin` introduced with [stream-chat-react@v10.19.0](https://github.com/GetStream/stream-chat-react/releases/tag/v10.19.0) are now included among the default remark plugins. That means that in the messages that originally contained a sequence of multiple newline characters `\n`, these will be replaced with line break elements `<br/>`. The number of line breaks equals count of newline characters minus 1.
The dependencies used to parse the markdown with [`renderText()` function](../../components/core-components/message_list/#rendering-message-text-with-rendertext-function) have been upgraded as a result of that, the following changes had to be performed in stream-chat-react library:

### `ReactMarkdownProps` dropped from `customMarkDownRenderers`

`RenderTextOptions.customMarkDownRenderers`- a mapping of element name and corresponding React component to be rendered. The components are no longer accepting `ReactMarkdownProps`

### User mention renderer props change

The `RenderTextOptions.customMarkDownRenderers.mention` props have been reduced. From now on, only `children` and `node` are passed to the component. And so now `mention` renderer props look as follows:

```ts
import { PropsWithChildren } from 'react';
import type { UserResponse } from 'stream-chat';
import type { DefaultStreamChatGenerics } from 'stream-chat-react';

type MentionProps<
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
> = PropsWithChildren<{
node: {
mentionedUser: UserResponse<StreamChatGenerics>;
};
}>;
```

### Adjust custom rehype or remark plugins

If you have implemented your own rehype or remark plugin using `visit` function from the library `unist-util-visit` beware that the `index` and `parent` arguments of the `Visitor` function cannot be `null` but `undefined` instead. You should be notified by Typescript about this and should adjust the type checks accordingly.

If you would like to prevent applying plugins `htmlToTextPlugin`, `keepLineBreaksPlugin`, you can customize your `renderText()` by overriding the remark plugins. The example below will keep the plugin `remarkGfm` and exclude the rest:

```tsx
import remarkGfm from 'remark-gfm';
import { renderText, RenderTextPluginConfigurator } from 'stream-chat-react';


const getRemarkPlugins: RenderTextPluginConfigurator = () => {
return [[remarkGfm, { singleTilde: false }]];
};

const customRenderText = (text, mentionedUsers) =>
renderText(text, mentionedUsers, {
getRemarkPlugins
});
const CustomMessageList = () => (
<MessageList renderText={customRenderText}/>
);
```
2 changes: 2 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ module.exports = {
},
preset: 'ts-jest',
setupFiles: ['core-js'],
setupFilesAfterEnv: ['<rootDir>/jest.env.setup.js'],
testEnvironment: 'jsdom',
testPathIgnorePatterns: ['/node_modules/', '/examples/', '__snapshots__', '/e2e/'],
testRegex: [
/**
Expand Down
Loading

0 comments on commit a833f76

Please sign in to comment.