preparing for mobile webrtc integration

This commit is contained in:
Roland Osborne 2023-03-28 15:57:19 -07:00
parent 7b4eed0c7a
commit 00f4769505
6 changed files with 152 additions and 37 deletions

View File

@ -8,6 +8,7 @@ import { AppContextProvider } from 'context/AppContext';
import { AccountContextProvider } from 'context/AccountContext'; import { AccountContextProvider } from 'context/AccountContext';
import { ProfileContextProvider } from 'context/ProfileContext'; import { ProfileContextProvider } from 'context/ProfileContext';
import { CardContextProvider } from 'context/CardContext'; import { CardContextProvider } from 'context/CardContext';
import { RingContextProvider } from 'context/RingContext'
import { ChannelContextProvider } from 'context/ChannelContext'; import { ChannelContextProvider } from 'context/ChannelContext';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { ConversationContextProvider } from 'context/ConversationContext'; import { ConversationContextProvider } from 'context/ConversationContext';
@ -25,31 +26,33 @@ export default function App() {
return ( return (
<StoreContextProvider> <StoreContextProvider>
<UploadContextProvider> <UploadContextProvider>
<CardContextProvider> <RingContextProvider>
<ChannelContextProvider> <CardContextProvider>
<AccountContextProvider> <ChannelContextProvider>
<ProfileContextProvider> <AccountContextProvider>
<ConversationContextProvider> <ProfileContextProvider>
<AppContextProvider> <ConversationContextProvider>
<SafeAreaProvider> <AppContextProvider>
<NativeRouter> <SafeAreaProvider>
<Routes> <NativeRouter>
<Route path="/" element={ <Root /> } /> <Routes>
<Route path="/admin" element={ <Access mode="admin" /> } /> <Route path="/" element={ <Root /> } />
<Route path="/dashboard" element={ <Dashboard /> } /> <Route path="/admin" element={ <Access mode="admin" /> } />
<Route path="/login" element={ <Access mode="login" /> } /> <Route path="/dashboard" element={ <Dashboard /> } />
<Route path="/reset" element={ <Access mode="reset" /> } /> <Route path="/login" element={ <Access mode="login" /> } />
<Route path="/create" element={ <Access mode="create" /> } /> <Route path="/reset" element={ <Access mode="reset" /> } />
<Route path="/session" element={ <Session /> } /> <Route path="/create" element={ <Access mode="create" /> } />
</Routes> <Route path="/session" element={ <Session /> } />
</NativeRouter> </Routes>
</SafeAreaProvider> </NativeRouter>
</AppContextProvider> </SafeAreaProvider>
</ConversationContextProvider> </AppContextProvider>
</ProfileContextProvider> </ConversationContextProvider>
</AccountContextProvider> </ProfileContextProvider>
</ChannelContextProvider> </AccountContextProvider>
</CardContextProvider> </ChannelContextProvider>
</CardContextProvider>
</RingContextProvider>
</UploadContextProvider> </UploadContextProvider>
</StoreContextProvider> </StoreContextProvider>
); );

View File

@ -13,7 +13,6 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
46D8108CBA031189090AFC14 /* Pods_Databag_DatabagTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1181227D40684F18A9414840 /* Pods_Databag_DatabagTests.framework */; }; 46D8108CBA031189090AFC14 /* Pods_Databag_DatabagTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1181227D40684F18A9414840 /* Pods_Databag_DatabagTests.framework */; };
7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B13A773299E21170048D0DD /* GoogleService-Info.plist */; }; 7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7B13A773299E21170048D0DD /* GoogleService-Info.plist */; };
7B6135A329B439B80094A6E7 /* login.png in Resources */ = {isa = PBXBuildFile; fileRef = 7B6135A229B439B80094A6E7 /* login.png */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
A0B1EC4533FCFC5940B5FD7F /* Pods_Databag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9462C028F47F083241BB7941 /* Pods_Databag.framework */; }; A0B1EC4533FCFC5940B5FD7F /* Pods_Databag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9462C028F47F083241BB7941 /* Pods_Databag.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -43,7 +42,6 @@
5709B34CF0A7D63546082F79 /* Pods-Databag.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag.release.xcconfig"; path = "Target Support Files/Pods-Databag/Pods-Databag.release.xcconfig"; sourceTree = "<group>"; }; 5709B34CF0A7D63546082F79 /* Pods-Databag.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag.release.xcconfig"; path = "Target Support Files/Pods-Databag/Pods-Databag.release.xcconfig"; sourceTree = "<group>"; };
5B7EB9410499542E8C5724F5 /* Pods-Databag-DatabagTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag-DatabagTests.debug.xcconfig"; path = "Target Support Files/Pods-Databag-DatabagTests/Pods-Databag-DatabagTests.debug.xcconfig"; sourceTree = "<group>"; }; 5B7EB9410499542E8C5724F5 /* Pods-Databag-DatabagTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag-DatabagTests.debug.xcconfig"; path = "Target Support Files/Pods-Databag-DatabagTests/Pods-Databag-DatabagTests.debug.xcconfig"; sourceTree = "<group>"; };
7B13A773299E21170048D0DD /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; }; 7B13A773299E21170048D0DD /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
7B6135A229B439B80094A6E7 /* login.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = login.png; sourceTree = "<group>"; };
7B6135A429B68A7B0094A6E7 /* Databag.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Databag.entitlements; path = Databag/Databag.entitlements; sourceTree = "<group>"; }; 7B6135A429B68A7B0094A6E7 /* Databag.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Databag.entitlements; path = Databag/Databag.entitlements; sourceTree = "<group>"; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = Databag/LaunchScreen.storyboard; sourceTree = "<group>"; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = Databag/LaunchScreen.storyboard; sourceTree = "<group>"; };
89C6BE57DB24E9ADA2F236DE /* Pods-Databag-DatabagTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag-DatabagTests.release.xcconfig"; path = "Target Support Files/Pods-Databag-DatabagTests/Pods-Databag-DatabagTests.release.xcconfig"; sourceTree = "<group>"; }; 89C6BE57DB24E9ADA2F236DE /* Pods-Databag-DatabagTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Databag-DatabagTests.release.xcconfig"; path = "Target Support Files/Pods-Databag-DatabagTests/Pods-Databag-DatabagTests.release.xcconfig"; sourceTree = "<group>"; };
@ -97,7 +95,6 @@
13B07FB51A68108700A75B9A /* Images.xcassets */, 13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */, 13B07FB61A68108700A75B9A /* Info.plist */,
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
7B6135A229B439B80094A6E7 /* login.png */,
13B07FB71A68108700A75B9A /* main.m */, 13B07FB71A68108700A75B9A /* main.m */,
); );
name = Databag; name = Databag;
@ -253,7 +250,6 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
7B6135A329B439B80094A6E7 /* login.png in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */, 7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */,
); );
@ -575,7 +571,7 @@
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
@ -647,7 +643,7 @@
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;

View File

@ -0,0 +1,14 @@
import { createContext } from 'react';
import { useRingContext } from './useRingContext.hook';
export const RingContext = createContext({});
export function RingContextProvider({ children }) {
const { state, actions } = useRingContext();
return (
<RingContext.Provider value={{ state, actions }}>
{children}
</RingContext.Provider>
);
}

View File

@ -11,6 +11,7 @@ import { AccountContext } from 'context/AccountContext';
import { ProfileContext } from 'context/ProfileContext'; import { ProfileContext } from 'context/ProfileContext';
import { CardContext } from 'context/CardContext'; import { CardContext } from 'context/CardContext';
import { ChannelContext } from 'context/ChannelContext'; import { ChannelContext } from 'context/ChannelContext';
import { RingContext } from 'context/RingContext';
import { getVersion, getApplicationName, getDeviceId } from 'react-native-device-info' import { getVersion, getApplicationName, getDeviceId } from 'react-native-device-info'
import messaging from '@react-native-firebase/messaging'; import messaging from '@react-native-firebase/messaging';
@ -27,6 +28,7 @@ export function useAppContext() {
const profile = useContext(ProfileContext); const profile = useContext(ProfileContext);
const card = useContext(CardContext); const card = useContext(CardContext);
const channel = useContext(ChannelContext); const channel = useContext(ChannelContext);
const ring = useContext(RingContext);
const delay = useRef(0); const delay = useRef(0);
const ws = useRef(null); const ws = useRef(null);
@ -71,6 +73,7 @@ export function useAppContext() {
await profile.actions.setSession(access.current); await profile.actions.setSession(access.current);
await card.actions.setSession(access.current); await card.actions.setSession(access.current);
await channel.actions.setSession(access.current); await channel.actions.setSession(access.current);
await ring.actions.setSession(access.current);
setWebsocket(access.current); setWebsocket(access.current);
} }
@ -79,6 +82,7 @@ export function useAppContext() {
profile.actions.clearSession(); profile.actions.clearSession();
card.actions.clearSession(); card.actions.clearSession();
channel.actions.clearSession(); channel.actions.clearSession();
ring.actions.clearSession();
updateState({ session: false }); updateState({ session: false });
clearWebsocket(); clearWebsocket();
} }
@ -166,15 +170,24 @@ export function useAppContext() {
ws.current.onmessage = (ev) => { ws.current.onmessage = (ev) => {
try { try {
delay.current = 0; delay.current = 0;
const rev = JSON.parse(ev.data); let activity = JSON.parse(ev.data);
updateState({ status: 'connected' }); updateState({ status: 'connected' });
profile.actions.setRevision(rev.profile);
account.actions.setRevision(rev.account); if (activity.revision) {
channel.actions.setRevision(rev.channel); const { profile: profileRev, account: accountRev, channel: channelRev, card: cardRev } = activity.revision;
card.actions.setRevision(rev.card); profile.actions.setRevision(profileRev);
account.actions.setRevision(accountRev);
channel.actions.setRevision(channelRev);
card.actions.setRevision(cardRev);
}
if (activity.ring) {
const { cardId, callId, calleeToken } = activity.ring;
ring.actions.ring(cardId, callId, calleeToken);
}
} }
catch (err) { catch (err) {
console.log(err); console.log(err);
ws.current.close();
} }
} }
ws.current.onopen = () => { ws.current.onopen = () => {

View File

@ -0,0 +1,89 @@
import { useEffect, useContext, useState, useRef } from 'react';
import { createWebsocket } from 'api/fetchUtil';
import { addContactRing } from 'api/addContactRing';
import { addCall } from 'api/addCall';
import { keepCall } from 'api/keepCall';
import { removeCall } from 'api/removeCall';
import { removeContactCall } from 'api/removeContactCall';
export function useRingContext() {
const [state, setState] = useState({
ringing: new Map(),
callStatus: null,
cardId: null,
localStream: null,
localVideo: false,
localAudio: false,
remoteStream: null,
removeVideo: false,
removeAudio: false,
});
const access = useRef(null);
const EXPIRE = 3000
const RING = 2000
const ringing = useRef(new Map());
const calling = useRef(null);
const ws = useRef(null);
const pc = useRef(null);
const stream = useRef(null);
const accessVideo = useRef(false);
const accessAudio = useRef(false);
const videoTrack = useRef();
const audioTrack = useRef();
const iceServers = [
{
urls: 'stun:35.165.123.117:5001?transport=udp',
username: 'user',
credential: 'pass'
},
{
urls: 'turn:35.165.123.117:5001?transport=udp',
username: 'user',
credential: 'pass'
}];
const updateState = (value) => {
setState((s) => ({ ...s, ...value }))
}
const actions = {
setSession: (token) => {
if (access.current) {
throw new Error("invalid ring state");
}
access.current = token;
ringing.current = new Map();
calling.current = null;
updateState({ callStatus: null, ringing: ringing.current });
},
clearSession: () => {
access.current = null;
},
ring: (cardId, callId, calleeToken) => {
console.log("RING");
},
ignore: (cardId, callId) => {
},
decline: async (cardId, contactNode, contactToken, callId) => {
},
accept: async (cardId, callId, contactNode, contactToken, calleeToken) => {
},
end: async () => {
},
call: async (cardId, contactNode, contactToken) => {
},
enableVideo: async () => {
},
disableVideo: async () => {
},
enableAudio: async () => {
},
disableAudio: async () => {
},
}
return { state, actions }
}

View File

@ -370,8 +370,8 @@ export function Session() {
tabBarActiveTintColor: Colors.white, tabBarActiveTintColor: Colors.white,
tabBarInactiveTintColor: Colors.disabled, tabBarInactiveTintColor: Colors.disabled,
})}> })}>
<Tab.Screen name="Profile" component={ProfileStackScreen} />
<Tab.Screen name="Conversation" component={ConversationStackScreen} /> <Tab.Screen name="Conversation" component={ConversationStackScreen} />
<Tab.Screen name="Profile" component={ProfileStackScreen} />
<Tab.Screen name="Contacts" component={ContactStackScreen} /> <Tab.Screen name="Contacts" component={ContactStackScreen} />
</Tab.Navigator> </Tab.Navigator>
)} )}