Skip to content

Commit f95cae6

Browse files
authored
Merge pull request #77 from react-native-webrtc/add_example
Add example (follows #64)
2 parents 724104d + bbf563a commit f95cae6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+8075
-11
lines changed

LICENSE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2016-2018 The CallKeep Authors (see the AUTHORS file)
1+
Copyright (c) 2016-2019 The CallKeep Authors (see the AUTHORS file)
22

33
Permission to use, copy, modify, and/or distribute this software for any
44
purpose with or without fee is hereby granted, provided that the above

README.md

+1-5
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ RNCallKeep.addEventListener('didPerformDTMFAction', ({ digits, callUUID }) => {
461461

462462
## Example
463463

464-
A full example is available in the [wazo-react-native-demo](https://github.com/wazo-pbx/wazo-react-native-demo) repository.
464+
A full example is available in the [example](https://github.com/react-native-webrtc/react-native-callkeep/tree/master/example) folder.
465465

466466
```javascript
467467
import React from 'react';
@@ -584,10 +584,6 @@ class RNCallKeepExample extends React.Component {
584584
}
585585
```
586586

587-
## Notes
588-
589-
- Call setup once to initiate callkeep.
590-
591587
## Debug
592588

593589
### Android

android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016-2018 The CallKeep Authors (see the AUTHORS file)
2+
* Copyright (c) 2016-2019 The CallKeep Authors (see the AUTHORS file)
33
* SPDX-License-Identifier: ISC, MIT
44
*
55
* Permission to use, copy, modify, and distribute this software for any

android/src/main/java/io/wazo/callkeep/RNCallKeepPackage.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016-2018 The CallKeep Authors (see the AUTHORS file)
2+
* Copyright (c) 2016-2019 The CallKeep Authors (see the AUTHORS file)
33
* SPDX-License-Identifier: ISC, MIT
44
*
55
* Permission to use, copy, modify, and distribute this software for any

android/src/main/java/io/wazo/callkeep/VoiceConference.java

+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
/*
2+
* Copyright (c) 2016-2019 The CallKeep Authors (see the AUTHORS file)
3+
* SPDX-License-Identifier: ISC, MIT
4+
*
5+
* Permission to use, copy, modify, and distribute this software for any
6+
* purpose with or without fee is hereby granted, provided that the above
7+
* copyright notice and this permission notice appear in all copies.
8+
*
9+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16+
*/
17+
118
package io.wazo.callkeep;
219

320
import android.telecom.Conference;

android/src/main/java/io/wazo/callkeep/VoiceConnection.java

+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
/*
2+
* Copyright (c) 2016-2019 The CallKeep Authors (see the AUTHORS file)
3+
* SPDX-License-Identifier: ISC, MIT
4+
*
5+
* Permission to use, copy, modify, and distribute this software for any
6+
* purpose with or without fee is hereby granted, provided that the above
7+
* copyright notice and this permission notice appear in all copies.
8+
*
9+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16+
*/
17+
118
package io.wazo.callkeep;
219

320
import android.annotation.TargetApi;

android/src/main/java/io/wazo/callkeep/VoiceConnectionService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016-2018 The CallKeep Authors (see the AUTHORS file)
2+
* Copyright (c) 2016-2019 The CallKeep Authors (see the AUTHORS file)
33
* SPDX-License-Identifier: ISC, MIT
44
*
55
* Permission to use, copy, modify, and distribute this software for any

example/.gitignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
node_modules/**/*
2+
.expo/*
3+
npm-debug.*
4+
*.jks
5+
*.p8
6+
*.p12
7+
*.key
8+
*.mobileprovision
9+
*.orig.*
10+
web-build/
11+
web-report/
12+
13+
ios/Pods/

example/.watchmanconfig

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

example/App.js

+248
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
import React, { useState, useEffect } from 'react';
2+
import { Platform, StyleSheet, Text, View, TouchableOpacity, ScrollView } from 'react-native';
3+
import uuid from 'uuid';
4+
import RNCallKeep from 'react-native-callkeep';
5+
import BackgroundTimer from 'react-native-background-timer';
6+
import DeviceInfo from 'react-native-device-info';
7+
8+
BackgroundTimer.start();
9+
10+
const hitSlop = { top: 10, left: 10, right: 10, bottom: 10};
11+
const styles = StyleSheet.create({
12+
container: {
13+
flex: 1,
14+
marginTop: 20,
15+
backgroundColor: '#fff',
16+
alignItems: 'center',
17+
justifyContent: 'center',
18+
},
19+
button: {
20+
marginTop: 20,
21+
marginBottom: 20,
22+
},
23+
callButtons: {
24+
flexDirection: 'row',
25+
justifyContent: 'space-between',
26+
paddingHorizontal: 30,
27+
width: '100%',
28+
},
29+
logContainer: {
30+
flex: 3,
31+
width: '100%',
32+
backgroundColor: '#D9D9D9',
33+
},
34+
log: {
35+
fontSize: 10,
36+
}
37+
});
38+
39+
RNCallKeep.setup({
40+
ios: {
41+
appName: 'CallKeepDemo',
42+
},
43+
android: {
44+
alertTitle: 'Permissions required',
45+
alertDescription: 'This application needs to access your phone accounts',
46+
cancelButton: 'Cancel',
47+
okButton: 'ok',
48+
},
49+
});
50+
51+
const getNewUuid = () => uuid.v4().toLowerCase();
52+
53+
const format = uuid => uuid.split('-')[0];
54+
55+
const getRandomNumber = () => String(Math.floor(Math.random() * 100000));
56+
57+
export default function App() {
58+
const [logText, setLog] = useState('');
59+
const [heldCalls, setHeldCalls] = useState({}); // callKeep uuid: held
60+
const [mutedCalls, setMutedCalls] = useState({}); // callKeep uuid: muted
61+
const [calls, setCalls] = useState({}); // callKeep uuid: number
62+
63+
const log = (text) => {
64+
console.info(text);
65+
setLog(logText + "\n" + text);
66+
};
67+
68+
const addCall = (callUUID, number) => {
69+
setHeldCalls({ ...heldCalls, [callUUID]: false });
70+
setCalls({ ...calls, [callUUID]: number });
71+
};
72+
73+
const removeCall = (callUUID) => {
74+
const { [callUUID]: _, ...updated } = calls;
75+
const { [callUUID]: __, ...updatedHeldCalls } = heldCalls;
76+
77+
setCalls(updated);
78+
setCalls(updatedHeldCalls);
79+
};
80+
81+
const setCallHeld = (callUUID, held) => {
82+
setHeldCalls({ ...heldCalls, [callUUID]: held });
83+
};
84+
85+
const setCallMuted = (callUUID, muted) => {
86+
setMutedCalls({ ...mutedCalls, [callUUID]: muted });
87+
};
88+
89+
const displayIncomingCall = (number) => {
90+
const callUUID = getNewUuid();
91+
addCall(callUUID, number);
92+
93+
log(`[displayIncomingCall] ${format(callUUID)}, number: ${number}`);
94+
95+
RNCallKeep.displayIncomingCall(callUUID, number, number, 'number', false);
96+
};
97+
98+
const displayIncomingCallNow = () => {
99+
displayIncomingCall(getRandomNumber());
100+
};
101+
102+
const displayIncomingCallDelayed = () => {
103+
BackgroundTimer.setTimeout(() => {
104+
displayIncomingCall(getRandomNumber());
105+
}, 3000);
106+
};
107+
108+
const answerCall = ({ callUUID }) => {
109+
const number = calls[callUUID];
110+
log(`[answerCall] ${format(callUUID)}, number: ${number}`);
111+
112+
RNCallKeep.startCall(callUUID, number, number);
113+
114+
BackgroundTimer.setTimeout(() => {
115+
log(`[setCurrentCallActive] ${format(callUUID)}, number: ${number}`);
116+
RNCallKeep.setCurrentCallActive(callUUID);
117+
}, 1000);
118+
};
119+
120+
const didPerformDTMFAction = ({ callUUID, digits }) => {
121+
const number = calls[callUUID];
122+
log(`[didPerformDTMFAction] ${format(callUUID)}, number: ${number} (${digits})`);
123+
};
124+
125+
const didReceiveStartCallAction = ({ handle }) => {
126+
if (!handle) {
127+
// @TODO: sometime we receive `didReceiveStartCallAction` with handle` undefined`
128+
return;
129+
}
130+
const callUUID = getNewUuid();
131+
addCall(callUUID, handle);
132+
133+
log(`[didReceiveStartCallAction] ${callUUID}, number: ${handle}`);
134+
135+
RNCallKeep.startCall(callUUID, handle, handle);
136+
137+
BackgroundTimer.setTimeout(() => {
138+
log(`[setCurrentCallActive] ${format(callUUID)}, number: ${handle}`);
139+
RNCallKeep.setCurrentCallActive(callUUID);
140+
}, 1000);
141+
};
142+
143+
const didPerformSetMutedCallAction = ({ muted, callUUID }) => {
144+
const number = calls[callUUID];
145+
log(`[didPerformSetMutedCallAction] ${format(callUUID)}, number: ${number} (${muted})`);
146+
147+
setCallMuted(callUUID, muted);
148+
};
149+
150+
const didToggleHoldCallAction = ({ hold, callUUID }) => {
151+
const number = calls[callUUID];
152+
log(`[didToggleHoldCallAction] ${format(callUUID)}, number: ${number} (${hold})`);
153+
154+
setCallHeld(callUUID, hold);
155+
};
156+
157+
const endCall = ({ callUUID }) => {
158+
const handle = calls[callUUID];
159+
log(`[endCall] ${format(callUUID)}, number: ${handle}`);
160+
161+
removeCall(callUUID);
162+
};
163+
164+
const hangup = (callUUID) => {
165+
RNCallKeep.endCall(callUUID);
166+
removeCall(callUUID);
167+
};
168+
169+
const setOnHold = (callUUID, held) => {
170+
const handle = calls[callUUID];
171+
RNCallKeep.setOnHold(callUUID, held);
172+
log(`[setOnHold: ${held}] ${format(callUUID)}, number: ${handle}`);
173+
174+
setCallHeld(callUUID, held);
175+
};
176+
177+
const setOnMute = (callUUID, muted) => {
178+
const handle = calls[callUUID];
179+
RNCallKeep.setMutedCall(callUUID, muted);
180+
log(`[setMutedCall: ${muted}] ${format(callUUID)}, number: ${handle}`);
181+
182+
setCallMuted(callUUID, muted);
183+
};
184+
185+
useEffect(() => {
186+
RNCallKeep.addEventListener('answerCall', answerCall);
187+
RNCallKeep.addEventListener('didPerformDTMFAction', didPerformDTMFAction);
188+
RNCallKeep.addEventListener('didReceiveStartCallAction', didReceiveStartCallAction);
189+
RNCallKeep.addEventListener('didPerformSetMutedCallAction', didPerformSetMutedCallAction);
190+
RNCallKeep.addEventListener('didToggleHoldCallAction', didToggleHoldCallAction);
191+
RNCallKeep.addEventListener('endCall', endCall);
192+
193+
return () => {
194+
RNCallKeep.removeEventListener('answerCall', answerCall);
195+
RNCallKeep.removeEventListener('didPerformDTMFAction', didPerformDTMFAction);
196+
RNCallKeep.removeEventListener('didReceiveStartCallAction', didReceiveStartCallAction);
197+
RNCallKeep.removeEventListener('didPerformSetMutedCallAction', didPerformSetMutedCallAction);
198+
RNCallKeep.removeEventListener('didToggleHoldCallAction', didToggleHoldCallAction);
199+
RNCallKeep.removeEventListener('endCall', endCall);
200+
}
201+
}, []);
202+
203+
if (Platform.OS === 'ios' && DeviceInfo.isEmulator()) {
204+
return <Text style={styles.container}>CallKeep doesn't work on iOS emulator</Text>;
205+
}
206+
207+
return (
208+
<View style={styles.container}>
209+
<TouchableOpacity onPress={displayIncomingCallNow} style={styles.button} hitSlop={hitSlop}>
210+
<Text>Display incoming call now</Text>
211+
</TouchableOpacity>
212+
213+
<TouchableOpacity onPress={displayIncomingCallDelayed} style={styles.button} hitSlop={hitSlop}>
214+
<Text>Display incoming call now in 3s</Text>
215+
</TouchableOpacity>
216+
217+
{Object.keys(calls).map(callUUID => (
218+
<View key={callUUID} style={styles.callButtons}>
219+
<TouchableOpacity
220+
onPress={() => setOnHold(callUUID, !heldCalls[callUUID])}
221+
style={styles.button}
222+
hitSlop={hitSlop}
223+
>
224+
<Text>{heldCalls[callUUID] ? 'Unhold' : 'Hold'} {calls[callUUID]}</Text>
225+
</TouchableOpacity>
226+
227+
<TouchableOpacity
228+
onPress={() => setOnMute(callUUID, !mutedCalls[callUUID])}
229+
style={styles.button}
230+
hitSlop={hitSlop}
231+
>
232+
<Text>{mutedCalls[callUUID] ? 'Unmute' : 'Mute'} {calls[callUUID]}</Text>
233+
</TouchableOpacity>
234+
235+
<TouchableOpacity onPress={() => hangup(callUUID)} style={styles.button} hitSlop={hitSlop}>
236+
<Text>Hangup {calls[callUUID]}</Text>
237+
</TouchableOpacity>
238+
</View>
239+
))}
240+
241+
<ScrollView style={styles.logContainer}>
242+
<Text style={styles.log}>
243+
{logText}
244+
</Text>
245+
</ScrollView>
246+
</View>
247+
);
248+
}

example/README.md

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# CallKeep example
2+
3+
4+
5+
## How to install it
6+
7+
```
8+
# Install dependancies
9+
yarn install
10+
11+
cd ios
12+
pod install
13+
```
14+
15+
## How to use it
16+
17+
```
18+
# Start metro bundler
19+
yarn start
20+
21+
# Start the application (in another term)
22+
yarn android # or yarn ios
23+
```
24+
25+
26+
## How this example was setted up
27+
28+
```sh
29+
expo init CallKeepDemo
30+
expo eject
31+
yarn add react-native-callkeep
32+
./node_modules/.bin/react-native link react-native-callkeep
33+
```

0 commit comments

Comments
 (0)