Skip to content

Commit

Permalink
fix: reject was not called on timeout, decline and cancel scenarios (#…
Browse files Browse the repository at this point in the history
…1576)

## Background

Currently, we don't call reject unless `reject: true` is passed on
leave(). This was a recent change, so it caused a bug where reject was
not called on timeout, decline, and cancel scenarios.

There are four predefined reasons for rejecting the call: 

- `busy` - when the callee is busy and cannot accept the call.
- `decline` - when the callee intentionally declines the call.
- `cancel` - when the caller cancels the call.
- `timeout` - when the **caller** or **callee** rejects the call after
`auto_cancel_timeout_ms` or `incoming_call_timeout_ms` accordingly

## What has been done

- Reject is now called on timeout, decline and cancel scenarios. We dont
handle `busy` yet. Will be part of Android telecom/callkit alignment I
believe.
- Added reason to reject API call
- `incoming_call_timeout_ms` support has been added
  • Loading branch information
santhoshvai authored Nov 14, 2024
1 parent 1766c3e commit 8be76a4
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 23 deletions.
30 changes: 14 additions & 16 deletions packages/client/src/Call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,20 +516,15 @@ export class Call {
await waitUntilCallJoined();
}

if (reject && this.ringing) {
// I'm the one who started the call, so I should cancel it.
const hasOtherParticipants = this.state.remoteParticipants.length > 0;
if (
this.isCreatedByMe &&
!hasOtherParticipants &&
callingState === CallingState.RINGING
) {
// Signals other users that I have cancelled my call to them
// before they accepted it.
await this.reject();
} else if (callingState === CallingState.RINGING) {
// Signals other users that I have rejected the incoming call.
await this.reject();
if (callingState === CallingState.RINGING) {
if (reject) {
await this.reject(reason);
} else {
const hasOtherParticipants = this.state.remoteParticipants.length > 0;
if (this.isCreatedByMe && !hasOtherParticipants) {
// I'm the one who started the call, so I should cancel it when there are no other participants.
await this.reject('cancel');
}
}
}

Expand Down Expand Up @@ -1960,13 +1955,16 @@ export class Call {
// ignore if the call is not ringing
if (this.state.callingState !== CallingState.RINGING) return;

const timeoutInMs = settings.ring.auto_cancel_timeout_ms;
const timeoutInMs = this.isCreatedByMe
? settings.ring.auto_cancel_timeout_ms
: settings.ring.incoming_call_timeout_ms;

// 0 means no auto-drop
if (timeoutInMs <= 0) return;

clearTimeout(this.dropTimeout);
this.dropTimeout = setTimeout(() => {
this.leave({ reason: 'ring: timeout' }).catch((err) => {
this.leave({ reject: true, reason: 'timeout' }).catch((err) => {
this.logger('error', 'Failed to drop call', err);
});
}, timeoutInMs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ export const IncomingCallControls = ({
} = useTheme();
return (
<View style={[styles.buttonGroup, incomingCall.buttonGroup]}>
<RejectCallButton onPressHandler={onRejectCallHandler} />
<RejectCallButton
onPressHandler={onRejectCallHandler}
rejectReason="decline"
/>
<ToggleVideoPreviewButton />
<AcceptCallButton onPressHandler={onAcceptCallHandler} />
</View>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { useTheme } from '../../../contexts';
import { HangUpCallButton } from './HangupCallButton';
import { ToggleAudioPreviewButton } from './ToggleAudioPreviewButton';
import { ToggleVideoPreviewButton } from './ToggleVideoPreviewButton';
import { RejectCallButton } from './RejectCallButton';

/**
* Props for the OutgoingCallControls Component.
Expand Down Expand Up @@ -32,9 +32,10 @@ export const OutgoingCallControls = ({
<ToggleAudioPreviewButton />
<ToggleVideoPreviewButton />
</View>
<HangUpCallButton
<RejectCallButton
onPressHandler={onHangupCallHandler}
size={buttonSizes.md}
rejectReason="cancel"
/>
</View>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,32 @@ type RejectCallButtonProps = {
* Note: If the `onPressHandler` is passed this handler will not be executed.
*/
onRejectCallHandler?: () => void;
/**
* Sets the height, width and border-radius (half the value) of the button.
*/
size?: React.ComponentProps<typeof CallControlsButton>['size'];
/**
* Optional: Reason for rejecting the call.
* Pass a predefined or a custom reason.
* There are four predefined reasons for rejecting the call:
- `busy` - when the callee is busy and cannot accept the call.
- `decline` - when the callee intentionally declines the call.
- `cancel` - when the caller cancels the call.
- `timeout` - when the **caller** or **callee** rejects the call after `auto_cancel_timeout_ms` or `incoming_call_timeout_ms` accordingly.
*/
rejectReason?: string;
};

/**
* Button to reject a call.
*
* Mostly calls call.leave({ reject: true }) internally.
* Calls call.leave({ reject: true, reason: `OPTIONAL-REASON` }) internally.
*/
export const RejectCallButton = ({
onPressHandler,
onRejectCallHandler,
size,
rejectReason,
}: RejectCallButtonProps) => {
const call = useCall();
const { useCallCallingState } = useCallStateHooks();
Expand All @@ -50,7 +66,7 @@ export const RejectCallButton = ({
if (callingState === CallingState.LEFT) {
return;
}
await call?.leave({ reject: true });
await call?.leave({ reject: true, reason: rejectReason });
if (onRejectCallHandler) {
onRejectCallHandler();
}
Expand All @@ -64,7 +80,7 @@ export const RejectCallButton = ({
<CallControlsButton
onPress={rejectCallHandler}
color={colors.error}
size={buttonSizes.lg}
size={size ?? buttonSizes.lg}
// TODO: check what to do about this random style prop
// svgContainerStyle={theme.icon.lg}
style={rejectCallButton}
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native-sdk/src/utils/push/internal/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const processCallFromPush = async (
}
await callFromPush.join();
} else if (action === 'decline') {
await callFromPush.leave({ reject: true });
await callFromPush.leave({ reject: true, reason: 'decline' });
}
} catch (e) {
const logger = getLogger(['processCallFromPush']);
Expand Down

0 comments on commit 8be76a4

Please sign in to comment.