diff --git a/app/client/web/src/context/useRingContext.hook.ts b/app/client/web/src/context/useRingContext.hook.ts index addc06ef..7e16fb68 100644 --- a/app/client/web/src/context/useRingContext.hook.ts +++ b/app/client/web/src/context/useRingContext.hook.ts @@ -35,6 +35,7 @@ export function useRingContext() { connected: false, failed: false, fullscreen: false, + connectedTime: 0, }) // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -76,8 +77,14 @@ export function useRingContext() { if (call.current) { const { peer, link } = call.current; if (status === 'connected') { - updateState({ connected: true }); - await actions.enableAudio(); + const connectedTime = Math.floor((new Date()).getTime() / 1000); + updateState({ connected: true, connectedTime }); + try { + await actions.enableAudio(); + } catch (err) { + console.log('failed to enable audio on connection'); + console.log(err); + } } else if (status === 'closed') { await cleanup; } @@ -177,7 +184,7 @@ export function useRingContext() { call.current = { peer, link, candidates }; link.setStatusListener(linkStatus); link.setMessageListener((msg: any) => updatePeer('message', msg)); - updateState({ calling: card, failed: false, connected: false, + updateState({ calling: card, failed: false, connected: false, connectedTime: 0, audioEnabled: false, videoEnabled: false, localVideo: false, remoteVideo: false, localStream: localStream.current, remoteStream: remoteStream.current }); } @@ -204,7 +211,7 @@ export function useRingContext() { localStream.current = null; remoteStream.current = null, peerUpdate.current = []; - updateState({ calling: null, failed: false, localStream: null, remoteStream: null, localVideo: false, remoteVideo: false }); + updateState({ calling: null, connected: false, connectedTime: 0, failed: false, localStream: null, remoteStream: null, localVideo: false, remoteVideo: false }); closing.current = false; } diff --git a/app/client/web/src/ring/Ring.module.css b/app/client/web/src/ring/Ring.module.css index 50d83d6a..cbc98d94 100644 --- a/app/client/web/src/ring/Ring.module.css +++ b/app/client/web/src/ring/Ring.module.css @@ -1,57 +1,68 @@ -active { +.active { width: 100%; height: 64px; - max-width: 500px; display: flex; align-items: center; justify-content: center; } -inactive { +.inactive { display: none; } -ring { +.ring { display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; - height: 100%; + height: 48px; + max-width: 400px; border-radius: 16px; - padding-left: 16px; - padding-right: 8px; + padding-left: 32px; + padding-right: 32px; + gap: 8px; + background-color: var(--mantine-color-surface-4); } -card { +.card { padding: 8px; width: 100%; + height: 100%; } -circleIcon { -} -flipIcon { +.off { + margin-top: 16px; transform: rotate(135deg); } -end { +.space { + position: relative; + padding: 8px; } -name { +.circleIcon { +} +.flipIcon { + transform: rotate(135deg); +} +.end { +} +.name { flex-grow: 1; flex-shrink: 1; display: flex; flex-direction: row; padding-left: 8px; } -nameSet { +.nameSet { font-size: 20px; } -nameUnset { +.nameUnset { font-size: 20px; font-style: italic; } -status { +.status { width: 64px; display: flex; align-items: center; justify-content: center; } -duration { +.duration { color: Colors.primary; font-size: 20px; } diff --git a/app/client/web/src/ring/Ring.tsx b/app/client/web/src/ring/Ring.tsx index 72092bbe..cd763068 100644 --- a/app/client/web/src/ring/Ring.tsx +++ b/app/client/web/src/ring/Ring.tsx @@ -5,7 +5,7 @@ import { Card as Contact } from '../card/Card'; import { Colors } from '../constants/Colors'; import { modals } from '@mantine/modals' import { Loader, Image, Text, ActionIcon } from '@mantine/core' -import { IconEyeX, IconPhone, IconPhoneOff, IconMicrophone, IconMicrophoneOff } from '@tabler/icons-react' +import { IconEyeX, IconPhone, IconPhoneOff, IconArrowsMaximize, IconMicrophone, IconMicrophoneOff } from '@tabler/icons-react' export function Ring() { const { state, actions } = useRing(); @@ -99,20 +99,64 @@ export function Ring() { } const calls = state.calls.map((ring, index) => { - const { name, handle, node, imageUrl } = ring.card; - const ignoreButton = ignore(ring)} color={Colors.pending}> - const declineButton =
decline(ring)} color={Colors.offsync}>
- const acceptButton = accept(ring)} color={Colors.primary}> + const { callId, card } = ring; + const { name, handle, node, imageUrl } = card; + const ignoreButton = ignore(callId, card)} color={Colors.pending}> + const declineButton =
decline(callId, card)} color={Colors.offsync}>
+ const acceptButton = accept(callId, card)} color={Colors.primary}> return ( -
- -
+ ) }); return ( -
+
0) ? classes.active : classes.inactive}> + { state.calls.length > 0 && !accepting && !state.calling && ( +
+ { calls[0] } +
+ )} + { accepting && !state.calling && ( +
+ +
+ )} + { state.calling && ( +
+ + { state.audioEnabled && ( + + )} + { !state.audioEnabled && ( + + )} + + + + +
+ { state.calling.name && ( + { state.calling.name } + )} + { !state.calling.name && ( + { state.strings.name } + )} +
+
+ { state.connected && ( + { `${Math.floor(state.duration/60)}:${(state.duration % 60).toString().padStart(2, '0')}` } + )} + { !state.connected && ( + + )} +
+
+ +
+
+ )} +
); }