diff --git a/app/mobile/ios/Podfile.lock b/app/mobile/ios/Podfile.lock index 09dcb1db..3aa16c90 100644 --- a/app/mobile/ios/Podfile.lock +++ b/app/mobile/ios/Podfile.lock @@ -62,6 +62,7 @@ PODS: - hermes-engine (0.71.3): - hermes-engine/Pre-built (= 0.71.3) - hermes-engine/Pre-built (0.71.3) + - JitsiWebRTC (106.0.0) - libevent (2.1.12) - nanopb (2.30909.0): - nanopb/decode (= 2.30909.0) @@ -339,6 +340,9 @@ PODS: - react-native-video/Video (= 5.2.1) - react-native-video/Video (5.2.1): - React-Core + - react-native-webrtc (106.0.7): + - JitsiWebRTC (~> 106.0.0) + - React-Core - React-perflogger (0.71.3) - React-RCTActionSheet (0.71.3): - React-Core/RCTActionSheetHeaders (= 0.71.3) @@ -510,6 +514,7 @@ DEPENDENCIES: - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) - react-native-sqlite-storage (from `../node_modules/react-native-sqlite-storage`) - react-native-video (from `../node_modules/react-native-video`) + - react-native-webrtc (from `../node_modules/react-native-webrtc`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) @@ -545,6 +550,7 @@ SPEC REPOS: - fmt - GoogleDataTransport - GoogleUtilities + - JitsiWebRTC - libevent - nanopb - PromisesObjC @@ -603,6 +609,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-sqlite-storage" react-native-video: :path: "../node_modules/react-native-video" + react-native-webrtc: + :path: "../node_modules/react-native-webrtc" React-perflogger: :path: "../node_modules/react-native/ReactCommon/reactperflogger" React-RCTActionSheet: @@ -666,6 +674,7 @@ SPEC CHECKSUMS: GoogleDataTransport: ea169759df570f4e37bdee1623ec32a7e64e67c4 GoogleUtilities: c2bdc4cf2ce786c4d2e6b3bcfd599a25ca78f06f hermes-engine: 38bfe887e456b33b697187570a08de33969f5db7 + JitsiWebRTC: f441eb0e2d67f0588bf24e21c5162e97342714fb libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431 PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb @@ -689,6 +698,7 @@ SPEC CHECKSUMS: react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc react-native-sqlite-storage: f6d515e1c446d1e6d026aa5352908a25d4de3261 react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253 + react-native-webrtc: 0df36747802476e758af6b6dceccdeaed8c826c2 React-perflogger: af8a3d31546077f42d729b949925cc4549f14def React-RCTActionSheet: 57cc5adfefbaaf0aae2cf7e10bccd746f2903673 React-RCTAnimation: 11c61e94da700c4dc915cf134513764d87fc5e2b diff --git a/app/mobile/src/session/profile/Profile.jsx b/app/mobile/src/session/profile/Profile.jsx index d62bab4c..0165e059 100644 --- a/app/mobile/src/session/profile/Profile.jsx +++ b/app/mobile/src/session/profile/Profile.jsx @@ -1,3 +1,4 @@ +import { useEffect, useRef, useState } from 'react'; import { ActivityIndicator, KeyboardAvoidingView, Modal, View, Switch, Text, TextInput, TouchableOpacity, Alert } from 'react-native'; import Ionicons from 'react-native-vector-icons/AntDesign'; import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons'; @@ -10,6 +11,18 @@ import { BlockedTopics } from './blockedTopics/BlockedTopics'; import { BlockedContacts } from './blockedContacts/BlockedContacts'; import { BlockedMessages } from './blockedMessages/BlockedMessages'; +import { + ScreenCapturePickerView, + RTCPeerConnection, + RTCIceCandidate, + RTCSessionDescription, + RTCView, + MediaStream, + MediaStreamTrack, + mediaDevices, + registerGlobals +} from 'react-native-webrtc'; + export function ProfileHeader() { const { state, actions } = useProfile(); @@ -20,6 +33,103 @@ export function ProfileHeader() { export function ProfileBody() { const { state, actions } = useProfile(); + const ws = useRef(); + const peer = useRef(); + const stream = useRef(); + const [streamUrl, setStreamUrl] = useState(null); + + useEffect(() => { + ws.current = new WebSocket('wss://balzack.coredb.org/relay'); + ws.current.onmessage = async (ev) => { + +console.log(ev.data); + + const msg = JSON.parse(ev.data); + if (msg.candidate) { + console.log("> CANDIDATE: ", msg.candidate); + const candidate = new RTCIceCandidate( msg.candidate ); + return peer.current.addIceCandidate(candidate); + } + else if (msg.offer) { + console.log("> OFFER: ", msg.offer); + const offerDescription = new RTCSessionDescription(msg.offer ); + await peer.current.setRemoteDescription( offerDescription ); + const answer = await peer.current.createAnswer(); + await peer.current.setLocalDescription( answer ); + ws.current.send(JSON.stringify({ answer })); + } + else if (msg.answer) { + console.log("> ANSWER: ", msg.answer); + } + } + ws.current.onclose = (e) => { + console.log("CLOSED"); + } + ws.current.onopen = () => { + console.log("OPENED"); + } + ws.current.error = (e) => { + console.log("ERROR"); + } + + + + let peerConstraints = { + iceServers: [ + { + urls: 'stun:192.168.13.233:5001?transport=udp', + username: 'user', + credential: 'pass' + }, + { + urls: 'turn:192.168.13.233:5001?transport=udp', + username: 'user', + credential: 'pass' + }] + }; + + peer.current = new RTCPeerConnection( peerConstraints ); + + peer.current.addEventListener( 'connectionstatechange', event => { + console.log("CONNECTION STATE"); + } ); + + peer.current.addEventListener( 'icecandidate', event => { + if ( !event.candidate ) { return; }; + ws.current.send(JSON.stringify({ candidate: event.candidate })); + console.log("SEND CANDIDATE!!!"); + } ); + + peer.current.addEventListener( 'icecandidateerror', event => { + console.log("ICE ERROR"); + } ); + + peer.current.addEventListener( 'iceconnectionstatechange', event => { + console.log("ICE STATE CHANGE"); + } ); + + peer.current.addEventListener( 'negotiationneeded', event => { + console.log("ICE NEGOTIATION"); + } ); + + peer.current.addEventListener( 'signalingstatechange', event => { + console.log("ICE SIGNALING"); + } ); + + peer.current.addEventListener( 'track', event => { + console.log("ICE TRACK", event.track); + // Grab the remote track from the connected participant. + //remoteMediaStream = remoteMediaStream || new MediaStream(); + //remoteMediaStream.addTrack( event.track, remoteMediaStream ); + + if (!stream.current) { + stream.current = new MediaStream(); + } + stream.current.addTrack(event.track, stream.current); + setStreamUrl(stream.current.toURL()); + } ); + + }, []); const logout = async () => { Alert.alert( @@ -131,104 +241,14 @@ export function ProfileBody() { return ( - - - - - - - - - - - { state.disconnected && ( - Disconnected - )} - - - - - { state.name && ( - { state.name } - )} - { !state.name && ( - Name - )} - - - - - - - { state.location && ( - { state.location } - )} - { !state.location && ( - Location - )} - - - - - - { state.description && ( - { state.description } - )} - { !state.description && ( - Description - )} - - - - - - setVisible(!state.searchable)} activeOpacity={1}> - Visible in Registry - - - - - setNotifications(!state.pushEnabled)} activeOpacity={1}> - Enable Notifications - - - - - - - - Logout - - - - - Change Login - - - { state.sealable && ( - - - Sealed Topics - - )} - - - - Delete Account - - - Manage Blocked: - - - Contacts - - - Topics - - - Messages - - + WEBRTC +