[RN] Reduce maintenance
JitsiMeetViewListener currently has methods of one and the same pattern so adding new methods i.e. events i.e. redux action types is a question of repetition in the Java source code. Speed up the support of new events by trying to deal with them in a generic way. The same goes for JitsiMeetViewDelegate.
This commit is contained in:
parent
6982506acc
commit
1d8ee9d32f
|
@ -25,7 +25,12 @@ import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
|||
import org.jitsi.meet.sdk.JitsiMeetView;
|
||||
import org.jitsi.meet.sdk.JitsiMeetViewListener;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Module implementing a simple API to enable a proximity sensor-controlled
|
||||
|
@ -35,10 +40,60 @@ import java.util.HashMap;
|
|||
*/
|
||||
class ExternalAPIModule extends ReactContextBaseJavaModule {
|
||||
/**
|
||||
* React Native module name.
|
||||
* The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
|
||||
* redux action types.
|
||||
*/
|
||||
private static final Map<String, Method> JITSI_MEET_VIEW_LISTENER_METHODS
|
||||
= new HashMap<>();
|
||||
|
||||
/**
|
||||
* The name of this module to be used in the React Native bridge.
|
||||
*/
|
||||
private static final String MODULE_NAME = "ExternalAPI";
|
||||
|
||||
static {
|
||||
// Figure out the mapping between the JitsiMeetViewListener methods
|
||||
// and the events i.e. redux action types.
|
||||
Pattern onPattern = Pattern.compile("^on[A-Z]+");
|
||||
Pattern camelcasePattern = Pattern.compile("([a-z0-9]+)([A-Z0-9]+)");
|
||||
|
||||
for (Method method : JitsiMeetViewListener.class.getDeclaredMethods()) {
|
||||
// * The method must be public (because it is declared by an
|
||||
// interface).
|
||||
// * The method must be/return void.
|
||||
if (!Modifier.isPublic(method.getModifiers())
|
||||
|| !Void.TYPE.equals(method.getReturnType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// * The method name must start with "on" followed by a
|
||||
// capital/uppercase letter (in agreement with the camelcase
|
||||
// coding style customary to Java in general and the projects of
|
||||
// the Jitsi community in particular).
|
||||
String name = method.getName();
|
||||
|
||||
if (!onPattern.matcher(name).find()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// * The method must accept/have exactly 1 parameter of a type
|
||||
// assignable from HashMap.
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
|
||||
if (parameterTypes.length != 1
|
||||
|| !parameterTypes[0].isAssignableFrom(HashMap.class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert the method name to an event name.
|
||||
name
|
||||
= camelcasePattern.matcher(name.substring(2))
|
||||
.replaceAll("$1_$2")
|
||||
.toUpperCase(Locale.ROOT);
|
||||
JITSI_MEET_VIEW_LISTENER_METHODS.put(name, method);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new module instance. There shall be a single instance of
|
||||
* this module throughout the lifetime of the application.
|
||||
|
@ -85,26 +140,14 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
|
|||
return;
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
case "CONFERENCE_FAILED":
|
||||
listener.onConferenceFailed(toHashMap(data));
|
||||
break;
|
||||
Method method = JITSI_MEET_VIEW_LISTENER_METHODS.get(name);
|
||||
|
||||
case "CONFERENCE_JOINED":
|
||||
listener.onConferenceJoined(toHashMap(data));
|
||||
break;
|
||||
|
||||
case "CONFERENCE_LEFT":
|
||||
listener.onConferenceLeft(toHashMap(data));
|
||||
break;
|
||||
|
||||
case "CONFERENCE_WILL_JOIN":
|
||||
listener.onConferenceWillJoin(toHashMap(data));
|
||||
break;
|
||||
|
||||
case "CONFERENCE_WILL_LEAVE":
|
||||
listener.onConferenceWillLeave(toHashMap(data));
|
||||
break;
|
||||
if (method != null) {
|
||||
try {
|
||||
method.invoke(listener, toHashMap(data));
|
||||
} catch (ReflectiveOperationException roe) {
|
||||
throw new RuntimeException(roe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,26 +52,33 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
|||
return;
|
||||
}
|
||||
|
||||
if ([name isEqualToString:@"CONFERENCE_FAILED"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceFailed:)]) {
|
||||
[delegate conferenceFailed:data];
|
||||
SEL sel = NSSelectorFromString([self methodNameFromEventName:name]);
|
||||
|
||||
} else if ([name isEqualToString:@"CONFERENCE_JOINED"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceJoined:)]) {
|
||||
[delegate conferenceJoined:data];
|
||||
|
||||
} else if ([name isEqualToString:@"CONFERENCE_LEFT"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceLeft:)]) {
|
||||
[delegate conferenceLeft:data];
|
||||
|
||||
} else if ([name isEqualToString:@"CONFERENCE_WILL_JOIN"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceWillJoin:)]) {
|
||||
[delegate conferenceWillJoin:data];
|
||||
|
||||
} else if ([name isEqualToString:@"CONFERENCE_WILL_LEAVE"]
|
||||
&& [delegate respondsToSelector:@selector(conferenceWillLeave:)]) {
|
||||
[delegate conferenceWillLeave:data];
|
||||
if (sel && [delegate respondsToSelector:sel]) {
|
||||
[delegate performSelector:sel withObject:data];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a specific event name i.e. redux action type description to a
|
||||
* method name.
|
||||
*
|
||||
* @param eventName The event name to convert to a method name.
|
||||
* @return A method name constructed from the specified {@code eventName}.
|
||||
*/
|
||||
- (NSString *)methodNameFromEventName:(NSString *)eventName {
|
||||
NSMutableString *methodName
|
||||
= [NSMutableString stringWithCapacity:eventName.length];
|
||||
|
||||
for (NSString *c in [eventName componentsSeparatedByString:@"_"]) {
|
||||
if (c.length) {
|
||||
[methodName appendString:
|
||||
methodName.length ? c.capitalizedString : c.lowercaseString];
|
||||
}
|
||||
}
|
||||
[methodName appendString:@":"];
|
||||
|
||||
return methodName;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue