Skip to content

Commit 375bbca

Browse files
authored
Merge pull request #539 from GetStream/custom-message-action-click
feat: Allow custom event handler for message actions button
2 parents b0a1e9e + bc07a09 commit 375bbca

File tree

9 files changed

+60
-30
lines changed

9 files changed

+60
-30
lines changed

docusaurus/docs/Angular/components/MessageActionsBoxComponent.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ export class CustomMessageComponent {
3030

3131
## Customization
3232

33-
You can provide your own message actions box component (or just a template for the items) by the [`CustomTemplatesService`](../services/CustomTemplatesService.mdx)
33+
- You can provide your own message actions box component (or just a template for the items) by the [`CustomTemplatesService`](../services/CustomTemplatesService.mdx).
34+
- You can extend the built-in actions with custom actions, for more info see the [`MessageActionsService`](../../services/MessageActionsService/#customactions)
35+
- You can also provide a custom event handler method to be called when the message actions button is clicked, for more info see the [`MessageActionsService`](../../services/MessageActionsService/#customactionclickhandler)
3436

3537
[//]: # "Start of generated content"
3638
[//]: # "End of generated content"

package-lock.json

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
"@ngx-translate/core": "^13.0.0",
118118
"@ngx-translate/http-loader": "^6.0.0",
119119
"@popperjs/core": "^2.11.5",
120-
"@stream-io/stream-chat-css": "4.5.0",
120+
"@stream-io/stream-chat-css": "4.6.0",
121121
"@stream-io/transliterate": "^1.5.2",
122122
"angular-mentions": "^1.4.0",
123123
"dayjs": "^1.10.7",

projects/stream-chat-angular/src/lib/message-actions-box/message-actions-box.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export class MessageActionsBoxComponent
7070
/**
7171
* An event which emits `true` if the edit message modal is open, and `false` when it is closed.
7272
*
73-
* @deprecated components should use `messageReactionsService.getAuthorizedMessageActionsCount` method
73+
* @deprecated components should use `messageReactionsService.messageToEdit$` Observable
7474
*
7575
* More information: https://getstream.io/chat/docs/sdk/angular/services/MessageActionsService
7676
*/

projects/stream-chat-angular/src/lib/message-actions.service.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
CustomMessageActionItem,
55
DefaultStreamChatGenerics,
66
MessageActionItem,
7+
MessageActionsClickDetails,
78
StreamMessage,
89
} from './types';
910
import { ChatClientService } from './chat-client.service';
@@ -99,6 +100,10 @@ export class MessageActionsService<
99100
* You can pass your own custom actions that will be displayed inside the built-in message actions component
100101
*/
101102
customActions$ = new BehaviorSubject<CustomMessageActionItem[]>([]);
103+
/**
104+
* By default the [`MessageComponent`](../../components/MessageComponent) will display the [`MessageActionsBoxComponent`](../../components/MessageActionsBoxComponent). You can override that behavior by providing your own event handler.
105+
*/
106+
customActionClickHandler?: (details: MessageActionsClickDetails<T>) => void;
102107

103108
constructor(
104109
private chatClientService: ChatClientService,

projects/stream-chat-angular/src/lib/message/message.component.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<div
3636
class="str-chat__message-simple__actions str-chat__message-options"
3737
data-testid="message-options"
38+
[class.str-chat__message-actions-open]="isActionBoxOpen"
3839
[class.str-chat__message-edit-in-progress]="isEditing"
3940
*ngIf="areOptionsVisible"
4041
>
@@ -56,6 +57,7 @@
5657
[popperHideOnClickOutside]="true"
5758
[popperHideOnMouseLeave]="false"
5859
[popperDisableAnimation]="true"
60+
(popperOnHidden)="isActionBoxOpen = false"
5961
>
6062
<popper-content #popperContent>
6163
<ng-template
@@ -87,8 +89,8 @@
8789
<div
8890
class="str-chat__message-actions-box-button"
8991
data-testid="action-icon"
90-
(click)="isActionBoxOpen = !isActionBoxOpen"
91-
(keyup.enter)="isActionBoxOpen = !isActionBoxOpen"
92+
(click)="messageActionsClicked()"
93+
(keyup.enter)="messageActionsClicked()"
9294
*ngIf="visibleMessageActionsCount > 0"
9395
>
9496
<stream-icon-placeholder

projects/stream-chat-angular/src/lib/message/message.component.spec.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -549,16 +549,22 @@ describe('MessageComponent', () => {
549549
expect(queryMessageActionsBoxComponent()?.isOpen).toBeTrue();
550550
});
551551

552-
it('should close message actions box on mouseleave event', () => {
552+
it('should call custom message actions click handler', () => {
553+
const service = TestBed.inject(MessageActionsService);
554+
const spy = jasmine.createSpy();
555+
service.customActionClickHandler = spy;
553556
component.enabledMessageActions = ['update-own-message', 'flag-message'];
554-
component.isActionBoxOpen = true;
555557
component.ngOnChanges({ enabledMessageActions: {} as SimpleChange });
556558
fixture.detectChanges();
557559

558-
queryContainer()?.dispatchEvent(new Event('mouseleave'));
559-
fixture.detectChanges();
560+
queryActionIcon()?.click();
560561

561-
expect(component.isActionBoxOpen).toBeFalse();
562+
expect(spy).toHaveBeenCalledWith({
563+
message: component.message,
564+
enabledActions: component.enabledMessageActions,
565+
isMine: component.isSentByCurrentUser,
566+
customActions: component.customActions,
567+
});
562568
});
563569

564570
it('should provide #enabledActions to message actions box', () => {

projects/stream-chat-angular/src/lib/message/message.component.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ export class MessageComponent
161161
}
162162
if (isEditing !== this.isEditing) {
163163
this.isEditing = isEditing;
164+
if (!this.isEditing) {
165+
this.isActionBoxOpen = false;
166+
}
164167
if (this.isViewInited) {
165168
this.cdRef.detectChanges();
166169
}
@@ -257,17 +260,28 @@ export class MessageComponent
257260

258261
ngAfterViewInit(): void {
259262
this.isViewInited = true;
260-
this.ngZone.runOutsideAngular(() => {
261-
this.container?.nativeElement.addEventListener('mouseleave', () =>
262-
this.mouseLeft()
263-
);
264-
});
265263
}
266264

267265
ngOnDestroy(): void {
268266
this.subscriptions.forEach((s) => s.unsubscribe());
269267
}
270268

269+
messageActionsClicked() {
270+
if (!this.message) {
271+
return;
272+
}
273+
if (this.messageActionsService.customActionClickHandler) {
274+
this.messageActionsService.customActionClickHandler({
275+
message: this.message,
276+
enabledActions: this.enabledMessageActions,
277+
customActions: this.customActions,
278+
isMine: this.isSentByCurrentUser,
279+
});
280+
} else {
281+
this.isActionBoxOpen = !this.isActionBoxOpen;
282+
}
283+
}
284+
271285
getAttachmentListContext(): AttachmentListContext {
272286
return {
273287
messageId: this.message?.id || '',
@@ -386,14 +400,6 @@ export class MessageComponent
386400
this.createMessageParts(false);
387401
}
388402

389-
mouseLeft() {
390-
if (this.isActionBoxOpen) {
391-
this.ngZone.run(() => {
392-
this.isActionBoxOpen = false;
393-
});
394-
}
395-
}
396-
397403
private createMessageParts(shouldTranslate = true) {
398404
this.messageTextParts = undefined;
399405
this.messageText = undefined;

projects/stream-chat-angular/src/lib/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,12 @@ export type MessageReactionClickDetails = {
410410
messageId: string;
411411
reactionType: string;
412412
};
413+
414+
export type MessageActionsClickDetails<
415+
T extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
416+
> = {
417+
message: StreamMessage<T>;
418+
enabledActions: string[];
419+
isMine: boolean;
420+
customActions: CustomMessageActionItem[];
421+
};

0 commit comments

Comments
 (0)