From 2ca6f54bfa37ae84855f58fcdf1e2db682a60c67 Mon Sep 17 00:00:00 2001 From: HariharanIT Date: Wed, 15 Oct 2025 11:14:35 +0530 Subject: [PATCH 1/5] Updated the username input validation on join button action --- .../components/precall/joinCallBtn.native.tsx | 9 ++- .../src/components/precall/joinCallBtn.tsx | 9 ++- .../precall/joinWaitingRoomBtn.native.tsx | 11 ++- .../components/precall/joinWaitingRoomBtn.tsx | 11 ++- template/src/components/precall/textInput.tsx | 67 +++++++++++++------ .../src/components/precall/usePreCall.tsx | 7 ++ 6 files changed, 82 insertions(+), 32 deletions(-) diff --git a/template/src/components/precall/joinCallBtn.native.tsx b/template/src/components/precall/joinCallBtn.native.tsx index ce2971160..487e03f33 100644 --- a/template/src/components/precall/joinCallBtn.native.tsx +++ b/template/src/components/precall/joinCallBtn.native.tsx @@ -33,7 +33,7 @@ export interface PreCallJoinCallBtnProps { const JoinCallBtn = (props: PreCallJoinCallBtnProps) => { const {rtcProps} = useContext(PropsContext); - const {setCallActive} = usePreCall(); + const {setCallActive, setIsNameIsEmpty} = usePreCall(); const username = useGetName(); const {isJoinDataFetched} = useRoomInfo(); const joinRoomButton = @@ -58,12 +58,17 @@ const JoinCallBtn = (props: PreCallJoinCallBtnProps) => { }, [rtcProps?.role]); const onSubmit = () => { + if (!username || (username && username?.trim() === '')) { + setIsNameIsEmpty(true); + return; + } + setIsNameIsEmpty(false); setCallActive(true); }; const title = buttonText; const onPress = () => onSubmit(); - const disabled = !isJoinDataFetched || username === ''; + const disabled = !isJoinDataFetched; return props?.render ? ( props.render(onPress, title, disabled) ) : ( diff --git a/template/src/components/precall/joinCallBtn.tsx b/template/src/components/precall/joinCallBtn.tsx index 56ba22fb2..5dcdf4992 100644 --- a/template/src/components/precall/joinCallBtn.tsx +++ b/template/src/components/precall/joinCallBtn.tsx @@ -42,7 +42,7 @@ export interface PreCallJoinCallBtnProps { const JoinCallBtn = (props: PreCallJoinCallBtnProps) => { const {rtcProps} = useContext(PropsContext); - const {setCallActive} = usePreCall(); + const {setCallActive, setIsNameIsEmpty} = usePreCall(); const username = useGetName(); const setUsername = useSetName(); const {isJoinDataFetched} = useRoomInfo(); @@ -59,6 +59,11 @@ const JoinCallBtn = (props: PreCallJoinCallBtnProps) => { ); const onSubmit = () => { + if (!username || (username && username?.trim() === '')) { + setIsNameIsEmpty(true); + return; + } + setIsNameIsEmpty(false); logger.log( LogSource.Internals, 'PRECALL_SCREEN', @@ -95,7 +100,7 @@ const JoinCallBtn = (props: PreCallJoinCallBtnProps) => { const title = buttonText; const onPress = () => onSubmit(); - const disabled = !isJoinDataFetched || username?.trim() === ''; + const disabled = !isJoinDataFetched; return props?.render ? ( props.render(onPress, title, disabled) ) : ( diff --git a/template/src/components/precall/joinWaitingRoomBtn.native.tsx b/template/src/components/precall/joinWaitingRoomBtn.native.tsx index 5abb48992..bf952aa0f 100644 --- a/template/src/components/precall/joinWaitingRoomBtn.native.tsx +++ b/template/src/components/precall/joinWaitingRoomBtn.native.tsx @@ -58,7 +58,7 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { const waitingRoomUsersInCallText = useString(waitingRoomUsersInCall); let pollingTimeout = React.useRef(null); const {rtcProps} = useContext(PropsContext); - const {setCallActive, callActive} = usePreCall(); + const {setCallActive, callActive, setIsNameIsEmpty} = usePreCall(); const username = useGetName(); const {isJoinDataFetched, isInWaitingRoom} = useRoomInfo(); const {setRoomInfo} = useSetRoomInfo(); @@ -212,6 +212,11 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { }; const onSubmit = () => { + if (!username || (username && username?.trim() === '')) { + setIsNameIsEmpty(true); + return; + } + setIsNameIsEmpty(false); shouldWaitingRoomPoll = true; // Enter waiting rooom; setRoomInfo(prev => { @@ -232,8 +237,8 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { const title = buttonText; const onPress = () => onSubmit(); const disabled = $config.ENABLE_WAITING_ROOM_AUTO_REQUEST - ? !hasHostJoined || isInWaitingRoom || username?.trim() === '' - : isInWaitingRoom || username?.trim() === ''; + ? !hasHostJoined || isInWaitingRoom + : isInWaitingRoom; return props?.render ? ( props.render(onPress, title, disabled) ) : ( diff --git a/template/src/components/precall/joinWaitingRoomBtn.tsx b/template/src/components/precall/joinWaitingRoomBtn.tsx index 8d5be8efd..1e6301810 100644 --- a/template/src/components/precall/joinWaitingRoomBtn.tsx +++ b/template/src/components/precall/joinWaitingRoomBtn.tsx @@ -69,7 +69,7 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { const waitingRoomUsersInCallText = useString(waitingRoomUsersInCall); let pollingTimeout = React.useRef(null); const {rtcProps} = useContext(PropsContext); - const {setCallActive, callActive} = usePreCall(); + const {setCallActive, callActive, setIsNameIsEmpty} = usePreCall(); const username = useGetName(); const setUsername = useSetName(); const {isJoinDataFetched, isInWaitingRoom} = useRoomInfo(); @@ -236,6 +236,11 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { }; const onSubmit = () => { + if (!username || (username && username?.trim() === '')) { + setIsNameIsEmpty(true); + return; + } + setIsNameIsEmpty(false); shouldWaitingRoomPoll = true; setUsername(username.trim()); //setCallActive(true); @@ -281,8 +286,8 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { const title = buttonText; const onPress = () => onSubmit(); const disabled = $config.ENABLE_WAITING_ROOM_AUTO_REQUEST - ? !hasHostJoined || isInWaitingRoom || username?.trim() === '' - : isInWaitingRoom || username?.trim() === ''; + ? !hasHostJoined || isInWaitingRoom + : isInWaitingRoom; return props?.render ? ( props.render(onPress, title, disabled) ) : ( diff --git a/template/src/components/precall/textInput.tsx b/template/src/components/precall/textInput.tsx index 22f7e2f2f..eea74a3d6 100644 --- a/template/src/components/precall/textInput.tsx +++ b/template/src/components/precall/textInput.tsx @@ -11,7 +11,7 @@ */ import React from 'react'; -import {TextStyle} from 'react-native'; +import {TextStyle, Text} from 'react-native'; import TextInput from '../../atoms/TextInput'; import {useString} from '../../utils/useString'; import {useRoomInfo} from '../room-info/useRoomInfo'; @@ -25,6 +25,7 @@ import { precallNameInputPlaceholderText, precallYouAreJoiningAsHeading, } from '../../language/default-labels/precallScreenLabels'; +import {usePreCall} from './usePreCall'; export interface PreCallTextInputProps { labelStyle?: TextStyle; @@ -39,30 +40,52 @@ const PreCallTextInput = (props?: PreCallTextInputProps) => { const username = useGetName(); const setUsername = useSetName(); const {isJoinDataFetched, isInWaitingRoom} = useRoomInfo(); + const {isNameIsEmpty, setIsNameIsEmpty} = usePreCall(); const {isDesktop = false, isOnPrecall = false} = props; return ( - setUsername(text ? text : '')} - onSubmitEditing={() => {}} - placeholder={isJoinDataFetched ? placeHolder : fetchingNamePlaceholder} - editable={!isInWaitingRoom && isJoinDataFetched} - /> + <> + { + setUsername(text ? text : ''); + if (text && text.trim() === '') { + setIsNameIsEmpty(true); + } else { + setIsNameIsEmpty(false); + } + }} + onSubmitEditing={() => {}} + placeholder={isJoinDataFetched ? placeHolder : fetchingNamePlaceholder} + editable={!isInWaitingRoom && isJoinDataFetched} + style={isNameIsEmpty ? {borderColor: $config.SEMANTIC_ERROR} : {}} + /> + {isNameIsEmpty && ( + + {'Name is required'} + + )} + ); }; diff --git a/template/src/components/precall/usePreCall.tsx b/template/src/components/precall/usePreCall.tsx index 6b468a167..e3ae6a8c1 100644 --- a/template/src/components/precall/usePreCall.tsx +++ b/template/src/components/precall/usePreCall.tsx @@ -29,6 +29,8 @@ export interface PreCallContextInterface { setSpeakerAvailable: React.Dispatch>; isPermissionRequested: boolean; setIsPermissionRequested: React.Dispatch>; + isNameIsEmpty: boolean; + setIsNameIsEmpty: React.Dispatch>; } const PreCallContext = createContext({ @@ -42,6 +44,8 @@ const PreCallContext = createContext({ setSpeakerAvailable: () => {}, isPermissionRequested: false, setIsPermissionRequested: () => {}, + isNameIsEmpty: false, + setIsNameIsEmpty: () => {}, }); interface PreCallProviderProps { @@ -54,6 +58,7 @@ const PreCallProvider = (props: PreCallProviderProps) => { const roomInfo = useRoomInfo(); const {deviceList} = useContext(DeviceContext); const setUsername = useSetName(); + const [isNameIsEmpty, setIsNameIsEmpty] = useState(false); const [isCameraAvailable, setCameraAvailable] = useState(false); const [isMicAvailable, setMicAvailable] = useState(false); const [isSpeakerAvailable, setSpeakerAvailable] = useState(false); @@ -69,6 +74,8 @@ const PreCallProvider = (props: PreCallProviderProps) => { setSpeakerAvailable, isPermissionRequested, setIsPermissionRequested, + isNameIsEmpty, + setIsNameIsEmpty, }; useEffect(() => { From f254d808b1ddfd6b9960661bedbaf4627c75b02b Mon Sep 17 00:00:00 2001 From: HariharanIT Date: Wed, 15 Oct 2025 13:39:10 +0530 Subject: [PATCH 2/5] Updated the input padding to match dropdown size --- template/src/atoms/Input.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/template/src/atoms/Input.tsx b/template/src/atoms/Input.tsx index c19d2380e..3fea6cf63 100644 --- a/template/src/atoms/Input.tsx +++ b/template/src/atoms/Input.tsx @@ -60,7 +60,7 @@ const styles = StyleSheet.create({ // height: 60, //causes text cut off in android width: '100%', borderWidth: 1, - paddingVertical: 21, + paddingVertical: 12, paddingHorizontal: 16, borderColor: $config.INPUT_FIELD_BORDER_COLOR, color: $config.FONT_COLOR, @@ -71,6 +71,7 @@ const styles = StyleSheet.create({ ...Platform.select({ web: { outlineStyle: 'none', + lineHeight: '26px', }, }), }, From c8680d4d35f4b51263b19542cb1e6a8a518c3ccd Mon Sep 17 00:00:00 2001 From: HariharanIT Date: Wed, 15 Oct 2025 13:39:25 +0530 Subject: [PATCH 3/5] Added waiting room sdk event emitting --- .../src/components/precall/joinWaitingRoomBtn.tsx | 15 ++++++++++++++- template/src/utils/SdkEvents.ts | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/template/src/components/precall/joinWaitingRoomBtn.tsx b/template/src/components/precall/joinWaitingRoomBtn.tsx index 1e6301810..80362ea4b 100644 --- a/template/src/components/precall/joinWaitingRoomBtn.tsx +++ b/template/src/components/precall/joinWaitingRoomBtn.tsx @@ -45,6 +45,8 @@ import { waitingRoomHostNotJoined, waitingRoomUsersInCall, } from '../../language/default-labels/videoCallScreenLabels'; +import SDKEvents from '../../utils/SdkEvents'; +import isSDK from '../../utils/isSDK'; const audio = new Audio( 'https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3', @@ -150,6 +152,10 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { }); if (approved) { + if (isSDK()) { + //emit SDKEvent waiting-room-approval-granted + SDKEvents.emit('waiting-room-approval-granted'); + } setRoomInfo(prev => { return { ...prev, @@ -189,6 +195,10 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { }; }); } else { + if (isSDK()) { + //emit SDKEvent waiting-room-approval-rejected + SDKEvents.emit('waiting-room-approval-rejected'); + } setRoomInfo(prev => { return { ...prev, @@ -257,7 +267,10 @@ const JoinWaitingRoomBtn = (props: PreCallJoinWaitingRoomBtnProps) => { // join request API to server, server will send RTM message to all hosts regarding request from this user, requestServerToJoinRoom(); - + if (isSDK()) { + //emit SDKEvent waiting for approval + SDKEvents.emit('waiting-room-approval-requested'); + } // Play a sound to avoid autoblocking in safari if (isWebInternal() || isMobileOrTablet()) { audio.volume = 0; diff --git a/template/src/utils/SdkEvents.ts b/template/src/utils/SdkEvents.ts index 0bb6a963c..822f9eba0 100644 --- a/template/src/utils/SdkEvents.ts +++ b/template/src/utils/SdkEvents.ts @@ -51,6 +51,9 @@ export interface userEventsMapInterface { 'token-refreshed': () => void; 'rtc-user-removed': (uid: UidType, channel: string) => void; unauthorized: (errorMessage) => void; + 'waiting-room-approval-requested': () => void; + 'waiting-room-approval-granted': () => void; + 'waiting-room-approval-rejected': () => void; } const SDKEvents = createNanoEvents(); From 4ed6dbb592f2eecc1aeda2fd50b4157ce0d01985 Mon Sep 17 00:00:00 2001 From: HariharanIT Date: Wed, 15 Oct 2025 14:43:48 +0530 Subject: [PATCH 4/5] Updated the core/cli version --- template/defaultConfig.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/template/defaultConfig.js b/template/defaultConfig.js index 19d8fd349..d0d47d120 100644 --- a/template/defaultConfig.js +++ b/template/defaultConfig.js @@ -77,8 +77,8 @@ const DefaultConfig = { CHAT_ORG_NAME: '', CHAT_APP_NAME: '', CHAT_URL: '', - CLI_VERSION: '3.1.8-3', - CORE_VERSION: '4.1.8-3', + CLI_VERSION: '3.1.8-4', + CORE_VERSION: '4.1.8-4', DISABLE_LANDSCAPE_MODE: false, STT_AUTO_START: false, CLOUD_RECORDING_AUTO_START: false, From 49944fa5767803612d2d74ba7efcfcbf2ddbbb37 Mon Sep 17 00:00:00 2001 From: HariharanIT Date: Wed, 15 Oct 2025 14:45:12 +0530 Subject: [PATCH 5/5] 4.1.8-4 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0868a06fb..127c7dad0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { "name": "agora-appbuilder-core", - "version": "4.1.8-3", + "version": "4.1.8-4", "lockfileVersion": 1 } diff --git a/package.json b/package.json index 8f160cae9..afbfd336e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agora-appbuilder-core", - "version": "4.1.8-3", + "version": "4.1.8-4", "description": "React Native template for RTE app builder", "main": "index.js", "files": [