mirror of
https://github.com/balzack/databag.git
synced 2025-04-23 01:55:17 +00:00
preparing call component
This commit is contained in:
parent
84e351b1f8
commit
42c4026679
@ -1,13 +1,19 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect } 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';
|
||||
|
||||
export function Calling() {
|
||||
export function Calling({ callCard }: { callCard: string }) {
|
||||
const { state, actions } = useCalling();
|
||||
|
||||
useEffect(() => {
|
||||
if (callCard.cardId) {
|
||||
actions.call(callCard.cardId);
|
||||
}
|
||||
}, [callCard]);
|
||||
|
||||
return (
|
||||
<View style={(state.link || state.ringing.length > 0) ? styles.active : styles.inactive}>
|
||||
<BlurView style={styles.blur} blurType="dark" blurAmount={2} reducedTransparencyFallbackColor="dark" />
|
||||
|
@ -16,8 +16,6 @@ export function useCalling() {
|
||||
useEffect(() => {
|
||||
if (app.state.session) {
|
||||
const setRinging = (ringing: { cardId: string, callId: string }[]) => {
|
||||
console.log(">>>> ", ringing);
|
||||
|
||||
updateState({ ringing });
|
||||
}
|
||||
const ring = app.state.session.getRing();
|
||||
@ -29,6 +27,9 @@ console.log(">>>> ", ringing);
|
||||
}, [app.state.session]);
|
||||
|
||||
const actions = {
|
||||
call: (cardId: string) => {
|
||||
console.log('calling: ', cardId);
|
||||
},
|
||||
}
|
||||
|
||||
return { state, actions }
|
||||
|
@ -33,19 +33,24 @@ export function Session() {
|
||||
const scheme = useColorScheme();
|
||||
const [tab, setTab] = useState('content');
|
||||
const [textCard, setTextCard] = useState({ cardId: null} as {cardId: null|string});
|
||||
const [callCard, setCallCard] = useState({ cardId: null} as {cardId: null|string});
|
||||
const [dismissed, setDismissed] = useState(false);
|
||||
const [disconnected, setDisconnected] = useState(false);
|
||||
const [showDisconnected, setShowDisconnected] = useState(false);
|
||||
|
||||
const sessionNav = {strings: state.strings};
|
||||
const showContent = {display: tab === 'content' ? 'flex' : 'none'};
|
||||
const showContact = {display: tab === 'contacts' ? 'flex' : 'none'};
|
||||
const showSettings = {display: tab === 'settings' ? 'flex' : 'none'};
|
||||
|
||||
const textContact = (cardId: null|string) => {
|
||||
setTextCard({ cardId });
|
||||
}
|
||||
|
||||
const callContact = (cardId: null|string) => {
|
||||
setCallCard({ cardId });
|
||||
}
|
||||
|
||||
const sessionNav = {strings: state.strings, callContact, callCard, textContact, textCard};
|
||||
const showContent = {display: tab === 'content' ? 'flex' : 'none'};
|
||||
const showContact = {display: tab === 'contacts' ? 'flex' : 'none'};
|
||||
const showSettings = {display: tab === 'settings' ? 'flex' : 'none'};
|
||||
|
||||
const dismiss = () => {
|
||||
setDismissed(true);
|
||||
setTimeout(() => {
|
||||
@ -89,7 +94,7 @@ export function Session() {
|
||||
...styles.body,
|
||||
...showContact,
|
||||
}}>
|
||||
<ContactTab textContact={textContact} scheme={scheme} />
|
||||
<ContactTab textContact={textContact} callContact={callContact} scheme={scheme} />
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
@ -190,7 +195,7 @@ export function Session() {
|
||||
</Surface>
|
||||
</View>
|
||||
)}
|
||||
<Calling />
|
||||
<Calling callCard={callCard} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@ -226,7 +231,7 @@ function ContentTab({scheme, textCard, contentTab}: {scheme: string, textCard: {
|
||||
);
|
||||
}
|
||||
|
||||
function ContactTab({scheme, textContact}: {scheme: string, textContact: (cardId: null|string)=>void}) {
|
||||
function ContactTab({scheme, textContact, callContact}: {scheme: string, textContact: (cardId: string)=>void, callContact: (cardId: string)=>void}) {
|
||||
const [contactParams, setContactParams] = useState({
|
||||
guid: '',
|
||||
} as ContactParams);
|
||||
@ -244,7 +249,7 @@ function ContactTab({scheme, textContact}: {scheme: string, textContact: (cardId
|
||||
setContactParams(params);
|
||||
props.navigation.navigate('profile');
|
||||
}}
|
||||
callContact={(cardId: string)=>console.log("CALL: ", cardId)}
|
||||
callContact={callContact}
|
||||
textContact={textContact}
|
||||
/>
|
||||
)}
|
||||
@ -364,7 +369,6 @@ function RegistryScreen({nav}) {
|
||||
}
|
||||
|
||||
function ContactsScreen({nav}) {
|
||||
const [textCard, setTextCard] = useState({ cardId: null} as {cardId: null|string});
|
||||
const ContactsComponent = useCallback(
|
||||
() => (
|
||||
<Surface elevation={3}>
|
||||
@ -373,8 +377,8 @@ function ContactsScreen({nav}) {
|
||||
openContact={(params: ContactParams) => {
|
||||
nav.openContact(params, nav.profile.openDrawer);
|
||||
}}
|
||||
callContact={(cardId: string)=>console.log('CALL: ', cardId)}
|
||||
textContact={(cardId: null|string)=>setTextCard({ cardId })}
|
||||
callContact={nav.callContact}
|
||||
textContact={nav.textContact}
|
||||
/>
|
||||
</Surface>
|
||||
),
|
||||
@ -393,7 +397,7 @@ function ContactsScreen({nav}) {
|
||||
overlayColor: 'rgba(8,8,8,.9)',
|
||||
}}>
|
||||
<ContactsDrawer.Screen name="settings">{({navigation}) => (
|
||||
<SettingsScreen nav={{...nav, textCard, contacts: navigation}} />
|
||||
<SettingsScreen nav={{...nav, textCard, callCard, contacts: navigation}} />
|
||||
)}</ContactsDrawer.Screen>
|
||||
</ContactsDrawer.Navigator>
|
||||
);
|
||||
@ -428,8 +432,6 @@ function SettingsScreen({nav}) {
|
||||
}
|
||||
|
||||
function HomeScreen({nav}) {
|
||||
const [textCard, setTextCard] = useState({ cardId: null} as {cardId: null|string});
|
||||
|
||||
return (
|
||||
<View style={styles.frame}>
|
||||
<View style={styles.left}>
|
||||
|
@ -249,6 +249,15 @@ export const defaultProfileEntity = {
|
||||
node: '',
|
||||
};
|
||||
|
||||
export type Calling = {
|
||||
id: string;
|
||||
cardId: string;
|
||||
callerToken: string;
|
||||
calleeToken: string;
|
||||
keepAlive: number;
|
||||
ice: { urls: string; username: string; credential: string }[];
|
||||
}
|
||||
|
||||
export type Ringing = {
|
||||
cardId: string;
|
||||
callId: string;
|
||||
|
@ -21,6 +21,7 @@ export class LinkModule implements Link {
|
||||
private secure: boolean;
|
||||
private token: string;
|
||||
private ice: { urls: string; username: string; credential: string }[];
|
||||
private cleanup: null | (()=>void);
|
||||
|
||||
constructor(log: Logging) {
|
||||
this.log = log;
|
||||
@ -36,6 +37,7 @@ export class LinkModule implements Link {
|
||||
this.aliveInterval = null;
|
||||
this.ringInterval = null;
|
||||
this.ice = [];
|
||||
this.cleanup = null;
|
||||
}
|
||||
|
||||
public getIce(): { urls: string; username: string; credential: string }[] {
|
||||
@ -44,6 +46,7 @@ export class LinkModule implements Link {
|
||||
|
||||
public async call(node: string, secure: boolean, token: string, cardId: string, contactNode: string, contactToken: string) {
|
||||
const call = await addCall(node, secure, token, cardId);
|
||||
this.cleanup = () => { removeCall(node, secure, token, call.id };
|
||||
|
||||
const { id, keepAlive, calleeToken, callerToken, ice } = call;
|
||||
const insecure = /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|:\d+$|$)){4}$/.test(contactNode);
|
||||
@ -74,6 +77,7 @@ export class LinkModule implements Link {
|
||||
public async join(server: string, access: string, ice: { urls: string; username: string; credential: string }[]) {
|
||||
this.ice = ice;
|
||||
const insecure = /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|:\d+$|$)){4}$/.test(server);
|
||||
this.cleanup = () => { removeContactCall(server, !insecure, access); }
|
||||
connect(access, server, !insecure);
|
||||
}
|
||||
|
||||
@ -103,6 +107,13 @@ export class LinkModule implements Link {
|
||||
if (this.websocket) {
|
||||
this.websocket.close();
|
||||
}
|
||||
if (this.cleanup) {
|
||||
try {
|
||||
this.cleanup();
|
||||
} catch (err) {
|
||||
this.log.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public setStatusListener(listener: (status: string) => void) {
|
||||
|
10
app/sdk/src/net/addCall.ts
Normal file
10
app/sdk/src/net/addCall.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
import { Calling } from '../entities';
|
||||
|
||||
export async function addCall(node: string, secure: boolean, token: string, cardId: string): Promise<Calling> {
|
||||
const endpoint = `http${secure ? 's' : ''}://${node}/talk/calls?agent=${token}`;
|
||||
const call = await fetchWithTimeout(endpoint, { method: 'POST', body: JSON.stringify(cardId) });
|
||||
checkResponse(call.status);
|
||||
return await call.json();
|
||||
}
|
||||
|
9
app/sdk/src/net/addContactRing.ts
Normal file
9
app/sdk/src/net/addContactRing.ts
Normal file
@ -0,0 +1,9 @@
|
||||
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}';
|
||||
const { status } = await fetchWithTimeout(endpoint, { method: 'POST', body: JSON.stringify(ringing) });
|
||||
checkResponse(status);
|
||||
}
|
||||
|
8
app/sdk/src/net/keepCall.ts
Normal file
8
app/sdk/src/net/keepCall.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function keepCall(node: string, secure: boolean, token: string, callId: string): Promise<void> {
|
||||
const endpoint = `http${secure ? 's' : ''}://${node}/talk/calls/${callId}?agent=${token}`;
|
||||
const { status } = await fetchWithTimeout(endpoint, { method: 'PUT' });
|
||||
checkResponse(status);
|
||||
}
|
||||
|
8
app/sdk/src/net/removeCall.ts
Normal file
8
app/sdk/src/net/removeCall.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function removeCall(node: string, secure: boolean, token: string, callId: string): Promise<void> {
|
||||
const endpoint = `http${secure ? 's' : ''}://${node}/talk/calls/${callId}?agent=${token}`;
|
||||
const { status } = await fetchWithTimeout(endpoint, { method: 'DELETE' });
|
||||
checkResponse(status);
|
||||
}
|
||||
|
7
app/sdk/src/net/removeContactCall.ts
Normal file
7
app/sdk/src/net/removeContactCall.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { checkResponse, fetchWithTimeout } from './fetchUtil';
|
||||
|
||||
export async function removeContactCall(server: string, secure: boolean, token: string, callId: string): Promise<void> {
|
||||
const endpoint = `http${secure ? 's' : ''}://${server}/talk/calls/${callId}?contact=${token}`;
|
||||
const { status } = await fetchWithTimeout(endpoint, { method: 'DELETE' });
|
||||
checkResponse(status);
|
||||
}
|
@ -84,14 +84,15 @@ export class RingModule implements Ring {
|
||||
if (!entry || entry.expires < now || entry.status !== 'ringing') {
|
||||
throw new Error('invalid ringing entry');
|
||||
}
|
||||
entry.status = 'declined';
|
||||
this.emitRinging();
|
||||
try {
|
||||
await removeContactCall(contactNode, entry.call.calleeToken, entry.call.callId);
|
||||
const insecure = /^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|:\d+$|$)){4}$/.test(contactNode);
|
||||
await removeContactCall(contactNode, !insecure, entry.call.calleeToken, entry.call.callId);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
entry.status = 'declined';
|
||||
this.emitRinging();
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
|
Loading…
x
Reference in New Issue
Block a user