Skip to content

Commit

Permalink
Merge pull request #159 from GetStream/mention-enhancement
Browse files Browse the repository at this point in the history
Mention enhancement
  • Loading branch information
szuperaz authored Dec 9, 2021
2 parents 0dc4ea5 + ed23461 commit 91edeb9
Show file tree
Hide file tree
Showing 19 changed files with 364 additions and 111 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docusaurus/docs/Angular/code-examples/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Code examples",
"position": 6
}
138 changes: 138 additions & 0 deletions docusaurus/docs/Angular/code-examples/mention-actions.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
id: mention-actions
sidebar_position: 1
title: Mention actions
---

import Screenshot from "../assets/mention-screenshot.png";

In this example, we will demonstrate how to create custom mention actions if a user clicks on or hovers over a mention in a message.

## Custom mention template

You can provide a custom message template to the `MessageList` component:

```html
<div id="root">
<stream-channel-list></stream-channel-list>
<stream-channel>
<stream-channel-header></stream-channel-header>
<stream-message-list
[mentionTemplate]="mentionTemplate"
></stream-message-list>
<stream-notification-list></stream-notification-list>
<stream-message-input></stream-message-input>
</stream-channel>
</div>

<ng-template #mentionTemplate let-user="user">
<b>@{{ user.name || user.id }}</b>
</ng-template>
```

The `MessageList` component will provide the mentioned user in a variable called `user`, the object has a [`UserResponse`](https://github.com/GetStream/stream-chat-js/blob/master/src/types.ts) type and you can use it to display information about the user.

This template looks and works like the default mention template, however you can add interactions to this element.

## Display user information on click

In this step we will create a popover with additional user information that will be displayed if the user clicks on a mention. We are using the [`ngx-popperjs`](https://www.npmjs.com/package/ngx-popperjs) library for the popover, but you can use a different library as well.

### Install `ngx-popperjs`

Let's install the necessary dependencies:

```bash
npm install @popperjs/core ngx-popperjs --save
```

### Import the `NgxPopperjsModule` module

```typescript
import {NgxPopperjsModule} from 'ngx-popperjs';

@NgModule({
// ...
imports: [
// ...
NgxPopperjsModule
]
})
```

### Import SCSS

Add this to your `styles.scss`:

```scss
@import "~ngx-popperjs/scss/theme-white";
```

[CSS is also supported.](https://www.npmjs.com/package/ngx-popperjs)

### Create the popover

```html
<ng-template #mentionTemplate let-user="user">
<span
style="cursor: pointer"
[popper]="popperContent"
[popperPositionFixed]="true"
>
<b>@{{ user.name || user.id }}</b>
</span>
<popper-content #popperContent style="display: inline">
<div style="display: flex; align-items: center">
<stream-avatar
[imageUrl]="user.image"
[name]="user.name || user.id"
></stream-avatar>
<b>{{ user.name || user.id }}</b>
<span>&nbsp;{{ user.online ? "online" : "offline" }}</span>
</div>
</popper-content>
</ng-template>
```

This is the popover that is displayed if we click on a mention in a message:

<img src={Screenshot} width="500" />

[`ngx-popperjs`](https://www.npmjs.com/package/ngx-popperjs) has a lot of other configuration options, feel free to explore those.

## Display user information on hover

Let's modify our solution and display the popover on hover instead of click:

We need to add a variable to our component class:

```typescript
import { NgxPopperjsTriggers } from "ngx-popperjs";

popoverTrigger = NgxPopperjsTriggers.hover;
```

And modify our template:

```html
<ng-template #mentionTemplate let-user="user">
<span
style="cursor: pointer"
[popper]="popperContent"
[popperPositionFixed]="true"
[popperTrigger]="popoverTrigger"
>
<b>@{{ user.name || user.id }}</b>
</span>
<popper-content #popperContent style="display: inline">
<div style="display: flex; align-items: center">
<stream-avatar
[imageUrl]="user.image"
[name]="user.name || user.id"
></stream-avatar>
<b>{{ user.name || user.id }}</b>
<span>&nbsp;{{ user.online ? "online" : "offline" }}</span>
</div>
</popper-content>
</ng-template>
```
2 changes: 2 additions & 0 deletions docusaurus/docs/Angular/components/channel-preview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ The channel list uses the `ChannelPreview` component to display channels, if you
</ng-template>
```

Your custom template can receive the same inputs (with the same name) as the default `ChannelPreview` component.

:::note

If you want to build your own `ChannelPreview` component, you might find the following building blocks useful:
Expand Down
2 changes: 2 additions & 0 deletions docusaurus/docs/Angular/components/message-input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ If you want to create your own message input, here is how to use it:

The default chat UI uses the message input in two different places: at the bottom of the channel to send new message, and in the message list to edit a message.

Your custom template can receive the same inputs (with the same name) as the default `MessageInput` component.

:::note
If you want to create your own message input, you can use the following building blocks:

Expand Down
8 changes: 8 additions & 0 deletions docusaurus/docs/Angular/components/message-list.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ The input used for message edit. By default, the [default message input componen
| ----------- |
| TemplateRef |

### mentionTemplate

The template used to display a mention in a message. It receives the mentioned user in a variable called `user` with the type [`UserResponse`](https://github.com/GetStream/stream-chat-js/blob/master/src/types.ts). You can provide your own template if you want to [add actions to mentions](../code-examples/mention-actions.mdx).

| Type |
| ----------- |
| TemplateRef |

### areReactionsEnabled

If true, the message reactions are displayed. Users can also react to messages if they have the necessary [channel capability](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript).
Expand Down
10 changes: 10 additions & 0 deletions docusaurus/docs/Angular/components/message.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ The message list uses the `Message` component to display messages, if you want t
</ng-template>
```

Your custom template can receive the same inputs (with the same name) as the default `Message` component.

:::note

If you want to build your own `Message` component, you might find the following building blocks useful:
Expand Down Expand Up @@ -157,3 +159,11 @@ The input used for message edit. By default, the [default message input componen
| Type |
| ----------- |
| TemplateRef |

### mentionTemplate

The template used to display a mention in a message. It receives the mentioned user in a variable called `user` with the type [`UserResponse`](https://github.com/GetStream/stream-chat-js/blob/master/src/types.ts). You can provide your own template if you want to [add actions to mentions](../code-examples/mention-actions.mdx).

| Type |
| ----------- |
| TemplateRef |
4 changes: 0 additions & 4 deletions docusaurus/docs/Angular/pipes/_category_.json

This file was deleted.

51 changes: 0 additions & 51 deletions docusaurus/docs/Angular/pipes/mentions-highlight.mdx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
lastSentMessageId && message?.id === lastSentMessageId
),
canReceiveReadEvents: canReceiveReadEvents,
messageInputTemplate: messageInputTemplate
messageInputTemplate: messageInputTemplate,
mentionTemplate: mentionTemplate
}
"
></ng-container>
Expand All @@ -43,6 +44,7 @@
[enabledMessageActions]="enabledMessageActions"
[canReceiveReadEvents]="canReceiveReadEvents"
[messageInputTemplate]="messageInputTemplate"
[mentionTemplate]="mentionTemplate"
></stream-message>
</ng-template>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { TranslateModule } from '@ngx-translate/core';
import { Channel } from 'stream-chat';
import { ChannelService } from '../channel.service';
import { ChatClientService } from '../chat-client.service';
import { HighlightMentionsPipe } from '../message/highlight-mentions.pipe';
import { MessageComponent } from '../message/message.component';
import {
MockChannelService,
Expand All @@ -35,11 +34,7 @@ describe('MessageListComponent', () => {
channelServiceMock = mockChannelService();
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot()],
declarations: [
MessageComponent,
MessageListComponent,
HighlightMentionsPipe,
],
declarations: [MessageComponent, MessageListComponent],
providers: [
{ provide: ChannelService, useValue: channelServiceMock },
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { MessageActions } from '../message-actions-box/message-actions-box.compo
export class MessageListComponent implements AfterViewChecked, OnChanges {
@Input() messageTemplate: TemplateRef<any> | undefined;
@Input() messageInputTemplate: TemplateRef<any> | undefined;
@Input() mentionTemplate: TemplateRef<any> | undefined;
@Input() areReactionsEnabled = true;
/* eslint-disable-next-line @angular-eslint/no-input-rename */
@Input('enabledMessageActions') enabledMessageActionsInput: MessageActions[] =
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,30 @@
(click)="textClicked()"
(keyup.enter)="textClicked()"
data-testid="text"
[innerHTML]="
message?.html || message?.text
| highlightMentions: message?.mentioned_users
"
></div>
>
<p>
<!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->
<ng-container *ngFor="let part of messageTextParts">
<span
*ngIf="part.type === 'text'; else mention"
[innerHTML]="part.content"
></span>
<ng-template #mention>
<ng-container *ngIf="mentionTemplate; else defaultMention">
<ng-container
*ngTemplateOutlet="
mentionTemplate;
context: { user: part.user! }
"
></ng-container>
</ng-container>
<ng-template #defaultMention>
<b>{{ part.content }}</b>
</ng-template>
</ng-template>
</ng-container>
</p>
</div>
</div>
</div>
<div class="str-chat__message-data str-chat__message-simple-data">
Expand Down
Loading

0 comments on commit 91edeb9

Please sign in to comment.