adding webrtc calls

This commit is contained in:
Roland Osborne 2025-01-23 16:58:20 -08:00
parent 42c4026679
commit 37fd22b58b
6 changed files with 63 additions and 10 deletions

View File

@ -1,22 +1,46 @@
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { SafeAreaView, Modal, ScrollView, View } from 'react-native';
import { Surface, Icon, Divider, Button, IconButton, Text, TextInput} from 'react-native-paper';
import {styles} from './Calling.styled';
import {useCalling} from './useCalling.hook';
import {BlurView} from '@react-native-community/blur';
import { Confirm } from '../confirm/Confirm';
export function Calling({ callCard }: { callCard: string }) {
const { state, actions } = useCalling();
const [alert, setAlert] = useState(false);
const call = async (cardId: string) => {
try {
await actions.call(cardId);
} catch (err) {
console.log(err);
setAlert(true);
}
}
const alertParams = {
title: state.strings.operationFailed,
prompt: state.strings.tryAgain,
cancel: {
label: state.strings.close,
action: () => {
setAlert(false);
},
},
};
useEffect(() => {
if (callCard.cardId) {
actions.call(callCard.cardId);
const { cardId } = callCard;
if (cardId) {
call(cardId);
}
}, [callCard]);
return (
<View style={(state.link || state.ringing.length > 0) ? styles.active : styles.inactive}>
<View style={(state.link || state.ringing.length > 0 || alert) ? styles.active : styles.inactive}>
<BlurView style={styles.blur} blurType="dark" blurAmount={2} reducedTransparencyFallbackColor="dark" />
<Confirm show={alert} params={alertParams} />
</View>
);
}

View File

@ -1,11 +1,15 @@
import { useState, useContext, useEffect } from 'react'
import { DisplayContext } from '../context/DisplayContext';
import { AppContext } from '../context/AppContext'
import { ContextType } from '../context/ContextType'
export function useCalling() {
const app = useContext(AppContext) as ContextType
const app = useContext(AppContext) as ContextType;
const display = useContext(DisplayContext) as ContextType;
const [state, setState] = useState({
strings: {},
ringing: [],
cards: [],
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -13,22 +17,35 @@ export function useCalling() {
setState((s) => ({ ...s, ...value }))
}
useEffect(() => {
const { strings } = display.state;
updateState({ strings });
}, [display.state]);
useEffect(() => {
if (app.state.session) {
const setRinging = (ringing: { cardId: string, callId: string }[]) => {
updateState({ ringing });
}
const setContacts = (cards: Card[]) => {
updateState({ cards });
}
const ring = app.state.session.getRing();
ring.addRingingListener(setRinging);
const contact = app.state.session.getContact();
contact.addCardListener(setContacts);
return () => {
ring.removeRingingListener(setRinging);
contact.removeCardListener(setContacts);
}
}
}, [app.state.session]);
const actions = {
call: (cardId: string) => {
console.log('calling: ', cardId);
call: async (cardId: string) => {
const contact = app.state.session.getContact();
const link = await contact.callCard(cardId);
console.log(link);
},
}

View File

@ -854,6 +854,7 @@ export class ContactModule implements Contact {
}
const { profile, detail } = entry.item;
const link = new LinkModule(this.log);
console.log("LINK CALL");
await link.call(node, secure, token, cardId, profile.node, detail.token);
return link;
}

View File

@ -1,4 +1,9 @@
import type { Link, Logging } from './api';
import { addCall } from './net/addCall';
import { removeCall } from './net/removeCall';
import { removeContactCall } from './net/removeContactCall';
import { addContactRing } from './net/addContactRing';
import { keepCall } from './net/keepCall';
const RETRY_INTERVAL = 1000;
const PING_INTERVAL = 5000;
@ -45,14 +50,17 @@ export class LinkModule implements Link {
}
public async call(node: string, secure: boolean, token: string, cardId: string, contactNode: string, contactToken: string) {
console.log('add call');
const call = await addCall(node, secure, token, cardId);
this.cleanup = () => { removeCall(node, secure, token, call.id };
this.cleanup = () => { removeCall(node, secure, token, call.id) };
console.log('add ring', contactNode);
const { id, keepAlive, calleeToken, callerToken, ice } = call;
const insecure = /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|:\d+$|$)){4}$/.test(contactNode);
const ring = { index: 0, callId: id, calleeToken, ice };
await addContactRing(contactNode, !insecure, contactToken, ring);
console.log('go');
this.aliveInterval = setInterval(async () => {
try {
await keepCall(node, secure, token, id);

View File

@ -1,8 +1,10 @@
import { checkResponse, fetchWithTimeout } from './fetchUtil';
import { Ringing } from '../entities';
export async function addContactRing(server: string, secure: boolean, token: string, ringing: Ringing): {
const endpoint = `http${secure ? 's' : '' }://${server}/talk/rings/?contact=${token}';
export async function addContactRing(server: string, secure: boolean, token: string, ringing: Ringing) {
const endpoint = `http${secure ? 's' : '' }://${server}/talk/rings/?contact=${token}`;
console.log(endpoint);
const { status } = await fetchWithTimeout(endpoint, { method: 'POST', body: JSON.stringify(ringing) });
checkResponse(status);
}

View File

@ -2,6 +2,7 @@ import { EventEmitter } from 'eventemitter3';
import { LinkModule } from './link';
import type { Ring, Link, Logging } from './api';
import type { Call } from './types';
import { removeContactCall } from './net/removeContactCall';
const EXPIRES = 6000;