From 5d4d63c76d619045e31431500fa3878a4af6a035 Mon Sep 17 00:00:00 2001 From: Warrick Corfe-Tan Date: Wed, 22 Sep 2021 15:44:15 +1000 Subject: [PATCH] Adding partial UI for calls. --- ts/components/session/ActionsPanel.tsx | 4 + .../session/calling/CallContainer.tsx | 168 ++++++++++++++++++ ts/models/conversation.ts | 2 + 3 files changed, 174 insertions(+) create mode 100644 ts/components/session/calling/CallContainer.tsx diff --git a/ts/components/session/ActionsPanel.tsx b/ts/components/session/ActionsPanel.tsx index b2efb92c5..6d750d921 100644 --- a/ts/components/session/ActionsPanel.tsx +++ b/ts/components/session/ActionsPanel.tsx @@ -46,6 +46,7 @@ import { loadDefaultRooms } from '../../opengroup/opengroupV2/ApiUtil'; import { ActionPanelOnionStatusLight } from '../dialog/OnionStatusPathDialog'; import { switchHtmlToDarkTheme, switchHtmlToLightTheme } from '../../state/ducks/SessionTheme'; +import { CallContainer } from './calling/CallContainer'; const Section = (props: { type: SectionType; avatarPath?: string | null }) => { const ourNumber = useSelector(getOurNumber); const unreadMessageCount = useSelector(getUnreadMessageCount); @@ -286,6 +287,9 @@ export const ActionsPanel = () => { return ( <> + + +
diff --git a/ts/components/session/calling/CallContainer.tsx b/ts/components/session/calling/CallContainer.tsx new file mode 100644 index 000000000..3f2f8871d --- /dev/null +++ b/ts/components/session/calling/CallContainer.tsx @@ -0,0 +1,168 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; +import _ from 'underscore'; +import { ConversationModel } from '../../../models/conversation'; +// tslint:disable-next-line: no-submodule-imports +import { getConversationController } from '../../../session/conversations/ConversationController'; +import { SessionButton, SessionButtonColor } from '../SessionButton'; +import { SessionWrapperModal } from '../SessionWrapperModal'; + +export const CallWindow = styled.div` + position: absolute; + z-index: 9; + padding: 2rem; + top: 50vh; + left: 50vw; + transform: translate(-50%, -50%); + display: flex; + flex-direction: column; +`; + +// similar styling to modal header +const CallWindowHeader = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + + padding: $session-margin-lg; + + font-family: $session-font-default; + text-align: center; + line-height: 18px; + font-size: $session-font-md; + font-weight: 700; +`; + +// TODO: Add proper styling for this +const VideoContainer = styled.div` + width: 200px; + height: 200px; +`; + +const CallWindowInner = styled.div` + position: relative; + background-color: pink; + border: 1px solid #d3d3d3; + text-align: center; + padding: 2rem; + display: flex; + flex-direction: column; +`; + +const CallWindowControls = styled.div` + position: absolute; + top: 100%; + left: 0; + width: 100%; + /* background: green; */ + padding: 5px; + transform: translateY(-100%); +`; + +// type WindowPositionType = { +// top: string; +// left: string; +// } | null; + +type CallStateType = 'connecting' | 'ongoing' | 'incoming' | null + +export const CallContainer = () => { + const conversations = getConversationController().getConversations(); + + // TODO: + /** + * Add mute input, deafen, end call, possibly add person to call + * duration - look at how duration calculated for recording. + */ + + const [connectionState, setConnectionState] = useState('incoming'); + // const [callWindowPosition, setCallWindowPosition] = useState(null) + + // picking a conversation at random to test with + let randConvo = _.sample(conversations) as ConversationModel; + randConvo.callState = 'incoming'; + console.warn({ randConvo }); + + const firstCallingConvo = _.first(conversations.filter(convo => convo.callState !== undefined)); + + //#region input handlers + const handleAcceptIncomingCall = () => { + console.warn('accept call'); + + if (firstCallingConvo) { + setConnectionState('connecting'); + firstCallingConvo.callState = 'connecting'; + + // some delay + setConnectionState('ongoing'); + firstCallingConvo.callState = 'ongoing'; + } + // set conversationState = setting up + } + + const handleDeclineIncomingCall = () => { + // set conversation.callState = null or undefined + // close the modal + if (firstCallingConvo) { + firstCallingConvo.callState = undefined; + } + console.warn('declined call'); + } + + const handleEndCall = () => { + // call method to end call connection + console.warn("ending the call"); + } + + const handleMouseDown = () => { + // reposition call window + } + //#endregion + + return ( + <> + {connectionState === 'connecting' ? + 'connecting...' + : null + } + {connectionState === 'ongoing' ? + + + + { firstCallingConvo ? firstCallingConvo.getName() : 'Group name not found'} + + + + + + + + + : null + } + + {!connectionState ? + + 'none' + + : null + } + + {connectionState === 'incoming' ? + +
+ + +
+
+ : null + } + + ); +}; + diff --git a/ts/models/conversation.ts b/ts/models/conversation.ts index dfc68c9df..ac79ac978 100644 --- a/ts/models/conversation.ts +++ b/ts/models/conversation.ts @@ -184,6 +184,8 @@ export class ConversationModel extends Backbone.Model { public markRead: (newestUnreadDate: number, providedOptions?: any) => Promise; public initialPromise: any; + public callState: 'incoming' | 'connecting' | 'ongoing' | 'none' | undefined; + private typingRefreshTimer?: NodeJS.Timeout | null; private typingPauseTimer?: NodeJS.Timeout | null; private typingTimer?: NodeJS.Timeout | null;