feat(voice): Attach call recordings + show call duration on the bubble (#14344)
When an inbound voice call ends, the conversation bubble now (1) renders an inline audio player as soon as Twilio finishes the recording and (2) shows the call duration alongside "Call ended" so the agent gets the at-a-glance summary without opening the recording. Fixes https://linear.app/chatwoot/issue/PLA-118/feat-recordings-on-calls-should-be-attached-on-the-conversation and https://linear.app/chatwoot/issue/PLA-119/duration-of-the-call-is-not-visible-on-the-chat-bubble ## How to test 1. Set up a Twilio voice inbox and trigger an inbound call. 2. Answer the call from an agent, talk for a few seconds, then hang up. 3. As soon as the call ends, the bubble should read **"Call ended — 0:NN"** (where NN is the call duration in seconds). 4. Wait a few seconds for Twilio to finish processing the recording (usually <30s after hangup). 5. The same bubble should now show an inline audio player below the duration. Press play; the recording should be audible. 6. Refresh the page — both the duration and the player should still be there. 7. End a second call on the same conversation — its bubble should get its own duration + player, independent of the first. --------- Co-authored-by: Muhsin <12408980+muhsin-k@users.noreply.github.com>
This commit is contained in:
@@ -94,6 +94,29 @@ export const shortTimestamp = (time, withAgo = false) => {
|
||||
return convertToShortTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats a duration in seconds into mm:ss or hh:mm:ss.
|
||||
* @param {number|string} durationInSeconds - Duration in seconds.
|
||||
* @returns {string} Formatted duration string. Empty string for invalid input.
|
||||
*/
|
||||
export const formatDuration = durationInSeconds => {
|
||||
if (durationInSeconds === null || durationInSeconds === undefined) return '';
|
||||
|
||||
const totalSeconds = Number(durationInSeconds);
|
||||
if (Number.isNaN(totalSeconds) || totalSeconds < 0) return '';
|
||||
|
||||
const hours = Math.floor(totalSeconds / 3600);
|
||||
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
|
||||
const mm = minutes.toString().padStart(2, '0');
|
||||
const ss = seconds.toString().padStart(2, '0');
|
||||
if (hours > 0) {
|
||||
return `${hours.toString().padStart(2, '0')}:${mm}:${ss}`;
|
||||
}
|
||||
return `${mm}:${ss}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates the difference in days between now and a given timestamp.
|
||||
* @param {Date} now - Current date/time.
|
||||
|
||||
Reference in New Issue
Block a user