Skip to content

Commit baa16bd

Browse files
committed
Merge branch 'feat/voiceMessageHistoryLink' into feat/callHistoryCore
2 parents eb0e612 + aac855c commit baa16bd

File tree

4 files changed

+75
-28
lines changed

4 files changed

+75
-28
lines changed

.changeset/strong-maps-act.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@rocket.chat/meteor": minor
3+
"@rocket.chat/ui-voip": minor
4+
---
5+
6+
Introduces an info button to voice call's in-chat history message, which opens a contextual bar with more detailed information about the voice call.

apps/meteor/server/services/media-call/service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ export class MediaCallService extends ServiceClassInternal implements IMediaCall
193193
const state = this.getCallHistoryItemState(call);
194194
const duration = this.getCallDuration(call);
195195

196-
const record = getHistoryMessagePayload(state, duration);
196+
const record = getHistoryMessagePayload(state, duration, call._id);
197197

198198
try {
199199
const message = await sendMessage(user, record, room, false);

packages/ui-voip/src/ui-kit/getHistoryMessagePayload.spec.ts

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import { callStateToTranslationKey, callStateToIcon, getFormattedCallDuration, getHistoryMessagePayload } from './getHistoryMessagePayload';
1+
import {
2+
callStateToTranslationKey,
3+
callStateToIcon,
4+
getFormattedCallDuration,
5+
getHistoryMessagePayload,
6+
getHistoryAction,
7+
} from './getHistoryMessagePayload';
28

39
const appId = 'media-call-core';
410
describe('callStateToTranslationKey', () => {
@@ -31,27 +37,27 @@ describe('callStateToTranslationKey', () => {
3137
describe('callStateToIcon', () => {
3238
it('should return correct icon for "ended" state', () => {
3339
const result = callStateToIcon('ended');
34-
expect(result).toEqual({ type: 'icon', icon: 'phone-off', variant: 'secondary' });
40+
expect(result).toEqual({ type: 'icon', icon: 'phone-off', variant: 'secondary', framed: true });
3541
});
3642

3743
it('should return correct icon for "not-answered" state', () => {
3844
const result = callStateToIcon('not-answered');
39-
expect(result).toEqual({ type: 'icon', icon: 'clock', variant: 'danger' });
45+
expect(result).toEqual({ type: 'icon', icon: 'clock', variant: 'danger', framed: true });
4046
});
4147

4248
it('should return correct icon for "failed" state', () => {
4349
const result = callStateToIcon('failed');
44-
expect(result).toEqual({ type: 'icon', icon: 'phone-issue', variant: 'danger' });
50+
expect(result).toEqual({ type: 'icon', icon: 'phone-issue', variant: 'danger', framed: true });
4551
});
4652

4753
it('should return correct icon for "error" state', () => {
4854
const result = callStateToIcon('error');
49-
expect(result).toEqual({ type: 'icon', icon: 'phone-issue', variant: 'danger' });
55+
expect(result).toEqual({ type: 'icon', icon: 'phone-issue', variant: 'danger', framed: true });
5056
});
5157

5258
it('should return correct icon for "transferred" state', () => {
5359
const result = callStateToIcon('transferred');
54-
expect(result).toEqual({ type: 'icon', icon: 'arrow-forward', variant: 'secondary' });
60+
expect(result).toEqual({ type: 'icon', icon: 'arrow-forward', variant: 'secondary', framed: true });
5561
});
5662
});
5763

@@ -102,9 +108,24 @@ describe('getFormattedCallDuration', () => {
102108
});
103109
});
104110

111+
const actionObj = {
112+
type: 'icon_button',
113+
icon: { type: 'icon', icon: 'info', variant: 'default' },
114+
actionId: 'open-history',
115+
appId,
116+
blockId: 'callid',
117+
};
118+
119+
describe('getHistoryAction', () => {
120+
it('should return correct action for "ended" state', () => {
121+
const result = getHistoryAction('callid');
122+
expect(result).toEqual(actionObj);
123+
});
124+
});
125+
105126
describe('getHistoryMessagePayload', () => {
106127
it('should return correct payload for "ended" state without duration', () => {
107-
const result = getHistoryMessagePayload('ended', undefined);
128+
const result = getHistoryMessagePayload('ended', undefined, 'callid');
108129
expect(result).toEqual({
109130
msg: '',
110131
groupable: false,
@@ -116,9 +137,10 @@ describe('getHistoryMessagePayload', () => {
116137
{
117138
background: 'default',
118139
elements: [
119-
{ type: 'icon', icon: 'phone-off', variant: 'secondary' },
140+
{ type: 'icon', icon: 'phone-off', variant: 'secondary', framed: true },
120141
{ type: 'mrkdwn', i18n: { key: 'Call_ended_bold' }, text: 'Call ended' },
121142
],
143+
action: actionObj,
122144
},
123145
],
124146
},
@@ -127,7 +149,7 @@ describe('getHistoryMessagePayload', () => {
127149
});
128150

129151
it('should return correct payload for "ended" state with duration', () => {
130-
const result = getHistoryMessagePayload('ended', 125);
152+
const result = getHistoryMessagePayload('ended', 125, 'callid');
131153
expect(result).toEqual({
132154
msg: '',
133155
groupable: false,
@@ -139,9 +161,10 @@ describe('getHistoryMessagePayload', () => {
139161
{
140162
background: 'default',
141163
elements: [
142-
{ type: 'icon', icon: 'phone-off', variant: 'secondary' },
164+
{ type: 'icon', icon: 'phone-off', variant: 'secondary', framed: true },
143165
{ type: 'mrkdwn', i18n: { key: 'Call_ended_bold' }, text: 'Call ended' },
144166
],
167+
action: actionObj,
145168
},
146169
{
147170
background: 'secondary',
@@ -154,7 +177,7 @@ describe('getHistoryMessagePayload', () => {
154177
});
155178

156179
it('should return correct payload for "not-answered" state', () => {
157-
const result = getHistoryMessagePayload('not-answered', undefined);
180+
const result = getHistoryMessagePayload('not-answered', undefined, 'callid');
158181
expect(result).toEqual({
159182
msg: '',
160183
groupable: false,
@@ -166,9 +189,10 @@ describe('getHistoryMessagePayload', () => {
166189
{
167190
background: 'default',
168191
elements: [
169-
{ type: 'icon', icon: 'clock', variant: 'danger' },
192+
{ type: 'icon', icon: 'clock', variant: 'danger', framed: true },
170193
{ type: 'mrkdwn', i18n: { key: 'Call_not_answered_bold' }, text: 'Call not answered' },
171194
],
195+
action: actionObj,
172196
},
173197
],
174198
},
@@ -177,7 +201,7 @@ describe('getHistoryMessagePayload', () => {
177201
});
178202

179203
it('should return correct payload for "failed" state', () => {
180-
const result = getHistoryMessagePayload('failed', undefined);
204+
const result = getHistoryMessagePayload('failed', undefined, 'callid');
181205
expect(result).toEqual({
182206
msg: '',
183207
groupable: false,
@@ -189,9 +213,10 @@ describe('getHistoryMessagePayload', () => {
189213
{
190214
background: 'default',
191215
elements: [
192-
{ type: 'icon', icon: 'phone-issue', variant: 'danger' },
216+
{ type: 'icon', icon: 'phone-issue', variant: 'danger', framed: true },
193217
{ type: 'mrkdwn', i18n: { key: 'Call_failed_bold' }, text: 'Call failed' },
194218
],
219+
action: actionObj,
195220
},
196221
],
197222
},
@@ -200,7 +225,7 @@ describe('getHistoryMessagePayload', () => {
200225
});
201226

202227
it('should return correct payload for "error" state', () => {
203-
const result = getHistoryMessagePayload('error', undefined);
228+
const result = getHistoryMessagePayload('error', undefined, 'callid');
204229
expect(result).toEqual({
205230
msg: '',
206231
groupable: false,
@@ -212,9 +237,10 @@ describe('getHistoryMessagePayload', () => {
212237
{
213238
background: 'default',
214239
elements: [
215-
{ type: 'icon', icon: 'phone-issue', variant: 'danger' },
240+
{ type: 'icon', icon: 'phone-issue', variant: 'danger', framed: true },
216241
{ type: 'mrkdwn', i18n: { key: 'Call_failed_bold' }, text: 'Call failed' },
217242
],
243+
action: actionObj,
218244
},
219245
],
220246
},
@@ -223,7 +249,7 @@ describe('getHistoryMessagePayload', () => {
223249
});
224250

225251
it('should return correct payload for "transferred" state', () => {
226-
const result = getHistoryMessagePayload('transferred', undefined);
252+
const result = getHistoryMessagePayload('transferred', undefined, 'callid');
227253
expect(result).toEqual({
228254
msg: '',
229255
groupable: false,
@@ -235,9 +261,10 @@ describe('getHistoryMessagePayload', () => {
235261
{
236262
background: 'default',
237263
elements: [
238-
{ type: 'icon', icon: 'arrow-forward', variant: 'secondary' },
264+
{ type: 'icon', icon: 'arrow-forward', variant: 'secondary', framed: true },
239265
{ type: 'mrkdwn', i18n: { key: 'Call_transferred_bold' }, text: 'Call transferred' },
240266
],
267+
action: actionObj,
241268
},
242269
],
243270
},
@@ -246,7 +273,7 @@ describe('getHistoryMessagePayload', () => {
246273
});
247274

248275
it('should include duration row when duration is provided', () => {
249-
const result = getHistoryMessagePayload('ended', 3665);
276+
const result = getHistoryMessagePayload('ended', 3665, 'callid');
250277

251278
expect(result.blocks[0].rows).toHaveLength(2);
252279
expect(result.blocks[0].rows[1]).toEqual({
@@ -256,7 +283,7 @@ describe('getHistoryMessagePayload', () => {
256283
});
257284

258285
it('should not include duration row when duration is undefined', () => {
259-
const result = getHistoryMessagePayload('ended', undefined);
286+
const result = getHistoryMessagePayload('ended', undefined, 'callid');
260287
expect(result.blocks[0].rows).toHaveLength(1);
261288
});
262289

@@ -265,14 +292,16 @@ describe('getHistoryMessagePayload', () => {
265292
const duration = 125;
266293

267294
states.forEach((state) => {
268-
const result = getHistoryMessagePayload(state, duration);
295+
const result = getHistoryMessagePayload(state, duration, 'callid');
269296
expect(result.msg).toBe('');
270297
expect(result.groupable).toBe(false);
271298
expect(result.blocks).toHaveLength(1);
272299
expect(result.blocks[0].type).toBe('info_card');
273300
expect(result.blocks[0].rows).toHaveLength(2);
274301
expect(result.blocks[0].rows[1].background).toBe('secondary');
275302
expect(result.blocks[0].rows[1].elements[0].type).toBe('mrkdwn');
303+
expect(result.blocks[0].rows[0].action).toEqual(actionObj);
304+
expect(result.blocks[0].rows[1].action).toBeUndefined();
276305
});
277306
});
278307
});

packages/ui-voip/src/ui-kit/getHistoryMessagePayload.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { CallHistoryItemState, IMessage } from '@rocket.chat/core-typings';
2-
import type { IconElement, InfoCardBlock, TextObject } from '@rocket.chat/ui-kit';
2+
import type { IconButtonElement, FrameableIconElement, InfoCardBlock, TextObject } from '@rocket.chat/ui-kit';
33
import { intervalToDuration, secondsToMilliseconds } from 'date-fns';
44

55
const APP_ID = 'media-call-core';
@@ -18,17 +18,17 @@ export const callStateToTranslationKey = (callState: CallHistoryItemState): Text
1818
}
1919
};
2020

21-
export const callStateToIcon = (callState: CallHistoryItemState): IconElement => {
21+
export const callStateToIcon = (callState: CallHistoryItemState): FrameableIconElement => {
2222
switch (callState) {
2323
case 'ended':
24-
return { type: 'icon', icon: 'phone-off', variant: 'secondary' };
24+
return { type: 'icon', icon: 'phone-off', variant: 'secondary', framed: true };
2525
case 'not-answered':
26-
return { type: 'icon', icon: 'clock', variant: 'danger' };
26+
return { type: 'icon', icon: 'clock', variant: 'danger', framed: true };
2727
case 'failed':
2828
case 'error':
29-
return { type: 'icon', icon: 'phone-issue', variant: 'danger' };
29+
return { type: 'icon', icon: 'phone-issue', variant: 'danger', framed: true };
3030
case 'transferred':
31-
return { type: 'icon', icon: 'arrow-forward', variant: 'secondary' };
31+
return { type: 'icon', icon: 'arrow-forward', variant: 'secondary', framed: true };
3232
}
3333
};
3434

@@ -54,9 +54,20 @@ export const getFormattedCallDuration = (callDuration: number | undefined): Text
5454
} as const;
5555
};
5656

57+
export const getHistoryAction = (callId: string): IconButtonElement => {
58+
return {
59+
type: 'icon_button',
60+
icon: { type: 'icon', icon: 'info', variant: 'default' },
61+
actionId: 'open-history',
62+
appId: APP_ID,
63+
blockId: callId,
64+
};
65+
};
66+
5767
export const getHistoryMessagePayload = (
5868
callState: CallHistoryItemState,
5969
callDuration: number | undefined,
70+
callId?: string,
6071
): Pick<IMessage, 'msg' | 'groupable'> & { blocks: [InfoCardBlock] } => {
6172
const callStateTranslationKey = callStateToTranslationKey(callState);
6273
const icon = callStateToIcon(callState);
@@ -73,6 +84,7 @@ export const getHistoryMessagePayload = (
7384
{
7485
background: 'default',
7586
elements: [icon, callStateTranslationKey],
87+
...(callId && { action: getHistoryAction(callId) }),
7688
},
7789
...(callDurationFormatted
7890
? [

0 commit comments

Comments
 (0)