using keep awake while call active

This commit is contained in:
balzack 2023-03-30 22:43:48 -07:00
parent 53ce6417bb
commit 9625ad64e3
5 changed files with 204 additions and 135 deletions

View File

@ -1,4 +1,4 @@
import { useWindowDimensions, View, ScrollView, TouchableOpacity, StatusBar, Text, Image, Modal } from 'react-native';
import { View, ScrollView, TouchableOpacity, StatusBar, Text, Image, Modal } from 'react-native';
import { useState, useEffect, useContext } from 'react';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
@ -24,8 +24,8 @@ import { ProfileContext } from 'context/ProfileContext';
import { ProfileIcon } from './profileIcon/ProfileIcon';
import { CardsIcon } from './cardsIcon/CardsIcon';
import { Logo } from 'utils/Logo';
import { Call } from './call/Call';
import splash from 'images/session.png';
import { RTCView } from 'react-native-webrtc';
const ConversationStack = createStackNavigator();
const ProfileStack = createStackNavigator();
@ -164,34 +164,9 @@ export function Session() {
const [ringing, setRinging] = useState([]);
const { state, actions } = useSession();
const {height, width} = useWindowDimensions();
const [callWidth, setCallWidth] = useState(0);
const [callHeight, setCallHeight] = useState(0);
const drawerParams = { drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front' };
useEffect(() => {
console.log(width, height);
if (width > height) {
setCallWidth((height * 9)/10);
setCallHeight((height * 9)/10);
}
else {
setCallWidth((width * 9)/10);
setCallHeight((width * 9)/10);
}
}, [width, height]);
useEffect(() => {
console.log("**** REMOTE ****");
console.log(state.remoteStream);
}, [state.remoteStream]);
useEffect(() => {
console.log("**** LOCAL ****");
console.log(state.localStream, state.localVideo);
}, [state.localStream, state.localVideo]);
const HomeScreen = ({ navParams }) => {
const conversation = useContext(ConversationContext);
@ -451,58 +426,7 @@ export function Session() {
visible={state.callStatus != null}
supportedOrientations={['portrait', 'landscape']}
>
<View style={styles.callBase}>
<View style={{ ...styles.callFrame, width: callWidth, height: callHeight }}>
{ state.remoteStream && (
<RTCView
style={styles.callRemote}
mirror={true}
objectFit={'contain'}
streamURL={state.remoteStream.toURL()}
zOrder={1}
/>
)}
{ !state.remoteVideo && (
<View style={styles.callLogo}>
<Logo src={state.callLogo} width={callWidth} height={callHeight} radius={4} />
</View>
)}
{ state.localStream && (
<RTCView
style={styles.callLocal}
mirror={true}
objectFit={'contain'}
streamURL={state.localStream.toURL()}
zOrder={2}
/>
)}
<View style={styles.callOptions}>
{ state.localVideo && (
<TouchableOpacity style={styles.callOption} onPress={actions.disableVideo}>
<MatIcons name={'video-outline'} size={20} color={Colors.white} />
</TouchableOpacity>
)}
{ !state.localVideo && (
<TouchableOpacity style={styles.callOption} onPress={actions.enableVideo}>
<MatIcons name={'video-off-outline'} size={20} color={Colors.white} />
</TouchableOpacity>
)}
{ state.localAudio && (
<TouchableOpacity style={styles.callOption} onPress={actions.disableAudio}>
<MatIcons name={'microphone'} size={20} color={Colors.white} />
</TouchableOpacity>
)}
{ !state.localAudio && (
<TouchableOpacity style={styles.callOption} onPress={actions.enableAudio}>
<MatIcons name={'microphone-off'} size={20} color={Colors.white} />
</TouchableOpacity>
)}
</View>
<TouchableOpacity style={styles.callEnd} onPress={actions.end}>
<MatIcons name={'phone-hangup'} size={20} color={Colors.white} />
</TouchableOpacity>
</View>
</View>
<Call />
</Modal>
</NavigationContainer>
);

View File

@ -186,60 +186,5 @@ export const styles = StyleSheet.create({
padding: 6,
marginLeft: 4,
},
callBase: {
display: 'flex',
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(52, 52, 52, 0.8)'
},
callFrame: {
backgroundColor: Colors.formBackground,
padding: 8,
borderRadius: 4,
display: 'flex',
alignItems: 'center',
},
callEnd: {
position: 'absolute',
bottom: 16,
borderRadius: 24,
borderColor: Colors.white,
borderWidth: 1,
padding: 8,
backgroundColor: Colors.alert,
},
callLogo: {
position: 'absolute',
top: 0,
bottom: 0,
},
callOptions: {
display: 'flex',
flexDirection: 'row',
position: 'absolute',
top: 16,
},
callOption: {
borderRadius: 24,
borderColor: Colors.white,
borderWidth: 1,
padding: 8,
backgroundColor: Colors.primary,
marginLeft: 16,
marginRight: 16,
},
callRemote: {
width: '100%',
height: '100%',
},
callLocal: {
position: 'absolute',
bottom: 16,
left: 16,
height: '33%',
width: '33%',
},
});

View File

@ -0,0 +1,84 @@
import { useWindowDimensions, View, TouchableOpacity } from 'react-native';
import { useState, useEffect } from 'react';
import { Logo } from 'utils/Logo';
import Colors from 'constants/Colors';
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { useKeepAwake } from '@sayem314/react-native-keep-awake';
import { RTCView } from 'react-native-webrtc';
import { useCall } from './useCall.hook';
import { styles } from './Call.styled';
export function Call() {
const {height, width} = useWindowDimensions();
const [callWidth, setCallWidth] = useState(0);
const [callHeight, setCallHeight] = useState(0);
const { state, actions } = useCall();
useEffect(() => {
if (width > height) {
setCallWidth((height * 9)/10);
setCallHeight((height * 9)/10);
}
else {
setCallWidth((width * 9)/10);
setCallHeight((width * 9)/10);
}
}, [width, height]);
useKeepAwake();
return (
<View style={styles.callBase}>
<View style={{ ...styles.callFrame, width: callWidth, height: callHeight }}>
{ state.remoteStream && (
<RTCView
style={styles.callRemote}
mirror={true}
objectFit={'contain'}
streamURL={state.remoteStream.toURL()}
zOrder={1}
/>
)}
{ !state.remoteVideo && (
<View style={styles.callLogo}>
<Logo src={state.callLogo} width={callWidth} height={callHeight} radius={4} />
</View>
)}
{ state.localStream && (
<RTCView
style={styles.callLocal}
mirror={true}
objectFit={'contain'}
streamURL={state.localStream.toURL()}
zOrder={2}
/>
)}
<View style={styles.callOptions}>
{ state.localVideo && (
<TouchableOpacity style={styles.callOption} onPress={actions.disableVideo}>
<MatIcons name={'video-outline'} size={20} color={Colors.white} />
</TouchableOpacity>
)}
{ !state.localVideo && (
<TouchableOpacity style={styles.callOption} onPress={actions.enableVideo}>
<MatIcons name={'video-off-outline'} size={20} color={Colors.white} />
</TouchableOpacity>
)}
{ state.localAudio && (
<TouchableOpacity style={styles.callOption} onPress={actions.disableAudio}>
<MatIcons name={'microphone'} size={20} color={Colors.white} />
</TouchableOpacity>
)}
{ !state.localAudio && (
<TouchableOpacity style={styles.callOption} onPress={actions.enableAudio}>
<MatIcons name={'microphone-off'} size={20} color={Colors.white} />
</TouchableOpacity>
)}
</View>
<TouchableOpacity style={styles.callEnd} onPress={actions.end}>
<MatIcons name={'phone-hangup'} size={20} color={Colors.white} />
</TouchableOpacity>
</View>
</View>
)
}

View File

@ -0,0 +1,61 @@
import { StyleSheet } from 'react-native';
import { Colors } from 'constants/Colors';
export const styles = StyleSheet.create({
callBase: {
display: 'flex',
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(52, 52, 52, 0.8)'
},
callFrame: {
backgroundColor: Colors.formBackground,
padding: 8,
borderRadius: 4,
display: 'flex',
alignItems: 'center',
},
callEnd: {
position: 'absolute',
bottom: 16,
borderRadius: 24,
borderColor: Colors.white,
borderWidth: 1,
padding: 8,
backgroundColor: Colors.alert,
},
callLogo: {
position: 'absolute',
top: 0,
bottom: 0,
},
callOptions: {
display: 'flex',
flexDirection: 'row',
position: 'absolute',
top: 16,
},
callOption: {
borderRadius: 24,
borderColor: Colors.white,
borderWidth: 1,
padding: 8,
backgroundColor: Colors.primary,
marginLeft: 16,
marginRight: 16,
},
callRemote: {
width: '100%',
height: '100%',
},
callLocal: {
position: 'absolute',
bottom: 16,
left: 16,
height: '33%',
width: '33%',
},
});

View File

@ -0,0 +1,55 @@
import { useRef, useState, useEffect, useContext } from 'react';
import { CardContext } from 'context/CardContext';
import { RingContext } from 'context/RingContext';
export function useCall() {
const [state, setState] = useState({
callLogo: null,
localStream: null,
localVideo: false,
localAudio: false,
remoteStream: null,
remoteVideo: false,
remoteAudio: false,
});
const ring = useContext(RingContext);
const card = useContext(CardContext);
useEffect(() => {
let callLogo = null;
const contact = card.state.cards.get(ring.state.cardId);
if (contact) {
const { imageSet } = contact.card?.profile || {};
callLogo = imageSet ? card.actions.getCardImageUrl(ring.state.cardId) : null;
}
const { localStream, localVideo, localAudio, remoteStream, remoteVideo, remoteAudio } = ring.state;
updateState({ callLogo, localStream, localVideo, localAudio, remoteStream, remoteVideo, remoteAudio });
}, [ring.state]);
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
const actions = {
end: async () => {
await ring.actions.end();
},
enableVideo: async () => {
await ring.actions.enableVideo();
},
disableVideo: async () => {
await ring.actions.disableVideo();
},
enableAudio: async () => {
await ring.actions.enableAudio();
},
disableAudio: async () => {
await ring.actions.disableAudio();
},
};
return { state, actions };
}