diff --git a/template/customization-api/utils.ts b/template/customization-api/utils.ts index 5f0cd3eab..68ac9227e 100644 --- a/template/customization-api/utils.ts +++ b/template/customization-api/utils.ts @@ -35,3 +35,4 @@ export {default as useLocalAudio} from '../src/utils/useLocalAudio'; export {default as useLocalVideo} from '../src/utils/useLocalVideo'; export type {LanguageType} from '../src/subComponents/caption/utils'; export {default as useSpeechToText} from '../src/utils/useSpeechToText'; +export {default as useChatLogin} from '../src/utils/useChatLogin'; diff --git a/template/src/SDKAppWrapper.tsx b/template/src/SDKAppWrapper.tsx index 5caf375ef..e7028d7f2 100644 --- a/template/src/SDKAppWrapper.tsx +++ b/template/src/SDKAppWrapper.tsx @@ -21,13 +21,13 @@ export interface AppBuilderSdkApiInterface { joinRoom: ( roomDetails: string | meetingData, userName?: string, - preference?: {disableShareTile: boolean}, + preference?: {disableShareTile?: boolean; preventChatAutoLogin?: boolean}, ) => Promise; joinPrecall: ( roomDetails: string | meetingData, userName?: string, skipPrecall?: boolean, - preference?: {disableShareTile: boolean}, + preference?: {disableShareTile?: boolean; preventChatAutoLogin?: boolean}, ) => Promise< [ meetingData, @@ -73,7 +73,7 @@ export const AppBuilderSdkApi: AppBuilderSdkApiInterface = { logger.log(LogSource.SDK, 'Event', 'emiting event for joinRoom - join', { room: roomDetails, userName: userName, - preference: preference + preference: preference, }); return await SDKMethodEventsManager.emit( 'join', @@ -87,7 +87,7 @@ export const AppBuilderSdkApi: AppBuilderSdkApiInterface = { logger.log(LogSource.SDK, 'Event', 'emiting event for joinPrecall - join', { room: roomDetails, userName: userName, - preference: preference + preference: preference, }); if (!$config.PRECALL) { logger.error( diff --git a/template/src/components/SdkApiContext.tsx b/template/src/components/SdkApiContext.tsx index 8ee3918f2..f4aa487a6 100644 --- a/template/src/components/SdkApiContext.tsx +++ b/template/src/components/SdkApiContext.tsx @@ -27,7 +27,10 @@ type SdkApiContextInterface = { meetingDetails?: Partial; userName: string; skipPrecall: boolean; - preference: {disableShareTile: boolean}; + preference: { + disableShareTile?: boolean; + preventChatAutoLogin?: boolean; + }; promise: extractPromises<_InternalSDKMethodEventsMap['join']>; } | { diff --git a/template/src/components/chat-messages/useChatMessages.tsx b/template/src/components/chat-messages/useChatMessages.tsx index 3f3cdec8c..556cf8c2c 100644 --- a/template/src/components/chat-messages/useChatMessages.tsx +++ b/template/src/components/chat-messages/useChatMessages.tsx @@ -116,6 +116,7 @@ export interface ChatOption { file_name: string; file_url: string; from_platform?: string; + channel?: string; }; url?: string; } diff --git a/template/src/components/chat/chatConfigure.native.tsx b/template/src/components/chat/chatConfigure.native.tsx index 24cb101b5..0bd1def81 100644 --- a/template/src/components/chat/chatConfigure.native.tsx +++ b/template/src/components/chat/chatConfigure.native.tsx @@ -23,6 +23,11 @@ import {timeNow} from '../../rtm/utils'; import Share from 'react-native-share'; import RNFetchBlob from 'rn-fetch-blob'; import {logger, LogSource} from '../../logger/AppBuilderLogger'; +import LocalEventEmitter, { + LocalEventsEnum, +} from '../../rtm-events-api/LocalEvents'; +import events from '../../rtm-events-api'; +import {EventNames} from '../../rtm-events'; interface ChatMessageAttributes { file_ext?: string; @@ -34,6 +39,7 @@ interface ChatMessageAttributes { interface chatConfigureContextInterface { open: boolean; setOpen: React.Dispatch>; + allowChatLogin: boolean; sendChatSDKMessage: ( option: ChatOption, callback: ChatMessageStatusCallback, @@ -51,6 +57,7 @@ export const chatConfigureContext = createContext({ open: false, setOpen: () => {}, + allowChatLogin: false, sendChatSDKMessage: () => {}, deleteChatUser: () => {}, downloadAttachment: () => {}, @@ -59,16 +66,19 @@ export const chatConfigureContext = const ChatConfigure = ({children}) => { const [open, setOpen] = useState(false); - const {data} = useRoomInfo(); + const {data, roomPreference} = useRoomInfo(); const connRef = React.useRef(null); - const {defaultContent} = useContent(); - const defaultContentRef = React.useRef(defaultContent); + const chatClient = ChatClient.getInstance(); const chatManager = chatClient.chatManager; const localUid = data?.uid?.toString(); const agoraToken = data?.chat?.user_token; const {store} = React.useContext(StorageContext); + const [allowChatLogin, setAllowChatLogin] = useState( + () => !roomPreference.preventChatAutoLogin, + ); + const { addMessageToPrivateStore, showMessageNotification, @@ -77,29 +87,54 @@ const ChatConfigure = ({children}) => { removeMessageFromPrivateStore, } = useChatMessages(); - React.useEffect(() => { - defaultContentRef.current = defaultContent; - }, [defaultContent]); + const enableChatLoginCallback = () => { + console.warn('allow chat login callback', allowChatLogin); + setAllowChatLogin(true); + }; + + const logout = async () => { + try { + await chatClient?.logout(); + console.warn('chat logout success'); + logger.log( + LogSource.Internals, + 'CHAT', + `Logged out User ${localUid} from Agora Chat Server`, + ); + } catch (error) { + console.warn('logout failed'); + logger.log( + LogSource.Internals, + 'CHAT', + `Failed Logging out User ${localUid} from Agora Chat Server`, + ); + } + }; + + const enableChatLogoutCallback = async () => { + console.warn('allow chat logout callback', allowChatLogin); + setAllowChatLogin(false); + await logout(); + }; useEffect(() => { - const logout = async () => { - try { - await chatClient.logout(); - console.warn('logout success'); - logger.log( - LogSource.Internals, - 'CHAT', - `Logged out User ${localUid} from Agora Chat Server`, - ); - } catch (error) { - console.warn('logout failed'); - logger.log( - LogSource.Internals, - 'CHAT', - `Failed Logging out User ${localUid} from Agora Chat Server`, - ); - } - }; + // Handle Chat login for self and other users + LocalEventEmitter.on( + LocalEventsEnum.ENABLE_CHAT_LOGIN, + enableChatLoginCallback, + ); + events.on(EventNames.ENABLE_CHAT_LOGIN, () => { + enableChatLoginCallback(); + }); + + LocalEventEmitter.on( + LocalEventsEnum.ENABLE_CHAT_LOGOUT, + enableChatLogoutCallback, + ); + events.on(EventNames.ENABLE_CHAT_LOGOUT, () => { + enableChatLogoutCallback(); + }); + const setupMessageListener = () => { const msgListerner: ChatMessageEventListener = { onMessagesRecalled: (messages: ChatMessage[]) => { @@ -322,12 +357,26 @@ const ChatConfigure = ({children}) => { console.warn('chat sdk: init error', error); } }; + if (allowChatLogin) { + initializeChatSDK(); + } else { + console.warn('delay chat login'); + } - initializeChatSDK(); return () => { logout(); + LocalEventEmitter.off( + LocalEventsEnum.ENABLE_CHAT_LOGIN, + enableChatLoginCallback, + ); + events.off(EventNames.ENABLE_CHAT_LOGIN, enableChatLoginCallback); + LocalEventEmitter.off( + LocalEventsEnum.ENABLE_CHAT_LOGOUT, + enableChatLogoutCallback, + ); + events.off(EventNames.ENABLE_CHAT_LOGOUT, enableChatLogoutCallback); }; - }, []); + }, [allowChatLogin]); const sendChatSDKMessage = ( option: ChatOption, @@ -489,6 +538,7 @@ const ChatConfigure = ({children}) => { value={{ open, setOpen, + allowChatLogin, deleteChatUser, sendChatSDKMessage, downloadAttachment, diff --git a/template/src/components/chat/chatConfigure.tsx b/template/src/components/chat/chatConfigure.tsx index 2da799616..28955a2ee 100644 --- a/template/src/components/chat/chatConfigure.tsx +++ b/template/src/components/chat/chatConfigure.tsx @@ -2,6 +2,8 @@ import {createHook} from 'customization-implementation'; import React, {createContext, useState, useEffect} from 'react'; import AgoraChat from 'agora-chat'; import {useRoomInfo} from '../room-info/useRoomInfo'; +import events from '../../rtm-events-api'; +import {EventNames} from '../../rtm-events'; import {UidType, useContent} from 'customization-api'; import { @@ -18,6 +20,9 @@ import { useChatUIControls, } from '../../components/chat-ui/useChatUIControls'; import {logger, LogSource} from '../../logger/AppBuilderLogger'; +import LocalEventEmitter, { + LocalEventsEnum, +} from '../../rtm-events-api/LocalEvents'; export interface FileObj { url: string; @@ -29,6 +34,7 @@ export interface FileObj { interface chatConfigureContextInterface { open: boolean; setOpen: React.Dispatch>; + allowChatLogin: boolean; sendChatSDKMessage: (option: ChatOption, messageStatusCallback?: any) => void; deleteChatUser: () => void; downloadAttachment: (fileName: string, fileUrl: string) => void; @@ -44,6 +50,7 @@ export const chatConfigureContext = createContext({ open: false, setOpen: () => {}, + allowChatLogin: false, sendChatSDKMessage: () => {}, deleteChatUser: () => {}, downloadAttachment: () => {}, @@ -53,12 +60,20 @@ export const chatConfigureContext = const ChatConfigure = ({children}) => { const [open, setOpen] = useState(false); - const {data} = useRoomInfo(); + const {data, roomPreference} = useRoomInfo(); + const [allowChatLogin, setAllowChatLogin] = useState( + () => !roomPreference.preventChatAutoLogin, + ); + + // exponse onClick Chat so that this can be set truel + //const allowChatLogin = !roomPreference?.preventChatAutoLogin; + logger.debug(LogSource.Internals, 'CHAT', `Allow Chat Login`, allowChatLogin); + const connRef = React.useRef(null); - const {defaultContent} = useContent(); + const {privateChatUser, setUploadStatus, setUploadedFiles, uploadedFiles} = useChatUIControls(); - const defaultContentRef = React.useRef(defaultContent); + const { addMessageToPrivateStore, showMessageNotification, @@ -68,13 +83,39 @@ const ChatConfigure = ({children}) => { } = useChatMessages(); const {store} = React.useContext(StorageContext); - React.useEffect(() => { - defaultContentRef.current = defaultContent; - }, [defaultContent]); - let newConn = null; + const enableChatLoginCallback = () => { + logger.debug(LogSource.Internals, 'CHAT', `enable chat login callback`); + setAllowChatLogin(true); + }; + + const enableChatLogoutCallback = () => { + logger.debug(LogSource.Internals, 'CHAT', `enable chat logout callback`); + setAllowChatLogin(false); + if (connRef.current) { + connRef.current.close(); + } + }; + useEffect(() => { + // Handle Chat login for self and other users + LocalEventEmitter.on( + LocalEventsEnum.ENABLE_CHAT_LOGIN, + enableChatLoginCallback, + ); + events.on(EventNames.ENABLE_CHAT_LOGIN, () => { + enableChatLoginCallback(); + }); + + LocalEventEmitter.on( + LocalEventsEnum.ENABLE_CHAT_LOGOUT, + enableChatLogoutCallback, + ); + events.on(EventNames.ENABLE_CHAT_LOGOUT, () => { + enableChatLogoutCallback(); + }); + const initializeChatSDK = async () => { try { // disable Chat SDK logs @@ -307,16 +348,30 @@ const ChatConfigure = ({children}) => { }; // initializing chat sdk - initializeChatSDK(); + if (allowChatLogin) { + initializeChatSDK(); + } return () => { - newConn.close(); - logger.log( - LogSource.Internals, - 'CHAT', - `Logging out User ${data.uid} from Agora Chat Server`, + if (newConn) { + newConn.close(); + logger.log( + LogSource.Internals, + 'CHAT', + `Logging out User ${data.uid} from Agora Chat Server`, + ); + } + LocalEventEmitter.off( + LocalEventsEnum.ENABLE_CHAT_LOGIN, + enableChatLoginCallback, + ); + events.off(EventNames.ENABLE_CHAT_LOGIN, enableChatLoginCallback); + LocalEventEmitter.off( + LocalEventsEnum.ENABLE_CHAT_LOGOUT, + enableChatLogoutCallback, ); + events.off(EventNames.ENABLE_CHAT_LOGOUT, enableChatLogoutCallback); }; - }, []); + }, [allowChatLogin]); const sendChatSDKMessage = ( option: ChatOption, @@ -492,6 +547,7 @@ const ChatConfigure = ({children}) => { value={{ open, setOpen, + allowChatLogin, sendChatSDKMessage, deleteChatUser, downloadAttachment, diff --git a/template/src/components/room-info/useRoomInfo.tsx b/template/src/components/room-info/useRoomInfo.tsx index f174af73e..969521299 100644 --- a/template/src/components/room-info/useRoomInfo.tsx +++ b/template/src/components/room-info/useRoomInfo.tsx @@ -116,6 +116,7 @@ export const RoomInfoDefaultValue: RoomInfoContextInterface = { }, roomPreference: { disableShareTile: false, + preventChatAutoLogin: false, }, }; diff --git a/template/src/language/default-labels/videoCallScreenLabels.ts b/template/src/language/default-labels/videoCallScreenLabels.ts index 2d09c09e8..34c915ef4 100644 --- a/template/src/language/default-labels/videoCallScreenLabels.ts +++ b/template/src/language/default-labels/videoCallScreenLabels.ts @@ -202,6 +202,7 @@ export const chatPanelGroupTabText = 'chatPanelGroupTabText'; export const chatPanelPrivateTabText = 'chatPanelPrivateTabText'; export const groupChatWelcomeContent = 'groupChatWelcomeContent'; +export const chatUserNotLoggedIn = 'chatUserNotLogged'; export const peoplePanelHeaderText = 'peoplePanelHeaderText'; @@ -624,7 +625,7 @@ export interface I18nVideoCallScreenLabelsInterface { [chatPanelGroupTabText]?: I18nBaseType; [chatPanelPrivateTabText]?: I18nBaseType; - + [chatUserNotLoggedIn]?: I18nBaseType; [groupChatWelcomeContent]?: I18nConditionalType; [groupChatLiveInputPlaceHolderText]?: I18nBaseType; @@ -1011,6 +1012,7 @@ export const VideoCallScreenLabels: I18nVideoCallScreenLabelsInterface = { [chatPanelGroupTabText]: 'Public', [chatPanelPrivateTabText]: 'Private', + [chatUserNotLoggedIn]: 'You are currently not logged in Agora Chat', [groupChatWelcomeContent]: noMessage => noMessage diff --git a/template/src/rtm-events-api/LocalEvents.ts b/template/src/rtm-events-api/LocalEvents.ts index 209e3db2d..008183075 100644 --- a/template/src/rtm-events-api/LocalEvents.ts +++ b/template/src/rtm-events-api/LocalEvents.ts @@ -9,6 +9,8 @@ export enum LocalEventsEnum { WHITEBOARD_OFF = 'WHITEBOARD_OFF', MIC_CHANGED = 'MIC_CHANGED', CLEAR_WHITEBOARD = 'CLEAR_WHITEBOARD', + ENABLE_CHAT_LOGIN = 'ENABLE_CHAT_LOGIN', + ENABLE_CHAT_LOGOUT = 'ENABLE_CHAT_LOGOUT', } const LocalEventEmitter = new EventEmitter(); export default LocalEventEmitter; diff --git a/template/src/rtm-events/constants.ts b/template/src/rtm-events/constants.ts index 8e9f1344f..16205ce88 100644 --- a/template/src/rtm-events/constants.ts +++ b/template/src/rtm-events/constants.ts @@ -38,6 +38,8 @@ const WAITING_ROOM_STATUS_UPDATE = 'WAITING_ROOM_STATUS_UPDATE'; const WHITEBOARD_ACTIVE = 'WHITEBOARD_ACTIVE'; const BOARD_COLOR_CHANGED = 'BOARD_COLOR_CHANGED'; const WHITEBOARD_LAST_IMAGE_UPLOAD_POSITION = 'WHITEBOARD_L_I_U_P'; +const ENABLE_CHAT_LOGIN = 'ENABLE_CHAT_LOGIN'; +const ENABLE_CHAT_LOGOUT = 'ENABLE_CHAT_LOGOUT'; const EventNames = { RECORDING_STATE_ATTRIBUTE, @@ -58,6 +60,8 @@ const EventNames = { WHITEBOARD_ACTIVE, BOARD_COLOR_CHANGED, WHITEBOARD_LAST_IMAGE_UPLOAD_POSITION, + ENABLE_CHAT_LOGIN, + ENABLE_CHAT_LOGOUT, }; /** ***** EVENT NAMES ENDS ***** */ diff --git a/template/src/subComponents/ChatContainer.tsx b/template/src/subComponents/ChatContainer.tsx index 1d1396216..1bfa2a925 100644 --- a/template/src/subComponents/ChatContainer.tsx +++ b/template/src/subComponents/ChatContainer.tsx @@ -52,7 +52,9 @@ import { chatPanelUnreadMessageText, chatPanelUserOfflineText, groupChatWelcomeContent, + chatUserNotLoggedIn, } from '../language/default-labels/videoCallScreenLabels'; +import {useChatConfigure} from '../components/chat/chatConfigure'; /** * Chat container is the component which renders all the chat messages @@ -63,6 +65,7 @@ const ChatContainer = (props?: { chatBubble?: React.ComponentType; }) => { const info1 = useString(groupChatWelcomeContent); + const userLoginInfo = useString(chatUserNotLoggedIn); const [scrollToEnd, setScrollToEnd] = useState(false); const {dispatch} = useContext(DispatchContext); const [grpUnreadCount, setGrpUnreadCount] = useState(0); @@ -76,6 +79,7 @@ const ChatContainer = (props?: { const privateMessageStoreRef = useRef( privateMessageStore[privateChatUser]?.length, ); + const {allowChatLogin} = useChatConfigure(); const { setUnreadGroupMessageCount, unreadGroupMessageCount, @@ -207,6 +211,9 @@ const ChatContainer = (props?: { {info1(messageStore?.length ? false : true)} + {!allowChatLogin && ( + {userLoginInfo()} + )} {messageStore.map((message: any, index) => ( <> diff --git a/template/src/subComponents/ChatInput.native.tsx b/template/src/subComponents/ChatInput.native.tsx index e3a1d43dc..e28c20888 100644 --- a/template/src/subComponents/ChatInput.native.tsx +++ b/template/src/subComponents/ChatInput.native.tsx @@ -90,7 +90,7 @@ export const ChatTextInput = (props: ChatTextInputProps) => { } = useChatUIControls(); const {defaultContent} = useContent(); - const {sendChatSDKMessage} = useChatConfigure(); + const {sendChatSDKMessage, allowChatLogin} = useChatConfigure(); const {data} = useRoomInfo(); const [name] = useUserName(); const groupChatInputPlaceHolder = $config.EVENT_MODE @@ -177,6 +177,7 @@ export const ChatTextInput = (props: ChatTextInputProps) => { onChangeText={onChangeText} multiline={true} textAlignVertical="top" + editable={allowChatLogin} style={{ color: $config.FONT_COLOR, textAlign: 'left', diff --git a/template/src/subComponents/ChatInput.tsx b/template/src/subComponents/ChatInput.tsx index a9ee25856..9fee3f1dd 100644 --- a/template/src/subComponents/ChatInput.tsx +++ b/template/src/subComponents/ChatInput.tsx @@ -88,7 +88,8 @@ export const ChatTextInput = (props: ChatTextInputProps) => { setInputHeight, } = useChatUIControls(); const {defaultContent} = useContent(); - const {sendChatSDKMessage, uploadAttachment} = useChatConfigure(); + const {sendChatSDKMessage, uploadAttachment, allowChatLogin} = + useChatConfigure(); React.useEffect(() => { if (message.length === 0) { @@ -252,6 +253,7 @@ export const ChatTextInput = (props: ChatTextInputProps) => { onChangeText={onChangeText} textAlignVertical="top" scrollEnabled={true} + editable={allowChatLogin} style={{ color: $config.FONT_COLOR, textAlign: 'left', diff --git a/template/src/subComponents/chat/ChatAttachment.native.tsx b/template/src/subComponents/chat/ChatAttachment.native.tsx index 74f633dbf..b578d0387 100644 --- a/template/src/subComponents/chat/ChatAttachment.native.tsx +++ b/template/src/subComponents/chat/ChatAttachment.native.tsx @@ -48,7 +48,7 @@ interface ExtendedChatMessage extends ChatMessage { export const ChatAttachmentButton = (props: ChatAttachmentButtonProps) => { const {privateChatUser, setUploadStatus} = useChatUIControls(); - const {sendChatSDKMessage} = useChatConfigure(); + const {sendChatSDKMessage, allowChatLogin} = useChatConfigure(); const {data} = useRoomInfo(); const {addMessageToPrivateStore, addMessageToStore} = useChatMessages(); @@ -214,11 +214,12 @@ export const ChatAttachmentButton = (props: ChatAttachmentButtonProps) => { ) : ( { }, iconSize: 24, name: 'chat_attachment', - tintColor: $config.SECONDARY_ACTION_COLOR, + tintColor: !allowChatLogin + ? $config.SEMANTIC_NEUTRAL + : $config.SECONDARY_ACTION_COLOR, }} onPress={onPress} /> diff --git a/template/src/subComponents/chat/ChatAttachment.tsx b/template/src/subComponents/chat/ChatAttachment.tsx index c3d8dfb9d..e4a0b404e 100644 --- a/template/src/subComponents/chat/ChatAttachment.tsx +++ b/template/src/subComponents/chat/ChatAttachment.tsx @@ -29,7 +29,7 @@ export const ChatAttachmentButton = (props: ChatAttachmentButtonProps) => { const {data} = useRoomInfo(); const {privateChatUser, setUploadStatus, setUploadedFiles, uploadStatus} = useChatUIControls(); - const {uploadAttachment} = useChatConfigure(); + const {uploadAttachment, allowChatLogin} = useChatConfigure(); const toastHeadingType = useString(chatUploadErrorToastHeading)(); const toastHeadingSize = useString(chatUploadErrorFileSizeToastHeading)(); const errorSubHeadingSize = useString(chatUploadErrorFileSizeToastSubHeading); @@ -122,12 +122,16 @@ export const ChatAttachmentButton = (props: ChatAttachmentButtonProps) => { ref={fileInputRef} /> { iconSize: 24, name: 'chat_attachment', tintColor: - uploadStatus === UploadStatus.IN_PROGRESS + uploadStatus === UploadStatus.IN_PROGRESS || !allowChatLogin ? $config.SEMANTIC_NEUTRAL : $config.SECONDARY_ACTION_COLOR, }} diff --git a/template/src/subComponents/chat/ChatEmoji.native.tsx b/template/src/subComponents/chat/ChatEmoji.native.tsx index fb7cc6bda..c68e52d9b 100644 --- a/template/src/subComponents/chat/ChatEmoji.native.tsx +++ b/template/src/subComponents/chat/ChatEmoji.native.tsx @@ -4,6 +4,7 @@ import {useChatUIControls} from '../../components/chat-ui/useChatUIControls'; import IconButton from '../../../src/atoms/IconButton'; //import data from 'emoji-mart-native/data/google.json'; import {Picker} from 'emoji-mart-native'; +import {useChatConfigure} from '../../../src/components/chat/chatConfigure'; export interface ChatEmojiButtonProps { render?: (onPress: () => void) => JSX.Element; @@ -11,6 +12,7 @@ export interface ChatEmojiButtonProps { export const ChatEmojiButton = (props: ChatEmojiButtonProps) => { const {setShowEmojiPicker} = useChatUIControls(); + const {allowChatLogin} = useChatConfigure(); const onPress = () => { setShowEmojiPicker(prev => !prev); @@ -21,6 +23,7 @@ export const ChatEmojiButton = (props: ChatEmojiButtonProps) => { { const {setShowEmojiPicker} = useChatUIControls(); + const {allowChatLogin} = useChatConfigure(); const onPress = () => { setShowEmojiPicker(prev => !prev); }; @@ -137,7 +139,8 @@ export const ChatEmojiButton = (props: ChatEmojiButtonProps) => { props.render(onPress) ) : ( { iconProps={{ iconType: 'plain', base64: false, - hoverBase64: true, + hoverBase64: allowChatLogin ? true : false, iconContainerStyle: { padding: 4, }, iconSize: 24, name: 'chat_emoji', - hoverIconName: 'chat_emoji_fill', - tintColor: $config.SECONDARY_ACTION_COLOR, + hoverIconName: !allowChatLogin ? 'chat_emoji' : 'chat_emoji_fill', + tintColor: !allowChatLogin + ? $config.SEMANTIC_NEUTRAL + : $config.SECONDARY_ACTION_COLOR, }} onPress={onPress} /> diff --git a/template/src/subComponents/chat/ChatSendButton.tsx b/template/src/subComponents/chat/ChatSendButton.tsx index 1c4f6bffc..69e030cda 100644 --- a/template/src/subComponents/chat/ChatSendButton.tsx +++ b/template/src/subComponents/chat/ChatSendButton.tsx @@ -27,7 +27,7 @@ export interface ChatSendButtonProps { } const ChatSendButton = (props: ChatSendButtonProps) => { - const {sendChatSDKMessage} = useChatConfigure(); + const {sendChatSDKMessage, allowChatLogin} = useChatConfigure(); const {setShowEmojiPicker} = useChatUIControls(); const { privateChatUser: selectedUserId, @@ -101,14 +101,17 @@ const ChatSendButton = (props: ChatSendButtonProps) => { ) : ( , skipPrecall?: boolean, username?: string, - preference?: {disableShareTile: boolean}, + preference?: {disableShareTile?: boolean; preventChatAutoLogin?: boolean}, ): RoomInfoContextInterface['data']; microphoneDevice: (deviceId: deviceId) => void; speakerDevice: (deviceId: deviceId) => void; diff --git a/template/src/utils/useChatLogin.ts b/template/src/utils/useChatLogin.ts new file mode 100644 index 000000000..24def4b52 --- /dev/null +++ b/template/src/utils/useChatLogin.ts @@ -0,0 +1,58 @@ +/* +******************************************** + Copyright © 2021 Agora Lab, Inc., all rights reserved. + AppBuilder and all associated components, source code, APIs, services, and documentation + (the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be + accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc. + Use without a license or in violation of any license terms and conditions (including use for + any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more + information visit https://appbuilder.agora.io. +********************************************* +*/ + +import {useRoomInfo} from '../components/room-info/useRoomInfo'; +import LocalEventEmitter, { + LocalEventsEnum, +} from '../rtm-events-api/LocalEvents'; +import {EventNames} from '../rtm-events'; +import {LogSource, logger} from '../logger/AppBuilderLogger'; +import events, {PersistanceLevel} from '../rtm-events-api'; +import {useChatConfigure} from '../components/chat/chatConfigure'; + +/** + * Returns a function that enables users to login to agora-chat + * @returns function + */ +function useChatLogin() { + const { + roomPreference: {preventChatAutoLogin}, + } = useRoomInfo(); + const {allowChatLogin} = useChatConfigure(); + + const enableChatLogin = () => { + if (preventChatAutoLogin) { + logger.debug(LogSource.Internals, 'CONTROLS', `enable chat login`); + // chat not signed in yet + // send local event for current user and RTM (L3) event to others in call + LocalEventEmitter.emit(LocalEventsEnum.ENABLE_CHAT_LOGIN); + events.send(EventNames.ENABLE_CHAT_LOGIN, null, PersistanceLevel.Session); + } + }; + + const enableChatLogout = () => { + if (preventChatAutoLogin) { + logger.debug(LogSource.Internals, 'CONTROLS', `enable chat logout`); + // chat not signed in yet + // send local event for current user and RTM (L3) event to others in call + LocalEventEmitter.emit(LocalEventsEnum.ENABLE_CHAT_LOGOUT); + events.send( + EventNames.ENABLE_CHAT_LOGOUT, + null, + PersistanceLevel.Session, + ); + } + }; + return {allowChatLogin, enableChatLogin, enableChatLogout}; +} + +export default useChatLogin; diff --git a/template/src/utils/useCreateRoom.ts b/template/src/utils/useCreateRoom.ts index c14077b7e..cac27a119 100644 --- a/template/src/utils/useCreateRoom.ts +++ b/template/src/utils/useCreateRoom.ts @@ -1,5 +1,8 @@ import {gql, useMutation} from '@apollo/client'; -import {RoomInfoContextInterface} from '../components/room-info/useRoomInfo'; +import { + RoomInfoContextInterface, + RoomInfoDefaultValue, +} from '../components/room-info/useRoomInfo'; import {useSetRoomInfo} from '../components/room-info/useSetRoomInfo'; import SDKEvents from '../utils/SdkEvents'; import isSDK from './isSDK'; @@ -105,6 +108,12 @@ export default function useCreateRoom(): createRoomFun { roomId: roomInfo?.roomId, pstn: roomInfo?.pstn, }, + roomPreference: { + disableShareTile: + RoomInfoDefaultValue.roomPreference.disableShareTile, + preventChatAutoLogin: + RoomInfoDefaultValue.roomPreference.preventChatAutoLogin, + }, }); SDKEvents.emit( 'create', diff --git a/template/src/utils/useJoinRoom.ts b/template/src/utils/useJoinRoom.ts index 62447eafd..84950e927 100644 --- a/template/src/utils/useJoinRoom.ts +++ b/template/src/utils/useJoinRoom.ts @@ -79,7 +79,8 @@ const JOIN_CHANNEL_PHRASE = gql` */ export interface joinRoomPreference { - disableShareTile: boolean; + disableShareTile?: boolean; + preventChatAutoLogin?: boolean; } export default function useJoinRoom() { @@ -245,11 +246,15 @@ export default function useJoinRoom() { ...prevState.data, ...roomInfo, }; + const validPreference = + preference && Object.keys(preference).length > 0; return { ...prevState, isJoinDataFetched: true, data: compiledMeetingInfo, - roomPreference: {...preference}, + roomPreference: validPreference + ? {...preference} + : prevState.roomPreference, }; }); return roomInfo; diff --git a/template/src/utils/useSidePanel.tsx b/template/src/utils/useSidePanel.tsx index 80540f4b4..fc08c17e6 100644 --- a/template/src/utils/useSidePanel.tsx +++ b/template/src/utils/useSidePanel.tsx @@ -14,6 +14,13 @@ import React, {useState, SetStateAction, useEffect} from 'react'; import {SidePanelType} from '../subComponents/SidePanelEnum'; import {createHook} from 'customization-implementation'; import {LogSource, logger} from '../logger/AppBuilderLogger'; +import {useRoomInfo} from '../components/room-info/useRoomInfo'; +import LocalEventEmitter, { + LocalEventsEnum, +} from '../rtm-events-api/LocalEvents'; +import {EventNames} from '../rtm-events'; +import events, {PersistanceLevel} from '../rtm-events-api'; +import useChatLogin from './useChatLogin'; export interface SidePanelContextInterface { sidePanel: SidePanelType; @@ -30,6 +37,11 @@ interface SidePanelProviderProps { } const SidePanelProvider = (props: SidePanelProviderProps) => { const [sidePanel, setSidePanel] = useState(SidePanelType.None); + const { + roomPreference: {preventChatAutoLogin}, + } = useRoomInfo(); + + const {enableChatLogin} = useChatLogin(); useEffect(() => { logger.log( @@ -37,6 +49,11 @@ const SidePanelProvider = (props: SidePanelProviderProps) => { 'CONTROLS', `Side panel changed to -> ${SidePanelType[sidePanel]}`, ); + + if (sidePanel === SidePanelType.Chat) { + // use below fn if preventChatLogin is true + //enableChatLogin(); + } }, [sidePanel]); const value = {sidePanel, setSidePanel};