From 1f5d2c82a715c49dda9d7ebe52f0a08ee3173ffb Mon Sep 17 00:00:00 2001 From: Kristian Martinoski Date: Wed, 27 Nov 2024 12:12:17 +0100 Subject: [PATCH 1/4] fix: add disable state to call controls to prevent multiple call actions --- .../components/Call/CallControls/AcceptCallButton.tsx | 8 +++++++- .../components/Call/CallControls/RejectCallButton.tsx | 8 +++++++- .../dogfood/src/screens/Call/JoinCallScreen.tsx | 11 +++++++++-- .../react-native/dogfood/src/translations/en.json | 3 ++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx index 03188e46ea..6ecce1bae2 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/AcceptCallButton.tsx @@ -1,6 +1,6 @@ import { useCall } from '@stream-io/video-react-bindings'; import { getLogger } from '@stream-io/video-client'; -import React from 'react'; +import React, { useState } from 'react'; import { CallControlsButton } from './CallControlsButton'; import { IconWrapper, Phone } from '../../../icons'; import { useTheme } from '../../../contexts/ThemeContext'; @@ -38,7 +38,10 @@ export const AcceptCallButton = ({ acceptCallButton, }, } = useTheme(); + const [isLoading, setIsLoading] = useState(false); + const acceptCallHandler = async () => { + setIsLoading(true); if (onPressHandler) { onPressHandler(); return; @@ -51,6 +54,8 @@ export const AcceptCallButton = ({ } catch (error) { const logger = getLogger(['AcceptCallButton']); logger('error', 'Error joining Call', error); + } finally { + setIsLoading(false); } }; @@ -60,6 +65,7 @@ export const AcceptCallButton = ({ color={colors.buttonSuccess} size={buttonSizes.md} style={acceptCallButton} + disabled={isLoading} > diff --git a/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx b/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx index a27c009ce4..51f93bff78 100644 --- a/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx +++ b/packages/react-native-sdk/src/components/Call/CallControls/RejectCallButton.tsx @@ -1,5 +1,5 @@ import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings'; -import React from 'react'; +import React, { useState } from 'react'; import { CallControlsButton } from './CallControlsButton'; import { IconWrapper, PhoneDown } from '../../../icons'; import { CallingState, getLogger } from '@stream-io/video-client'; @@ -57,7 +57,10 @@ export const RejectCallButton = ({ variants: { buttonSizes, iconSizes }, }, } = useTheme(); + const [isLoading, setIsLoading] = useState(false); + const rejectCallHandler = async () => { + setIsLoading(true); if (onPressHandler) { onPressHandler(); return; @@ -73,6 +76,8 @@ export const RejectCallButton = ({ } catch (error) { const logger = getLogger(['RejectCallButton']); logger('error', 'Error rejecting Call', error); + } finally { + setIsLoading(false); } }; @@ -84,6 +89,7 @@ export const RejectCallButton = ({ // TODO: check what to do about this random style prop // svgContainerStyle={theme.icon.lg} style={rejectCallButton} + disabled={isLoading} > diff --git a/sample-apps/react-native/dogfood/src/screens/Call/JoinCallScreen.tsx b/sample-apps/react-native/dogfood/src/screens/Call/JoinCallScreen.tsx index 6d4e5fe1f3..ffbb17bea3 100644 --- a/sample-apps/react-native/dogfood/src/screens/Call/JoinCallScreen.tsx +++ b/sample-apps/react-native/dogfood/src/screens/Call/JoinCallScreen.tsx @@ -32,8 +32,10 @@ const JoinCallScreen = () => { const { t } = useI18n(); const orientation = useOrientation(); const styles = useStyles(); + const [isLoading, setIsLoading] = useState(false); const startCallHandler = useCallback(async () => { + setIsLoading(true); let ringingUserIds = !ringingUserIdsText ? ringingUsers : ringingUserIdsText.split(','); @@ -65,6 +67,8 @@ const JoinCallScreen = () => { Alert.alert('Error calling users', error.message); } console.log('Failed to createCall', error); + } finally { + setIsLoading(false); } }, [ringingUserIdsText, ringingUsers, videoClient, userId]); @@ -85,6 +89,9 @@ const JoinCallScreen = () => { flexDirection: orientation === 'landscape' ? 'row' : 'column', }; + const startCallDisabled = + (ringingUserIdsText === '' && ringingUsers.length === 0) || isLoading; + return ( { style={styles.textInputStyle} />