diff --git a/app/mobile/src/session/Session.jsx b/app/mobile/src/session/Session.jsx index ae14bc9d..b939c3a1 100644 --- a/app/mobile/src/session/Session.jsx +++ b/app/mobile/src/session/Session.jsx @@ -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,59 +426,8 @@ export function Session() { visible={state.callStatus != null} supportedOrientations={['portrait', 'landscape']} > - - - { state.remoteStream && ( - - )} - { !state.remoteVideo && ( - - - - )} - { state.localStream && ( - - )} - - { state.localVideo && ( - - - - )} - { !state.localVideo && ( - - - - )} - { state.localAudio && ( - - - - )} - { !state.localAudio && ( - - - - )} - - - - - - - + + ); } diff --git a/app/mobile/src/session/Session.styled.js b/app/mobile/src/session/Session.styled.js index 5cd409ca..2f36f45e 100644 --- a/app/mobile/src/session/Session.styled.js +++ b/app/mobile/src/session/Session.styled.js @@ -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%', - }, }); diff --git a/app/mobile/src/session/call/Call.jsx b/app/mobile/src/session/call/Call.jsx new file mode 100644 index 00000000..23279cb5 --- /dev/null +++ b/app/mobile/src/session/call/Call.jsx @@ -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 ( + + + { state.remoteStream && ( + + )} + { !state.remoteVideo && ( + + + + )} + { state.localStream && ( + + )} + + { state.localVideo && ( + + + + )} + { !state.localVideo && ( + + + + )} + { state.localAudio && ( + + + + )} + { !state.localAudio && ( + + + + )} + + + + + + + ) +} diff --git a/app/mobile/src/session/call/Call.styled.jsx b/app/mobile/src/session/call/Call.styled.jsx new file mode 100644 index 00000000..6c13ed27 --- /dev/null +++ b/app/mobile/src/session/call/Call.styled.jsx @@ -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%', + }, +}); + diff --git a/app/mobile/src/session/call/useCall.hook.js b/app/mobile/src/session/call/useCall.hook.js new file mode 100644 index 00000000..b507d90c --- /dev/null +++ b/app/mobile/src/session/call/useCall.hook.js @@ -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 }; +} +