rendering incoming calls

This commit is contained in:
Roland Osborne 2023-03-22 15:17:00 -07:00
parent 479ce81b30
commit 48a71d8051
4 changed files with 156 additions and 3 deletions

View File

@ -6,7 +6,7 @@ export function useRingContext() {
});
const access = useRef(null);
const EXPIRE = 3000
const EXPIRE = 3000000
const ringing = useRef(new Map());
const updateState = (value) => {
@ -20,18 +20,24 @@ export function useRingContext() {
},
ring: (cardId, callId, calleeToken) => {
const key = `${cardId}:${callId}`
const call = ringing.current.get(key) || { calleeToken, callId }
const call = ringing.current.get(key) || { cardId, calleeToken, callId }
call.expires = Date.now() + EXPIRE;
ringing.current.set(key, call);
updateState({ ringing: ringing.current });
setTimeout(() => {
updateState({ ringing: ringing.current });
}, 3000);
},
ignore: (cardId, callId) => {
const key = `${cardId}:${callId}`
console.log("IGNORE", key);
const call = ringing.current.get(key);
if (call) {
call.status = 'ignored'
ringing.current.set(key, call);
updateState({ ringing: ringing.current });
console.log(ringing.current);
}
},
decline: (cardId, callId) => {

View File

@ -1,3 +1,4 @@
import { useState, useEffect } from 'react';
import { Drawer, Spin } from 'antd';
import { SessionWrapper } from './Session.styled';
import { useSession } from './useSession.hook';
@ -12,10 +13,33 @@ import { Listing } from './listing/Listing';
import { Account } from './account/Account';
import { Welcome } from './welcome/Welcome';
import { BottomNav } from './bottomNav/BottomNav';
import { Logo } from 'logo/Logo';
import { EyeInvisibleOutlined, CloseOutlined, PhoneOutlined } from '@ant-design/icons';
export function Session() {
const { state, actions } = useSession();
const [ringing, setRinging] = useState([]);
console.log(state.ringing);
useEffect(() => {
let incoming = [];
for (let i = 0; i < state.ringing.length; i++) {
const ring = state.ringing[i];
const label = ring.name ? ring.name : `${ring.handle}@${ring.node}`;
incoming.push(
<div className="ringing-entry">
<Logo url={ring.url} width={40} height={40} radius={4} />
<div className="ringing-name">{ label }</div>
<div onClick={() => actions.ignore(ring)} className="ringing-ignore"><EyeInvisibleOutlined /></div>
<div onClick={() => actions.decline(ring)} className="ringing-decline"><PhoneOutlined /></div>
<div onClick={() => actions.accept(ring)} className="ringing-accept"><PhoneOutlined /></div>
</div>
);
}
setRinging(incoming);
}, [state.ringing]);
const closeAccount = () => {
actions.closeProfile();
@ -76,6 +100,13 @@ export function Session() {
<div class="center">
<div class="reframe">
<Welcome />
{ ringing.length > 0 && (
<div className="ringing">
<div className="ringing-list">
{ringing}
</div>
</div>
)}
</div>
{ state.conversation && (
<div class="reframe">
@ -174,6 +205,13 @@ export function Session() {
<Profile closeProfile={closeAccount}/>
)}
</Drawer>
{ ringing.length > 0 && (
<div className="ringing">
<div className="ringing-list">
{ringing}
</div>
</div>
)}
</div>
</div>
)}
@ -224,6 +262,13 @@ export function Session() {
<Profile />
</div>
)}
{ ringing.length > 0 && (
<div className="ringing">
<div className="ringing-list">
{ringing}
</div>
</div>
)}
</div>
<div class="bottom">
<BottomNav state={state} actions={actions} />

View File

@ -1,4 +1,5 @@
import styled from 'styled-components';
import Colors from 'constants/Colors';
export const SessionWrapper = styled.div`
height: 100%;
@ -11,6 +12,86 @@ export const SessionWrapper = styled.div`
z-index: 2;
}
.ringing {
position: absolute;
top: 20%;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
z-index: 2;
.ringing-list {
padding: 4px;
border-radius: 4px;
background-color: rgba(0,0,0,0.3);
display: flex;
flex-direction: column;
.ringing-entry {
display: flex;
flex-direction: row;
align-items: center;
padding-left: 8px;
.ringing-accept {
color: ${Colors.primary};
font-size: 18;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
background-color: ${Colors.white};
border-radius: 16px;
margin: 8px;
cursor: pointer;
}
.ringing-ignore {
color: ${Colors.grey};
font-size: 18;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
background-color: ${Colors.white};
border-radius: 16px;
margin: 8px;
cursor: pointer;
}
.ringing-decline {
color: ${Colors.alert};
font-size: 18;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
background-color: ${Colors.white};
border-radius: 16px;
margin: 8px;
transform: rotate(270deg);
cursor: pointer;
}
.ringing-name {
font-size: 16px;
width: 192px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: flex;
justify-content: center;
color: ${Colors.white};
}
}
}
}
.spinner {
position: absolute;
width: 100%;

View File

@ -23,6 +23,7 @@ export function useSession() {
profile: false,
account: false,
loading: false,
ringing: [],
});
const app = useContext(AppContext);
@ -42,7 +43,18 @@ export function useSession() {
}
useEffect(() => {
console.log(ring.state);
const ringing = [];
const expired = Date.now();
ring.state.ringing.forEach(call => {
if (call.expires > expired && !call.status) {
const { callId, cardId, calleeToken } = call;
const contact = card.state.cards.get(cardId);
const { imageSet, name, handle, node } = contact.data.cardProfile || {};
const img = imageSet ? card.actions.getCardImageUrl(cardId) : 'avatar';
ringing.push({ cardId, img, name, handle, node, callId, calleeToken });
}
});
updateState({ ringing });
}, [ring.state]);
useEffect(() => {
@ -125,6 +137,15 @@ export function useSession() {
closeDetails: () => {
updateState({ details: false });
},
ignore: (call) => {
ring.actions.ignore(call.cardId, call.callId);
},
decline: (call) => {
ring.actions.decline(call.cardId, call.callId);
},
accept: (call) => {
ring.actions.accept(call.cardId, call.callId);
},
};
return { state, actions };