added ringing modal to mobile

This commit is contained in:
balzack 2023-03-28 22:43:18 -07:00
parent cd06333ccb
commit ee474b5f73
6 changed files with 129 additions and 5 deletions

View File

@ -571,7 +571,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
@ -643,7 +643,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;

View File

@ -1,6 +1,6 @@
import { checkResponse, fetchWithTimeout } from './fetchUtil';
export async function removeContactCall(server, token, calllId) {
export async function removeContactCall(server, token, callId) {
const call = await fetchWithTimeout(`https://${server}/talk/calls/${callId}?contact=${token}`, { method: 'DELETE' });
checkResponse(call);
}

View File

@ -71,7 +71,7 @@ export function useRingContext() {
updateState({ ringing: ringing.current });
}, EXPIRE);
},
ignore: (cardId, callId) => {
ignore: async (cardId, callId) => {
const key = `${cardId}:${callId}`
const call = ringing.current.get(key);
if (call) {

View File

@ -1,4 +1,4 @@
import { View, ScrollView, TouchableOpacity, StatusBar, Text, Image } 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';
@ -6,6 +6,7 @@ import { createDrawerNavigator } from '@react-navigation/drawer';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';
import Ionicons from 'react-native-vector-icons/AntDesign';
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { useSession } from './useSession.hook';
import { styles } from './Session.styled';
import Colors from 'constants/Colors';
@ -22,6 +23,7 @@ import { ConversationContext } from 'context/ConversationContext';
import { ProfileContext } from 'context/ProfileContext';
import { ProfileIcon } from './profileIcon/ProfileIcon';
import { CardsIcon } from './cardsIcon/CardsIcon';
import { Logo } from 'utils/Logo';
import splash from 'images/session.png';
const ConversationStack = createStackNavigator();
@ -159,6 +161,7 @@ function ContactStackScreen() {
export function Session() {
const [ringing, setRinging] = useState([]);
const { state, actions } = useSession();
const drawerParams = { drawerPosition: 'right', headerShown: false, swipeEnabled: false, drawerType: 'front' };
@ -310,6 +313,31 @@ export function Session() {
);
}
useEffect(() => {
let incoming = [];
for (let i = 0; i < state.ringing.length; i++) {
const { img, name, handle, callId, cardId, contactNode, contactToken, calleeToken } = state.ringing[i];
const label = name ? name : `${handle}@${contactNode}`;
const key = `${cardId}:${callId}`
incoming.push(
<View key={key} style={styles.ringEntry}>
<Logo src={img} width={40} height={40} radius={4} />
<Text style={styles.ringName} numberOfLines={1} ellipsizeMode={'tail'}>{ label }</Text>
<TouchableOpacity style={styles.ringIgnore} onPress={() => actions.ignore(cardId, callId)}>
<MatIcons name={'eye-off-outline'} size={20} color={Colors.text} />
</TouchableOpacity>
<TouchableOpacity style={styles.ringDecline} onPress={() => actions.decline(cardId, contactNode, contactToken, callId)}>
<MatIcons name={'phone-hangup'} size={20} color={Colors.alert} />
</TouchableOpacity>
<TouchableOpacity style={styles.ringAccept} onPress={() => actions.accept(cardId, callId, contactNode, contactToken, calleeToken)}>
<MatIcons name={'phone'} size={20} color={Colors.primary} />
</TouchableOpacity>
</View>
);
}
setRinging(incoming);
}, [state.ringing]);
return (
<NavigationContainer>
<View style={styles.body}>
@ -379,6 +407,18 @@ export function Session() {
</View>
)}
</View>
<Modal
animationType="fade"
transparent={true}
visible={ringing.length > 0}
supportedOrientations={['portrait', 'landscape']}
>
<View style={styles.ringBase}>
<View style={styles.ringFrame}>
{ ringing }
</View>
</View>
</Modal>
</NavigationContainer>
);
}

View File

@ -138,5 +138,53 @@ export const styles = StyleSheet.create({
fontSize: 18,
color: Colors.tetx,
},
ringBase: {
display: 'flex',
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(52, 52, 52, 0.8)'
},
ringFrame: {
backgroundColor: Colors.formBackground,
padding: 16,
width: '90%',
maxWidth: 400,
borderRadius: 4,
},
ringEntry: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
ringName: {
flexGrow: 1,
paddingLeft: 8,
paddingRight: 8,
},
ringIgnore: {
borderWidth: 1,
borderRadius: 20,
borderColor: Colors.text,
padding: 6,
marginRight: 4,
},
ringDecline: {
borderWidth: 1,
borderRadius: 20,
borderColor: Colors.alert,
padding: 6,
marginLeft: 8,
marginRight: 8,
},
ringAccept: {
borderWidth: 1,
borderRadius: 20,
borderColor: Colors.primary,
padding: 6,
marginLeft: 4,
},
});

View File

@ -3,10 +3,13 @@ import { useWindowDimensions } from 'react-native';
import { useNavigate } from 'react-router-dom';
import config from 'constants/Config';
import { StoreContext } from 'context/StoreContext';
import { CardContext } from 'context/CardContext';
import { RingContext } from 'context/RingContext';
export function useSession() {
const [state, setState] = useState({
ringing: [],
tabbled: null,
subWidth: '50%',
baseWidth: '50%',
@ -15,6 +18,8 @@ export function useSession() {
firstRun: null,
});
const ring = useContext(RingContext);
const card = useContext(CardContext);
const store = useContext(StoreContext);
const dimensions = useWindowDimensions();
const navigate = useNavigate();
@ -24,6 +29,27 @@ export function useSession() {
setState((s) => ({ ...s, ...value }));
}
useEffect(() => {
const ringing = [];
const expired = Date.now();
ring.state.ringing.forEach(call => {
if (call.expires > expired && !call.status) {
const { callId, cardId, calleeToken } = call;
const contact = card.state.cards.get(cardId);
if (contact) {
const { imageSet, name, handle, node, guid } = contact.card?.profile || {};
const { token } = contact.card?.detail || {};
const contactToken = `${guid}.${token}`;
const img = imageSet ? card.actions.getCardImageUrl(cardId) : null;
ringing.push({ cardId, img, name, handle, contactNode: node, callId, contactToken, calleeToken });
}
}
});
const { callStatus, localStream, localVideo, localAudio, remoteStream, remoteVideo, remoteAudio } = ring.state;
updateState({ ringing, callStatus, localStream, localVideo, localAudio, remoteStream, remoteVideo, remoteAudio });
}, [ring.state]);
useEffect(() => {
checkFirstRun();
}, []);
@ -55,6 +81,16 @@ export function useSession() {
updateState({ firstRun: false });
store.actions.setFirstRun();
},
ignore: async (cardId, callId) => {
await ring.actions.ignore(cardId, callId);
},
decline: async (cardId, contactNode, contactToken, callId) => {
await ring.actions.decline(cardId, contactNode, contactToken, callId);
},
accept: async (cardId, callId, contactNode, contactToken, calleeToken) => {
await ring.actions.accept(cardId, callId, contactNode, contactToken, calleeToken);
},
};
return { state, actions };