Skip to content

Commit c4eccd8

Browse files
Merge pull request #24 from linhvovan29546/dev/custom-component-js
allow customization of incoming call UI
2 parents af866a9 + 7c31e4e commit c4eccd8

File tree

8 files changed

+124
-8
lines changed

8 files changed

+124
-8
lines changed

README.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ import RNNotificationCall from "react-native-full-screen-notification-incoming-c
128128
answerText: "Answer",
129129
declineText: "Decline",
130130
notificationColor:"colorAccent",
131-
notificationSound: 'skype_ring'//raw
131+
notificationSound: 'skype_ring',//raw
132+
mainComponent:'MyReactNativeApp'//AppRegistry.registerComponent('MyReactNativeApp', () => CustomIncomingCall);
132133
}
133134
)
134135
```
@@ -148,6 +149,8 @@ import RNNotificationCall from "react-native-full-screen-notification-incoming-c
148149
- `declineText`: string (required) decline button label
149150
- `notificationColor`: string (optional) color of notification
150151
- `notificationSound`: raw file (optional) sound of notification
152+
- `mainComponent`:string appKey when custom incomingcall screen
153+
- `payload`:any(optional) pass whatever data you want to get when custom incomingcall screen
151154

152155
#### hide notification
153156

@@ -182,6 +185,14 @@ import RNNotificationCall from "react-native-full-screen-notification-incoming-c
182185
```js
183186
RNNotificationCall.backToApp()
184187
```
188+
#### decline call
189+
```js
190+
RNNotificationCall.declineCall(uuid)
191+
```
192+
#### answer call
193+
```js
194+
RNNotificationCall.answerCall(uuid)
195+
```
185196

186197
#### Known issue
187198
- Custom Android notification sound :

android/src/main/java/com/reactnativefullscreennotificationincomingcall/FullScreenNotificationIncomingCallModule.java

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public void displayNotification(String uuid, @Nullable String avatar,@Nullable i
5656
intent.putExtra("declineText",foregroundOptions.getString("declineText"));
5757
intent.putExtra("notificationColor",foregroundOptions.getString("notificationColor"));
5858
intent.putExtra("notificationSound",foregroundOptions.getString("notificationSound"));
59+
intent.putExtra("mainComponent",foregroundOptions.getString("mainComponent"));
60+
intent.putExtra("payload",foregroundOptions.getString("payload"));
5961
intent.setAction(Constants.ACTION_SHOW_INCOMING_CALL);
6062
getReactApplicationContext().startService(intent);
6163
}

android/src/main/java/com/reactnativefullscreennotificationincomingcall/IncomingCallActivity.java

+29-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.reactnativefullscreennotificationincomingcall;
22

3-
import android.app.Activity;
3+
44
import android.app.KeyguardManager;
55
import android.content.Context;
66
import android.content.Intent;
@@ -14,12 +14,16 @@
1414
import android.widget.TextView;
1515
import com.airbnb.lottie.LottieAnimationView;
1616
import androidx.appcompat.app.AppCompatActivity;
17+
import androidx.fragment.app.Fragment;
1718

19+
import com.facebook.react.ReactFragment;
1820
import com.facebook.react.bridge.Arguments;
1921
import com.facebook.react.bridge.WritableMap;
22+
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
2023
import com.squareup.picasso.Picasso;
2124

22-
public class IncomingCallActivity extends AppCompatActivity {
25+
public class IncomingCallActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
26+
2327
private static final String TAG = "MessagingService";
2428
private static final String TAG_KEYGUARD = "Incoming:unLock";
2529
private TextView tvName;
@@ -72,21 +76,38 @@ protected void onCreate(Bundle savedInstanceState) {
7276
keyguardLock.disableKeyguard();
7377
}
7478
}
75-
setContentView(R.layout.activity_call_incoming);
7679
getWindow().addFlags(
7780
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
7881
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
7982
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
8083
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
8184
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
85+
Bundle bundle = getIntent().getExtras();
86+
87+
if (bundle.containsKey("mainComponent")) {
88+
setContentView(R.layout.custom_ingcoming_call_rn);
89+
Fragment reactNativeFragment = new ReactFragment.Builder()
90+
.setComponentName(bundle.getString("mainComponent"))
91+
.setLaunchOptions(bundle)
92+
.build();
93+
getSupportFragmentManager()
94+
.beginTransaction()
95+
.add(R.id.reactNativeFragment, reactNativeFragment)
96+
.commit();
97+
if (bundle.containsKey("uuid")) {
98+
uuid = bundle.getString("uuid");
99+
}
100+
return;
101+
}else{
102+
setContentView(R.layout.activity_call_incoming);
103+
}
82104
tvName = findViewById(R.id.tvName);
83105
tvInfo = findViewById(R.id.tvInfo);
84106
ivAvatar = findViewById(R.id.ivAvatar);
85107
tvDecline=findViewById(R.id.tvDecline);
86108
tvAccept=findViewById(R.id.tvAccept);
87109
lnDeclineCall = findViewById(R.id.lnDeclineCall);
88110
lnAcceptCall = findViewById(R.id.lnAcceptCall);
89-
Bundle bundle = getIntent().getExtras();
90111
if (bundle != null) {
91112
if (bundle.containsKey("uuid")) {
92113
uuid = bundle.getString("uuid");
@@ -183,4 +204,8 @@ private void dismissDialing(String action) {
183204
}
184205
}
185206

207+
@Override
208+
public void invokeDefaultOnBackPressed() {
209+
super.onBackPressed();
210+
}
186211
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:id="@+id/reactNativeFragment"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent">
6+
7+
</FrameLayout>

example/index.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { AppRegistry } from 'react-native';
22
import App from './src/App';
33
import { name as appName } from './app.json';
4+
import CustomIncomingCall from './src/CustomIncomingCall';
45

6+
AppRegistry.registerComponent('MyReactNativeApp', () => CustomIncomingCall);
57
AppRegistry.registerComponent(appName, () => App);

example/src/App.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ export default function App() {
4545
answerText: "Answer",
4646
declineText: "Decline",
4747
notificationColor: 'colorAccent',//path color in android
48-
notificationSound: 'skype_ring'//raw
48+
notificationSound: 'skype_ring',//raw
49+
mainComponent: "MyReactNativeApp"
4950
}
5051
)
5152
// Cancel the timeout if necessary
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as React from 'react';
2+
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3+
import type { customIncomingActivityProps } from 'react-native-full-screen-notification-incoming-call';
4+
import RNNotificationCall from '../../../src/index'
5+
export default function CustomIncomingCall(props: customIncomingActivityProps) {
6+
console.log('props===', props)
7+
return (
8+
<View style={styles.container}>
9+
<TouchableOpacity style={styles.box} onPress={() => {
10+
RNNotificationCall.declineCall(props.uuid)
11+
}}>
12+
<Text>Decline</Text>
13+
</TouchableOpacity>
14+
<TouchableOpacity style={styles.box}
15+
onPress={() => {
16+
RNNotificationCall.answerCall(props.uuid)
17+
}}
18+
>
19+
<Text>Answer</Text>
20+
</TouchableOpacity>
21+
</View>
22+
);
23+
}
24+
25+
const styles = StyleSheet.create({
26+
container: {
27+
flex: 1,
28+
alignItems: 'center',
29+
justifyContent: 'center',
30+
backgroundColor: 'white'
31+
},
32+
box: {
33+
width: 60,
34+
height: 60,
35+
marginVertical: 20,
36+
},
37+
});

src/index.tsx

+33-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
1+
import { DeviceEventEmitter, NativeEventEmitter, NativeModules, Platform } from 'react-native';
22
const isAndroid = Platform.OS === 'android';
33
const RNNotificationIncomingCall = NativeModules.FullScreenNotificationIncomingCall;
44
let eventEmitter: any
@@ -9,6 +9,16 @@ enum RNNotificationEvent {
99
RNNotificationAnswerAction = 'RNNotificationAnswerAction',
1010
RNNotificationEndCallAction = 'RNNotificationEndCallAction'
1111
}
12+
enum CallAction {
13+
ACTION_END_CALL = "ACTION_END_CALL",
14+
ACTION_REJECTED_CALL = "ACTION_REJECTED_CALL",
15+
ACTION_HIDE_CALL = "ACTION_HIDE_CALL",
16+
ACTION_SHOW_INCOMING_CALL = "ACTION_SHOW_INCOMING_CALL",
17+
HIDE_NOTIFICATION_INCOMING_CALL = "HIDE_NOTIFICATION_INCOMING_CALL",
18+
ACTION_PRESS_ANSWER_CALL = "ACTION_PRESS_ANSWER_CALL",
19+
ACTION_PRESS_DECLINE_CALL = "ACTION_PRESS_DECLINE_CALL",
20+
ACTION_START_ACTIVITY = "ACTION_START_ACTIVITY",
21+
}
1222

1323
interface foregroundOptionsModel {
1424
channelId: string;
@@ -19,7 +29,15 @@ interface foregroundOptionsModel {
1929
answerText: string;
2030
declineText: string;
2131
notificationColor?: string;
22-
notificationSound?: string//raw
32+
notificationSound?: string;//raw
33+
mainComponent?: string;
34+
payload?: any//more info
35+
}
36+
export interface customIncomingActivityProps {
37+
avatar?: string;
38+
info?: string;
39+
uuid: string;
40+
payload?: any
2341
}
2442
class RNNotificationCall {
2543
private _notificationEventHandlers;
@@ -77,6 +95,19 @@ class RNNotificationCall {
7795
listener.remove();
7896
this._notificationEventHandlers.delete(type);
7997
};
98+
declineCall = (uuid: string) => {
99+
this.hideNotification()
100+
const payload = {
101+
callUUID: uuid,
102+
endAction: CallAction.ACTION_REJECTED_CALL
103+
}
104+
DeviceEventEmitter.emit(RNNotificationEvent.RNNotificationEndCallAction, payload)
105+
}
106+
answerCall = (uuid: string) => {
107+
this.hideNotification()
108+
const payload = { callUUID: uuid }
109+
DeviceEventEmitter.emit(RNNotificationEvent.RNNotificationAnswerAction, payload)
110+
}
80111
}
81112

82113
export default new RNNotificationCall();

0 commit comments

Comments
 (0)