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

View File

@ -13,7 +13,6 @@
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 */; };
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 */; };
A0B1EC4533FCFC5940B5FD7F /* Pods_Databag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9462C028F47F083241BB7941 /* Pods_Databag.framework */; };
/* 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>"; };
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>"; };
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>"; };
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>"; };
@ -97,7 +95,6 @@
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
7B6135A229B439B80094A6E7 /* login.png */,
13B07FB71A68108700A75B9A /* main.m */,
);
name = Databag;
@ -253,7 +250,6 @@
buildActionMask = 2147483647;
files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
7B6135A329B439B80094A6E7 /* login.png in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
7B13A774299E21170048D0DD /* GoogleService-Info.plist in Resources */,
);
@ -575,7 +571,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
@ -647,7 +643,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = 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 { CardContext } from 'context/CardContext';
import { ChannelContext } from 'context/ChannelContext';
import { RingContext } from 'context/RingContext';
import { getVersion, getApplicationName, getDeviceId } from 'react-native-device-info'
import messaging from '@react-native-firebase/messaging';
@ -27,6 +28,7 @@ export function useAppContext() {
const profile = useContext(ProfileContext);
const card = useContext(CardContext);
const channel = useContext(ChannelContext);
const ring = useContext(RingContext);
const delay = useRef(0);
const ws = useRef(null);
@ -71,6 +73,7 @@ export function useAppContext() {
await profile.actions.setSession(access.current);
await card.actions.setSession(access.current);
await channel.actions.setSession(access.current);
await ring.actions.setSession(access.current);
setWebsocket(access.current);
}
@ -79,6 +82,7 @@ export function useAppContext() {
profile.actions.clearSession();
card.actions.clearSession();
channel.actions.clearSession();
ring.actions.clearSession();
updateState({ session: false });
clearWebsocket();
}
@ -166,15 +170,24 @@ export function useAppContext() {
ws.current.onmessage = (ev) => {
try {
delay.current = 0;
const rev = JSON.parse(ev.data);
let activity = JSON.parse(ev.data);
updateState({ status: 'connected' });
profile.actions.setRevision(rev.profile);
account.actions.setRevision(rev.account);
channel.actions.setRevision(rev.channel);
card.actions.setRevision(rev.card);
if (activity.revision) {
const { profile: profileRev, account: accountRev, channel: channelRev, card: cardRev } = activity.revision;
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) {
console.log(err);
ws.current.close();
}
}
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,
tabBarInactiveTintColor: Colors.disabled,
})}>
<Tab.Screen name="Profile" component={ProfileStackScreen} />
<Tab.Screen name="Conversation" component={ConversationStackScreen} />
<Tab.Screen name="Profile" component={ProfileStackScreen} />
<Tab.Screen name="Contacts" component={ContactStackScreen} />
</Tab.Navigator>
)}