feat(mobile) adds ability to send and receive text messages (#8425)
This commit is contained in:
parent
df21ec6f04
commit
61037b982b
|
@ -60,7 +60,8 @@ public class BroadcastAction {
|
|||
|
||||
enum Type {
|
||||
SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"),
|
||||
HANG_UP("org.jitsi.meet.HANG_UP");
|
||||
HANG_UP("org.jitsi.meet.HANG_UP"),
|
||||
SEND_ENDPOINT_TEXT_MESSAGE("org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE");
|
||||
|
||||
private final String action;
|
||||
|
||||
|
|
|
@ -80,7 +80,8 @@ public class BroadcastEvent {
|
|||
CONFERENCE_WILL_JOIN("org.jitsi.meet.CONFERENCE_WILL_JOIN"),
|
||||
AUDIO_MUTED_CHANGED("org.jitsi.meet.AUDIO_MUTED_CHANGED"),
|
||||
PARTICIPANT_JOINED("org.jitsi.meet.PARTICIPANT_JOINED"),
|
||||
PARTICIPANT_LEFT("org.jitsi.meet.PARTICIPANT_LEFT");
|
||||
PARTICIPANT_LEFT("org.jitsi.meet.PARTICIPANT_LEFT"),
|
||||
ENDPOINT_TEXT_MESSAGE_RECEIVED("org.jitsi.meet.ENDPOINT_TEXT_MESSAGE_RECEIVED");
|
||||
|
||||
private static final String CONFERENCE_WILL_JOIN_NAME = "CONFERENCE_WILL_JOIN";
|
||||
private static final String CONFERENCE_JOINED_NAME = "CONFERENCE_JOINED";
|
||||
|
@ -88,6 +89,7 @@ public class BroadcastEvent {
|
|||
private static final String AUDIO_MUTED_CHANGED_NAME = "AUDIO_MUTED_CHANGED";
|
||||
private static final String PARTICIPANT_JOINED_NAME = "PARTICIPANT_JOINED";
|
||||
private static final String PARTICIPANT_LEFT_NAME = "PARTICIPANT_LEFT";
|
||||
private static final String ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME = "ENDPOINT_TEXT_MESSAGE_RECEIVED";
|
||||
|
||||
private final String action;
|
||||
|
||||
|
@ -122,6 +124,8 @@ public class BroadcastEvent {
|
|||
return PARTICIPANT_JOINED;
|
||||
case PARTICIPANT_LEFT_NAME:
|
||||
return PARTICIPANT_LEFT;
|
||||
case ENDPOINT_TEXT_MESSAGE_RECEIVED_NAME:
|
||||
return ENDPOINT_TEXT_MESSAGE_RECEIVED;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -12,4 +12,11 @@ public class BroadcastIntentHelper {
|
|||
public static Intent buildHangUpIntent() {
|
||||
return new Intent(BroadcastAction.Type.HANG_UP.getAction());
|
||||
}
|
||||
|
||||
public static Intent buildSendEndpointTextMessageIntent(String to, String message) {
|
||||
Intent intent = new Intent(BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
|
||||
intent.putExtra("to", to);
|
||||
intent.putExtra("message", message);
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ public class BroadcastReceiver extends android.content.BroadcastReceiver {
|
|||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(BroadcastAction.Type.SET_AUDIO_MUTED.getAction());
|
||||
intentFilter.addAction(BroadcastAction.Type.HANG_UP.getAction());
|
||||
intentFilter.addAction(BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
|
||||
|
||||
localBroadcastManager.registerReceiver(this, intentFilter);
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ class ExternalAPIModule
|
|||
|
||||
constants.put("SET_AUDIO_MUTED", BroadcastAction.Type.SET_AUDIO_MUTED.getAction());
|
||||
constants.put("HANG_UP", BroadcastAction.Type.HANG_UP.getAction());
|
||||
constants.put("SEND_ENDPOINT_TEXT_MESSAGE", BroadcastAction.Type.SEND_ENDPOINT_TEXT_MESSAGE.getAction());
|
||||
|
||||
return constants;
|
||||
}
|
||||
|
|
|
@ -271,6 +271,7 @@ public class JitsiMeetActivity extends FragmentActivity
|
|||
intentFilter.addAction(BroadcastEvent.Type.CONFERENCE_TERMINATED.getAction());
|
||||
intentFilter.addAction(BroadcastEvent.Type.PARTICIPANT_JOINED.getAction());
|
||||
intentFilter.addAction(BroadcastEvent.Type.PARTICIPANT_LEFT.getAction());
|
||||
intentFilter.addAction(BroadcastEvent.Type.ENDPOINT_TEXT_MESSAGE_RECEIVED.getAction());
|
||||
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, intentFilter);
|
||||
}
|
||||
|
|
|
@ -115,6 +115,10 @@
|
|||
NSLog(@"%@%@", @"Audio muted changed: ", data[@"muted"]);
|
||||
}
|
||||
|
||||
- (void)endpointTextMessageReceived:(NSDictionary *)data; {
|
||||
NSLog(@"%@%@", @"Endpoint text message received: ", data);
|
||||
}
|
||||
|
||||
#pragma mark - Helpers
|
||||
|
||||
- (void)terminate {
|
||||
|
|
|
@ -20,5 +20,6 @@
|
|||
|
||||
- (void)sendHangUp;
|
||||
- (void)sendSetAudioMuted: (BOOL)muted;
|
||||
- (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message;
|
||||
|
||||
@end
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
#import "JitsiMeetView+Private.h"
|
||||
|
||||
// Events
|
||||
static NSString * const hangUpEvent = @"org.jitsi.meet.HANG_UP";
|
||||
static NSString * const setAudioMutedEvent = @"org.jitsi.meet.SET_AUDIO_MUTED";
|
||||
static NSString * const hangUpAction = @"org.jitsi.meet.HANG_UP";
|
||||
static NSString * const setAudioMutedAction = @"org.jitsi.meet.SET_AUDIO_MUTED";
|
||||
static NSString * const sendEndpointTextMessageAction = @"org.jitsi.meet.SEND_ENDPOINT_TEXT_MESSAGE";
|
||||
|
||||
@implementation ExternalAPI
|
||||
|
||||
|
@ -27,8 +28,9 @@ RCT_EXPORT_MODULE();
|
|||
|
||||
- (NSDictionary *)constantsToExport {
|
||||
return @{
|
||||
@"HANG_UP": hangUpEvent,
|
||||
@"SET_AUDIO_MUTED" : setAudioMutedEvent
|
||||
@"HANG_UP": hangUpAction,
|
||||
@"SET_AUDIO_MUTED" : setAudioMutedAction,
|
||||
@"SEND_ENDPOINT_TEXT_MESSAGE": sendEndpointTextMessageAction
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -44,7 +46,7 @@ RCT_EXPORT_MODULE();
|
|||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[ hangUpEvent, setAudioMutedEvent ];
|
||||
return @[ hangUpAction, setAudioMutedAction, sendEndpointTextMessageAction ];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,13 +105,22 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
|||
}
|
||||
|
||||
- (void)sendHangUp {
|
||||
[self sendEventWithName:hangUpEvent body:nil];
|
||||
[self sendEventWithName:hangUpAction body:nil];
|
||||
}
|
||||
|
||||
- (void)sendSetAudioMuted:(BOOL)muted {
|
||||
NSDictionary *data = @{ @"muted": [NSNumber numberWithBool:muted]};
|
||||
|
||||
[self sendEventWithName:setAudioMutedEvent body:data];
|
||||
[self sendEventWithName:setAudioMutedAction body:data];
|
||||
}
|
||||
|
||||
- (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message {
|
||||
NSDictionary *data = @{
|
||||
@"to": to,
|
||||
@"message": message
|
||||
};
|
||||
|
||||
[self sendEventWithName:sendEndpointTextMessageAction body:data];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -16,11 +16,13 @@
|
|||
|
||||
#import <React/RCTBridge.h>
|
||||
|
||||
#import "ExternalAPI.h"
|
||||
#import "JitsiMeet.h"
|
||||
|
||||
@interface JitsiMeet ()
|
||||
|
||||
- (NSDictionary *)getDefaultProps;
|
||||
- (RCTBridge *)getReactBridge;
|
||||
- (ExternalAPI *)getExternalAPI;
|
||||
|
||||
@end
|
||||
|
|
|
@ -213,4 +213,8 @@
|
|||
return _bridgeWrapper.bridge;
|
||||
}
|
||||
|
||||
- (ExternalAPI *)getExternalAPI {
|
||||
return [_bridgeWrapper.bridge moduleForClass:ExternalAPI.class];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -41,4 +41,6 @@
|
|||
|
||||
- (void)setAudioMuted:(BOOL)muted;
|
||||
|
||||
- (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message;
|
||||
|
||||
@end
|
||||
|
|
|
@ -116,13 +116,18 @@ static void initializeViewsMap() {
|
|||
}
|
||||
|
||||
- (void)hangUp {
|
||||
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
|
||||
[[bridge moduleForClass:ExternalAPI.class] sendHangUp];
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendHangUp];
|
||||
}
|
||||
|
||||
- (void)setAudioMuted:(BOOL)muted {
|
||||
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
|
||||
[[bridge moduleForClass:ExternalAPI.class] sendSetAudioMuted:muted];
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendSetAudioMuted:muted];
|
||||
}
|
||||
|
||||
- (void)sendEndpointTextMessage:(NSString*)to :(NSString*)message {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendEndpointTextMessage:to :message];
|
||||
}
|
||||
|
||||
#pragma mark Private methods
|
||||
|
|
|
@ -75,4 +75,12 @@
|
|||
* The `data` dictionary contains a `muted` key with state of the audioMuted for the localParticipant.
|
||||
*/
|
||||
- (void)audioMutedChanged:(NSDictionary *)data;
|
||||
|
||||
/**
|
||||
* Called when an endpoint text message is received.
|
||||
*
|
||||
* The `data` dictionary contains a `senderId` key with the participantId of the sender and a 'message' key with the content.
|
||||
*/
|
||||
- (void)endpointTextMessageReceived:(NSDictionary *)data;
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import { getLogger } from '../../base/logging/functions';
|
||||
|
||||
export default getLogger('features/mobile/external-api');
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { NativeEventEmitter, NativeModules } from 'react-native';
|
||||
|
||||
import { ENDPOINT_TEXT_MESSAGE_NAME } from '../../../../modules/API/constants';
|
||||
import { appNavigate } from '../../app/actions';
|
||||
import { APP_WILL_MOUNT } from '../../base/app/actionTypes';
|
||||
import {
|
||||
|
@ -12,6 +13,7 @@ import {
|
|||
JITSI_CONFERENCE_URL_KEY,
|
||||
SET_ROOM,
|
||||
forEachConference,
|
||||
getCurrentConference,
|
||||
isRoomValid
|
||||
} from '../../base/conference';
|
||||
import { LOAD_CONFIG_ERROR } from '../../base/config';
|
||||
|
@ -22,6 +24,7 @@ import {
|
|||
JITSI_CONNECTION_URL_KEY,
|
||||
getURLWithoutParams
|
||||
} from '../../base/connection';
|
||||
import { JitsiConferenceEvents } from '../../base/lib-jitsi-meet';
|
||||
import { SET_AUDIO_MUTED } from '../../base/media/actionTypes';
|
||||
import { PARTICIPANT_JOINED, PARTICIPANT_LEFT } from '../../base/participants';
|
||||
import { MiddlewareRegistry } from '../../base/redux';
|
||||
|
@ -29,6 +32,7 @@ import { muteLocal } from '../../remote-video-menu/actions';
|
|||
import { ENTER_PICTURE_IN_PICTURE } from '../picture-in-picture';
|
||||
|
||||
import { sendEvent } from './functions';
|
||||
import logger from './logger';
|
||||
|
||||
/**
|
||||
* Event which will be emitted on the native side to indicate the conference
|
||||
|
@ -36,6 +40,12 @@ import { sendEvent } from './functions';
|
|||
*/
|
||||
const CONFERENCE_TERMINATED = 'CONFERENCE_TERMINATED';
|
||||
|
||||
/**
|
||||
* Event which will be emitted on the native side to indicate a message was received
|
||||
* through the channel.
|
||||
*/
|
||||
const ENDPOINT_TEXT_MESSAGE_RECEIVED = 'ENDPOINT_TEXT_MESSAGE_RECEIVED';
|
||||
|
||||
const { ExternalAPI } = NativeModules;
|
||||
const eventEmitter = new NativeEventEmitter(ExternalAPI);
|
||||
|
||||
|
@ -52,7 +62,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
|
||||
switch (type) {
|
||||
case APP_WILL_MOUNT:
|
||||
_registerForNativeEvents(store.dispatch);
|
||||
_registerForNativeEvents(store);
|
||||
break;
|
||||
case CONFERENCE_FAILED: {
|
||||
const { error, ...data } = action;
|
||||
|
@ -75,12 +85,16 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
break;
|
||||
}
|
||||
|
||||
case CONFERENCE_JOINED:
|
||||
case CONFERENCE_LEFT:
|
||||
case CONFERENCE_WILL_JOIN:
|
||||
_sendConferenceEvent(store, action);
|
||||
break;
|
||||
|
||||
case CONFERENCE_JOINED:
|
||||
_sendConferenceEvent(store, action);
|
||||
_registerForEndpointTextMessages(store);
|
||||
break;
|
||||
|
||||
case CONNECTION_DISCONNECTED: {
|
||||
// FIXME: This is a hack. See the description in the JITSI_CONNECTION_CONFERENCE_KEY constant definition.
|
||||
// Check if this connection was attached to any conference. If it wasn't, fake a CONFERENCE_TERMINATED event.
|
||||
|
@ -160,11 +174,11 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
/**
|
||||
* Registers for events sent from the native side via NativeEventEmitter.
|
||||
*
|
||||
* @param {Dispatch} dispatch - The Redux dispatch function.
|
||||
* @param {Store} store - The redux store.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _registerForNativeEvents(dispatch) {
|
||||
function _registerForNativeEvents({ getState, dispatch }) {
|
||||
eventEmitter.addListener(ExternalAPI.HANG_UP, () => {
|
||||
dispatch(appNavigate(undefined));
|
||||
});
|
||||
|
@ -172,6 +186,48 @@ function _registerForNativeEvents(dispatch) {
|
|||
eventEmitter.addListener(ExternalAPI.SET_AUDIO_MUTED, ({ muted }) => {
|
||||
dispatch(muteLocal(muted === 'true'));
|
||||
});
|
||||
|
||||
eventEmitter.addListener(ExternalAPI.SEND_ENDPOINT_TEXT_MESSAGE, ({ to, message }) => {
|
||||
const conference = getCurrentConference(getState());
|
||||
|
||||
try {
|
||||
conference && conference.sendEndpointMessage(to, {
|
||||
name: ENDPOINT_TEXT_MESSAGE_NAME,
|
||||
text: message
|
||||
});
|
||||
} catch (error) {
|
||||
logger.warn('Cannot send endpointMessage', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers for endpoint messages sent on conference data channel.
|
||||
*
|
||||
* @param {Store} store - The redux store.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _registerForEndpointTextMessages(store) {
|
||||
const conference = getCurrentConference(store.getState());
|
||||
|
||||
conference && conference.on(
|
||||
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
(...args) => {
|
||||
if (args && args.length >= 2) {
|
||||
const [ sender, eventData ] = args;
|
||||
|
||||
if (eventData.name === ENDPOINT_TEXT_MESSAGE_NAME) {
|
||||
sendEvent(
|
||||
store,
|
||||
ENDPOINT_TEXT_MESSAGE_RECEIVED,
|
||||
/* data */ {
|
||||
message: eventData.text,
|
||||
senderId: sender._id
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue