[Android] Introduce IncomingCallView (continued)
This commit is contained in:
parent
ea22d12581
commit
8ff3ae0ab2
|
@ -205,13 +205,13 @@ which displays a single `JitsiMeetView`.
|
||||||
|
|
||||||
See JitsiMeetView.getDefaultURL.
|
See JitsiMeetView.getDefaultURL.
|
||||||
|
|
||||||
#### getPictureInPictureEnabled()
|
#### isPictureInPictureEnabled()
|
||||||
|
|
||||||
See JitsiMeetView.getPictureInPictureEnabled.
|
See JitsiMeetView.isPictureInPictureEnabled.
|
||||||
|
|
||||||
#### getWelcomePageEnabled()
|
#### isWelcomePageEnabled()
|
||||||
|
|
||||||
See JitsiMeetView.getWelcomePageEnabled.
|
See JitsiMeetView.isWelcomePageEnabled.
|
||||||
|
|
||||||
#### loadURL(URL)
|
#### loadURL(URL)
|
||||||
|
|
||||||
|
@ -250,13 +250,13 @@ if set to `null`, the default built in JavaScript is used: https://meet.jit.si.
|
||||||
|
|
||||||
Returns the `JitsiMeetViewListener` instance attached to the view.
|
Returns the `JitsiMeetViewListener` instance attached to the view.
|
||||||
|
|
||||||
#### getPictureInPictureEnabled()
|
#### isPictureInPictureEnabled()
|
||||||
|
|
||||||
Returns `true` if Picture-in-Picture is enabled; `false`, otherwise. If not
|
Returns `true` if Picture-in-Picture is enabled; `false`, otherwise. If not
|
||||||
explicitly set (by a preceding `setPictureInPictureEnabled` call), defaults to
|
explicitly set (by a preceding `setPictureInPictureEnabled` call), defaults to
|
||||||
`true` if the platform supports Picture-in-Picture natively; `false`, otherwise.
|
`true` if the platform supports Picture-in-Picture natively; `false`, otherwise.
|
||||||
|
|
||||||
#### getWelcomePageEnabled()
|
#### isWelcomePageEnabled()
|
||||||
|
|
||||||
Returns true if the Welcome page is enabled; otherwise, false. If false, a black
|
Returns true if the Welcome page is enabled; otherwise, false. If false, a black
|
||||||
empty view will be rendered when not in a conference. Defaults to false.
|
empty view will be rendered when not in a conference. Defaults to false.
|
||||||
|
@ -316,7 +316,7 @@ effect.
|
||||||
|
|
||||||
#### setWelcomePageEnabled(boolean)
|
#### setWelcomePageEnabled(boolean)
|
||||||
|
|
||||||
Sets whether the Welcome page is enabled. See `getWelcomePageEnabled` for more
|
Sets whether the Welcome page is enabled. See `isWelcomePageEnabled` for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
NOTE: Must be called (if at all) before `loadURL`/`loadURLString` for it to take
|
NOTE: Must be called (if at all) before `loadURL`/`loadURLString` for it to take
|
||||||
|
|
|
@ -16,7 +16,9 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
|
||||||
class AndroidSettingsModule extends ReactContextBaseJavaModule {
|
class AndroidSettingsModule
|
||||||
|
extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
public AndroidSettingsModule(ReactApplicationContext reactContext) {
|
public AndroidSettingsModule(ReactApplicationContext reactContext) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2017-present Atlassian Pty Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.jitsi.meet.sdk;
|
package org.jitsi.meet.sdk;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -11,7 +27,9 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
class AppInfoModule extends ReactContextBaseJavaModule {
|
class AppInfoModule
|
||||||
|
extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
public AppInfoModule(ReactApplicationContext reactContext) {
|
public AppInfoModule(ReactApplicationContext reactContext) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,10 @@ import java.util.Set;
|
||||||
* Before a call has started and after it has ended the
|
* Before a call has started and after it has ended the
|
||||||
* {@code AudioModeModule.DEFAULT} mode should be used.
|
* {@code AudioModeModule.DEFAULT} mode should be used.
|
||||||
*/
|
*/
|
||||||
class AudioModeModule extends ReactContextBaseJavaModule implements AudioManager.OnAudioFocusChangeListener {
|
class AudioModeModule
|
||||||
|
extends ReactContextBaseJavaModule
|
||||||
|
implements AudioManager.OnAudioFocusChangeListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants representing the audio mode.
|
* Constants representing the audio mode.
|
||||||
* - DEFAULT: Used before and after every call. It represents the default
|
* - DEFAULT: Used before and after every call. It represents the default
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2018-present Atlassian Pty Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.jitsi.meet.sdk;
|
package org.jitsi.meet.sdk;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
@ -12,7 +28,9 @@ import com.facebook.react.ReactRootView;
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
import com.rnimmersive.RNImmersiveModule;
|
import com.rnimmersive.RNImmersiveModule;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
@ -20,7 +38,9 @@ import java.util.WeakHashMap;
|
||||||
/**
|
/**
|
||||||
* Base class for all views which are backed by a React Native view.
|
* Base class for all views which are backed by a React Native view.
|
||||||
*/
|
*/
|
||||||
public abstract class BaseReactView extends FrameLayout {
|
public abstract class BaseReactView<ListenerT>
|
||||||
|
extends FrameLayout {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Background color used by {@code BaseReactView} and the React Native root
|
* Background color used by {@code BaseReactView} and the React Native root
|
||||||
* view.
|
* view.
|
||||||
|
@ -28,30 +48,21 @@ public abstract class BaseReactView extends FrameLayout {
|
||||||
protected static int BACKGROUND_COLOR = 0xFF111111;
|
protected static int BACKGROUND_COLOR = 0xFF111111;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unique identifier of this {@code BaseReactView} within the process
|
* The collection of all existing {@code BaseReactView}s. Used to find the
|
||||||
* for the purposes of {@link ExternalAPIModule}. The name scope was
|
* {@code BaseReactView} when delivering events coming from
|
||||||
* inspired by postis which we use on Web for the similar purposes of the
|
* {@link ExternalAPIModule}.
|
||||||
* iframe-based external API.
|
|
||||||
*/
|
|
||||||
protected final String externalAPIScope;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* React Native root view.
|
|
||||||
*/
|
|
||||||
private ReactRootView reactRootView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection with all created views. This is used for finding the right
|
|
||||||
* view when delivering events coming from the {@link ExternalAPIModule};
|
|
||||||
*/
|
*/
|
||||||
static final Set<BaseReactView> views
|
static final Set<BaseReactView> views
|
||||||
= Collections.newSetFromMap(new WeakHashMap<BaseReactView, Boolean>());
|
= Collections.newSetFromMap(new WeakHashMap<BaseReactView, Boolean>());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a view which matches the given external API scope.
|
* Finds a {@code BaseReactView} which matches a specific external API
|
||||||
|
* scope.
|
||||||
*
|
*
|
||||||
* @param externalAPIScope - Scope for the view we want to find.
|
* @param externalAPIScope - The external API scope associated with the
|
||||||
* @return The found {@code BaseReactView}, or {@code null}.
|
* {@code BaseReactView} to find.
|
||||||
|
* @return The {@code BaseReactView}, if any, associated with the specified
|
||||||
|
* {@code externalAPIScope}; otherwise, {@code null}.
|
||||||
*/
|
*/
|
||||||
public static BaseReactView findViewByExternalAPIScope(
|
public static BaseReactView findViewByExternalAPIScope(
|
||||||
String externalAPIScope) {
|
String externalAPIScope) {
|
||||||
|
@ -66,6 +77,25 @@ public abstract class BaseReactView extends FrameLayout {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique identifier of this {@code BaseReactView} within the process
|
||||||
|
* for the purposes of {@link ExternalAPIModule}. The name scope was
|
||||||
|
* inspired by postis which we use on Web for the similar purposes of the
|
||||||
|
* iframe-based external API.
|
||||||
|
*/
|
||||||
|
protected final String externalAPIScope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The listener (e.g. {@link JitsiMeetViewListener}) instance for reporting
|
||||||
|
* events occurring in Jitsi Meet.
|
||||||
|
*/
|
||||||
|
private ListenerT listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React Native root view.
|
||||||
|
*/
|
||||||
|
private ReactRootView reactRootView;
|
||||||
|
|
||||||
public BaseReactView(@NonNull Context context) {
|
public BaseReactView(@NonNull Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
|
@ -85,16 +115,14 @@ public abstract class BaseReactView extends FrameLayout {
|
||||||
* Creates the {@code ReactRootView} for the given app name with the given
|
* Creates the {@code ReactRootView} for the given app name with the given
|
||||||
* props. Once created it's set as the view of this {@code FrameLayout}.
|
* props. Once created it's set as the view of this {@code FrameLayout}.
|
||||||
*
|
*
|
||||||
* @param appName - Name of the "app" (in React Native terms) which we want
|
* @param appName - The name of the "app" (in React Native terms) to load.
|
||||||
* to load.
|
* @param props - The React Component props to pass to the app.
|
||||||
* @param props - Props (in React terms) to be passed to the app.
|
|
||||||
*/
|
*/
|
||||||
public void createReactRootView(String appName, @Nullable Bundle props) {
|
public void createReactRootView(String appName, @Nullable Bundle props) {
|
||||||
if (props == null) {
|
if (props == null) {
|
||||||
props = new Bundle();
|
props = new Bundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set externalAPIScope
|
|
||||||
props.putString("externalAPIScope", externalAPIScope);
|
props.putString("externalAPIScope", externalAPIScope);
|
||||||
|
|
||||||
if (reactRootView == null) {
|
if (reactRootView == null) {
|
||||||
|
@ -114,8 +142,8 @@ public abstract class BaseReactView extends FrameLayout {
|
||||||
* Releases the React resources (specifically the {@link ReactRootView})
|
* Releases the React resources (specifically the {@link ReactRootView})
|
||||||
* associated with this view.
|
* associated with this view.
|
||||||
*
|
*
|
||||||
* This method MUST be called when the Activity holding this view is
|
* MUST be called when the {@link Activity} holding this view is destroyed,
|
||||||
* destroyed, typically in the {@code onDestroy} method.
|
* typically in the {@code onDestroy} method.
|
||||||
*/
|
*/
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (reactRootView != null) {
|
if (reactRootView != null) {
|
||||||
|
@ -125,15 +153,36 @@ public abstract class BaseReactView extends FrameLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the listener set on this {@code BaseReactView}.
|
||||||
|
*
|
||||||
|
* @return The listener set on this {@code BaseReactView}.
|
||||||
|
*/
|
||||||
|
public ListenerT getListener() {
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract method called by {@link ExternalAPIModule} when an event is
|
* Abstract method called by {@link ExternalAPIModule} when an event is
|
||||||
* received for this view.
|
* received for this view.
|
||||||
*
|
*
|
||||||
* @param name - Name of the event.
|
* @param name - The name of the event.
|
||||||
* @param data - Event data.
|
* @param data - The details of the event associated with/specific to the
|
||||||
|
* specified {@code name}.
|
||||||
*/
|
*/
|
||||||
public abstract void onExternalAPIEvent(String name, ReadableMap data);
|
public abstract void onExternalAPIEvent(String name, ReadableMap data);
|
||||||
|
|
||||||
|
protected void onExternalAPIEvent(
|
||||||
|
Map<String, Method> listenerMethods,
|
||||||
|
String name, ReadableMap data) {
|
||||||
|
ListenerT listener = getListener();
|
||||||
|
|
||||||
|
if (listener != null) {
|
||||||
|
ListenerUtils.runListenerMethod(
|
||||||
|
listener, listenerMethods, name, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the window containing this view gains or loses focus.
|
* Called when the window containing this view gains or loses focus.
|
||||||
*
|
*
|
||||||
|
@ -163,9 +212,20 @@ public abstract class BaseReactView extends FrameLayout {
|
||||||
// functionality is brittle anyway, akin to the icing on the
|
// functionality is brittle anyway, akin to the icing on the
|
||||||
// cake, and has been working without onWindowFocusChanged for a
|
// cake, and has been working without onWindowFocusChanged for a
|
||||||
// very long time.
|
// very long time.
|
||||||
Log.e("RNImmersiveModule",
|
Log.e(
|
||||||
"emitImmersiveStateChangeEvent() failed!", re);
|
"RNImmersiveModule",
|
||||||
|
"emitImmersiveStateChangeEvent() failed!",
|
||||||
|
re);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a specific listener on this {@code BaseReactView}.
|
||||||
|
*
|
||||||
|
* @param listener The listener to set on this {@code BaseReactView}.
|
||||||
|
*/
|
||||||
|
public void setListener(ListenerT listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,14 @@ import com.facebook.react.bridge.ReadableMap;
|
||||||
/**
|
/**
|
||||||
* Module implementing an API for sending events from JavaScript to native code.
|
* Module implementing an API for sending events from JavaScript to native code.
|
||||||
*/
|
*/
|
||||||
class ExternalAPIModule extends ReactContextBaseJavaModule {
|
class ExternalAPIModule
|
||||||
|
extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
private static final String TAG = ExternalAPIModule.class.getSimpleName();
|
private static final String TAG = ExternalAPIModule.class.getSimpleName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a new module instance. There shall be a single instance of
|
* Initializes a new module instance. There shall be a single instance of
|
||||||
* this module throughout the lifetime of the application.
|
* this module throughout the lifetime of the app.
|
||||||
*
|
*
|
||||||
* @param reactContext the {@link ReactApplicationContext} where this module
|
* @param reactContext the {@link ReactApplicationContext} where this module
|
||||||
* is created.
|
* is created.
|
||||||
|
@ -60,23 +62,18 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
|
||||||
* @param scope
|
* @param scope
|
||||||
*/
|
*/
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void sendEvent(final String name,
|
public void sendEvent(String name, ReadableMap data, String scope) {
|
||||||
final ReadableMap data,
|
|
||||||
final String scope) {
|
|
||||||
// The JavaScript App needs to provide uniquely identifying information
|
// The JavaScript App needs to provide uniquely identifying information
|
||||||
// to the native ExternalAPI module so that the latter may match the
|
// to the native ExternalAPI module so that the latter may match the
|
||||||
// former to the native BaseReactView which hosts it.
|
// former to the native BaseReactView which hosts it.
|
||||||
BaseReactView view = BaseReactView.findViewByExternalAPIScope(scope);
|
BaseReactView view = BaseReactView.findViewByExternalAPIScope(scope);
|
||||||
|
|
||||||
if (view == null) {
|
if (view != null) {
|
||||||
return;
|
try {
|
||||||
}
|
view.onExternalAPIEvent(name, data);
|
||||||
|
} catch(Exception e) {
|
||||||
try {
|
Log.e(TAG, "onExternalAPIEvent: error sending event", e);
|
||||||
view.onExternalAPIEvent(name, data);
|
}
|
||||||
} catch(Exception e) {
|
|
||||||
Log.e(TAG, "onExternalAPIEvent: error sending event", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,9 @@ import java.net.URL;
|
||||||
* hooked to the React Native subsystem via proxy calls through the
|
* hooked to the React Native subsystem via proxy calls through the
|
||||||
* {@code JitsiMeetView} static methods.
|
* {@code JitsiMeetView} static methods.
|
||||||
*/
|
*/
|
||||||
public class JitsiMeetActivity extends AppCompatActivity {
|
public class JitsiMeetActivity
|
||||||
|
extends AppCompatActivity {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The request code identifying requests for the permission to draw on top
|
* The request code identifying requests for the permission to draw on top
|
||||||
* of other apps. The value must be 16-bit and is arbitrarily chosen here.
|
* of other apps. The value must be 16-bit and is arbitrarily chosen here.
|
||||||
|
@ -95,25 +97,6 @@ public class JitsiMeetActivity extends AppCompatActivity {
|
||||||
return view == null ? defaultURL : view.getDefaultURL();
|
return view == null ? defaultURL : view.getDefaultURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @see JitsiMeetView#getPictureInPictureEnabled()
|
|
||||||
*/
|
|
||||||
public boolean getPictureInPictureEnabled() {
|
|
||||||
return
|
|
||||||
view == null
|
|
||||||
? pictureInPictureEnabled
|
|
||||||
: view.getPictureInPictureEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @see JitsiMeetView#getWelcomePageEnabled()
|
|
||||||
*/
|
|
||||||
public boolean getWelcomePageEnabled() {
|
|
||||||
return view == null ? welcomePageEnabled : view.getWelcomePageEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the {@link #view} of this {@code JitsiMeetActivity} with a
|
* Initializes the {@link #view} of this {@code JitsiMeetActivity} with a
|
||||||
* new {@link JitsiMeetView} instance.
|
* new {@link JitsiMeetView} instance.
|
||||||
|
@ -152,6 +135,25 @@ public class JitsiMeetActivity extends AppCompatActivity {
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @see JitsiMeetView#isPictureInPictureEnabled()
|
||||||
|
*/
|
||||||
|
public boolean isPictureInPictureEnabled() {
|
||||||
|
return
|
||||||
|
view == null
|
||||||
|
? pictureInPictureEnabled
|
||||||
|
: view.isPictureInPictureEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @see JitsiMeetView#isWelcomePageEnabled()
|
||||||
|
*/
|
||||||
|
public boolean isWelcomePageEnabled() {
|
||||||
|
return view == null ? welcomePageEnabled : view.isWelcomePageEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the given URL and displays the conference. If the specified URL is
|
* Loads the given URL and displays the conference. If the specified URL is
|
||||||
* null, the welcome page is displayed instead.
|
* null, the welcome page is displayed instead.
|
||||||
|
@ -177,7 +179,7 @@ public class JitsiMeetActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (!ReactActivityLifecycleAdapter.onBackPressed()) {
|
if (!ReactActivityLifecycleCallbacks.onBackPressed()) {
|
||||||
// JitsiMeetView didn't handle the invocation of the back button.
|
// JitsiMeetView didn't handle the invocation of the back button.
|
||||||
// Generally, an Activity extender would very likely want to invoke
|
// Generally, an Activity extender would very likely want to invoke
|
||||||
// Activity#onBackPressed(). For the sake of consistency with
|
// Activity#onBackPressed(). For the sake of consistency with
|
||||||
|
@ -220,7 +222,7 @@ public class JitsiMeetActivity extends AppCompatActivity {
|
||||||
view = null;
|
view = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReactActivityLifecycleAdapter.onHostDestroy(this);
|
ReactActivityLifecycleCallbacks.onHostDestroy(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java
|
// ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java
|
||||||
|
@ -255,7 +257,7 @@ public class JitsiMeetActivity extends AppCompatActivity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReactActivityLifecycleAdapter.onNewIntent(intent);
|
ReactActivityLifecycleCallbacks.onNewIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -263,14 +265,14 @@ public class JitsiMeetActivity extends AppCompatActivity {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
defaultBackButtonImpl = new DefaultHardwareBackBtnHandlerImpl(this);
|
defaultBackButtonImpl = new DefaultHardwareBackBtnHandlerImpl(this);
|
||||||
ReactActivityLifecycleAdapter.onHostResume(this, defaultBackButtonImpl);
|
ReactActivityLifecycleCallbacks.onHostResume(this, defaultBackButtonImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
|
||||||
ReactActivityLifecycleAdapter.onHostPause(this);
|
ReactActivityLifecycleCallbacks.onHostPause(this);
|
||||||
defaultBackButtonImpl = null;
|
defaultBackButtonImpl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,15 @@ import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class JitsiMeetView extends BaseReactView {
|
public class JitsiMeetView
|
||||||
|
extends BaseReactView<JitsiMeetViewListener> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
|
* The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
|
||||||
* redux action types.
|
* redux action types.
|
||||||
*/
|
*/
|
||||||
private static final Map<String, Method> LISTENER_METHODS
|
private static final Map<String, Method> LISTENER_METHODS
|
||||||
= ListenerUtils.slurpListenerMethods(JitsiMeetViewListener.class);
|
= ListenerUtils.mapListenerMethods(JitsiMeetViewListener.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Log} tag which identifies the source of the log messages of
|
* The {@link Log} tag which identifies the source of the log messages of
|
||||||
|
@ -82,12 +84,6 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
*/
|
*/
|
||||||
private final InviteController inviteController;
|
private final InviteController inviteController;
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link JitsiMeetViewListener} instance for reporting events occurring in
|
|
||||||
* Jitsi Meet.
|
|
||||||
*/
|
|
||||||
private JitsiMeetViewListener listener;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether Picture-in-Picture is enabled. If {@code null}, defaults to
|
* Whether Picture-in-Picture is enabled. If {@code null}, defaults to
|
||||||
* {@code true} iff the Android platform supports Picture-in-Picture
|
* {@code true} iff the Android platform supports Picture-in-Picture
|
||||||
|
@ -125,7 +121,7 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
* page.
|
* page.
|
||||||
*/
|
*/
|
||||||
public void enterPictureInPicture() {
|
public void enterPictureInPicture() {
|
||||||
if (getPictureInPictureEnabled() && getURL() != null) {
|
if (isPictureInPictureEnabled() && getURL() != null) {
|
||||||
PictureInPictureModule pipModule
|
PictureInPictureModule pipModule
|
||||||
= ReactInstanceManagerHolder.getNativeModule(
|
= ReactInstanceManagerHolder.getNativeModule(
|
||||||
PictureInPictureModule.class);
|
PictureInPictureModule.class);
|
||||||
|
@ -166,31 +162,6 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
return inviteController;
|
return inviteController;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link JitsiMeetViewListener} set on this {@code JitsiMeetView}.
|
|
||||||
*
|
|
||||||
* @return The {@code JitsiMeetViewListener} set on this
|
|
||||||
* {@code JitsiMeetView}.
|
|
||||||
*/
|
|
||||||
public JitsiMeetViewListener getListener() {
|
|
||||||
return listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets whether Picture-in-Picture is enabled. Picture-in-Picture is
|
|
||||||
* natively supported on Android API >= 26 (Oreo), so it should not be
|
|
||||||
* enabled on older platform versions.
|
|
||||||
*
|
|
||||||
* @return If Picture-in-Picture is enabled, {@code true}; {@code false},
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
public boolean getPictureInPictureEnabled() {
|
|
||||||
return
|
|
||||||
PictureInPictureModule.isPictureInPictureSupported()
|
|
||||||
&& (pictureInPictureEnabled == null
|
|
||||||
|| pictureInPictureEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the URL of the current conference.
|
* Gets the URL of the current conference.
|
||||||
*
|
*
|
||||||
|
@ -204,6 +175,21 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether Picture-in-Picture is enabled. Picture-in-Picture is
|
||||||
|
* natively supported on Android API >= 26 (Oreo), so it should not be
|
||||||
|
* enabled on older platform versions.
|
||||||
|
*
|
||||||
|
* @return If Picture-in-Picture is enabled, {@code true}; {@code false},
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isPictureInPictureEnabled() {
|
||||||
|
return
|
||||||
|
PictureInPictureModule.isPictureInPictureSupported()
|
||||||
|
&& (pictureInPictureEnabled == null
|
||||||
|
|| pictureInPictureEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether the Welcome page is enabled. If {@code true}, the Welcome
|
* Gets whether the Welcome page is enabled. If {@code true}, the Welcome
|
||||||
* page is rendered when this {@code JitsiMeetView} is not at a URL
|
* page is rendered when this {@code JitsiMeetView} is not at a URL
|
||||||
|
@ -212,7 +198,7 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
* @return {@code true} if the Welcome page is enabled; otherwise,
|
* @return {@code true} if the Welcome page is enabled; otherwise,
|
||||||
* {@code false}.
|
* {@code false}.
|
||||||
*/
|
*/
|
||||||
public boolean getWelcomePageEnabled() {
|
public boolean isWelcomePageEnabled() {
|
||||||
return welcomePageEnabled;
|
return welcomePageEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +247,7 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
// pictureInPictureEnabled
|
// pictureInPictureEnabled
|
||||||
props.putBoolean(
|
props.putBoolean(
|
||||||
"pictureInPictureEnabled",
|
"pictureInPictureEnabled",
|
||||||
getPictureInPictureEnabled());
|
isPictureInPictureEnabled());
|
||||||
|
|
||||||
// url
|
// url
|
||||||
if (urlObject != null) {
|
if (urlObject != null) {
|
||||||
|
@ -334,8 +320,9 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
/**
|
/**
|
||||||
* Handler for {@link ExternalAPIModule} events.
|
* Handler for {@link ExternalAPIModule} events.
|
||||||
*
|
*
|
||||||
* @param name - Name of the event.
|
* @param name The name of the event.
|
||||||
* @param data - Event data.
|
* @param data The details/specifics of the event to send determined
|
||||||
|
* by/associated with the specified {@code name}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onExternalAPIEvent(String name, ReadableMap data) {
|
public void onExternalAPIEvent(String name, ReadableMap data) {
|
||||||
|
@ -346,11 +333,7 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
// UI thread.
|
// UI thread.
|
||||||
maybeSetViewURL(name, data);
|
maybeSetViewURL(name, data);
|
||||||
|
|
||||||
JitsiMeetViewListener listener = getListener();
|
onExternalAPIEvent(LISTENER_METHODS, name, data);
|
||||||
if (listener != null) {
|
|
||||||
ListenerUtils.runListenerMethod(
|
|
||||||
listener, LISTENER_METHODS, name, data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -366,17 +349,6 @@ public class JitsiMeetView extends BaseReactView {
|
||||||
this.defaultURL = defaultURL;
|
this.defaultURL = defaultURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a specific {@link JitsiMeetViewListener} on this
|
|
||||||
* {@code JitsiMeetView}.
|
|
||||||
*
|
|
||||||
* @param listener The {@code JitsiMeetViewListener} to set on this
|
|
||||||
* {@code JitsiMeetView}.
|
|
||||||
*/
|
|
||||||
public void setListener(JitsiMeetViewListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether Picture-in-Picture is enabled. Because Picture-in-Picture is
|
* Sets whether Picture-in-Picture is enabled. Because Picture-in-Picture is
|
||||||
* natively supported only since certain platform versions, specifying
|
* natively supported only since certain platform versions, specifying
|
||||||
|
|
|
@ -22,7 +22,9 @@ import java.util.Map;
|
||||||
* Implements {@link JitsiMeetViewListener} so apps don't have to add stubs for
|
* Implements {@link JitsiMeetViewListener} so apps don't have to add stubs for
|
||||||
* all methods in the interface if they are only interested in some.
|
* all methods in the interface if they are only interested in some.
|
||||||
*/
|
*/
|
||||||
public abstract class JitsiMeetViewAdapter implements JitsiMeetViewListener {
|
public abstract class JitsiMeetViewAdapter
|
||||||
|
implements JitsiMeetViewListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConferenceFailed(Map<String, Object> data) {
|
public void onConferenceFailed(Map<String, Object> data) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2018-present Atlassian Pty Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.jitsi.meet.sdk;
|
package org.jitsi.meet.sdk;
|
||||||
|
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
import com.facebook.react.bridge.ReadableMap;
|
||||||
|
@ -24,8 +40,8 @@ public final class ListenerUtils {
|
||||||
* @param listener - The listener whose methods we want to slurp.
|
* @param listener - The listener whose methods we want to slurp.
|
||||||
* @return A mapping with event names - methods.
|
* @return A mapping with event names - methods.
|
||||||
*/
|
*/
|
||||||
public static Map<String, Method> slurpListenerMethods(Class listener) {
|
public static Map<String, Method> mapListenerMethods(Class listener) {
|
||||||
final Map<String, Method> methods = new HashMap<>();
|
Map<String, Method> methods = new HashMap<>();
|
||||||
|
|
||||||
// Figure out the mapping between the listener methods
|
// Figure out the mapping between the listener methods
|
||||||
// and the events i.e. redux action types.
|
// and the events i.e. redux action types.
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2017-present Atlassian Pty Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.jitsi.meet.sdk;
|
package org.jitsi.meet.sdk;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
@ -11,7 +27,9 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
import com.facebook.react.bridge.ReactMethod;
|
||||||
|
|
||||||
public class PictureInPictureModule extends ReactContextBaseJavaModule {
|
class PictureInPictureModule
|
||||||
|
extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
private final static String TAG = "PictureInPicture";
|
private final static String TAG = "PictureInPicture";
|
||||||
|
|
||||||
static boolean isPictureInPictureSupported() {
|
static boolean isPictureInPictureSupported() {
|
||||||
|
|
|
@ -31,7 +31,9 @@ import com.facebook.react.bridge.UiThreadUtil;
|
||||||
* object it will dim the screen and disable touch controls. The functionality
|
* object it will dim the screen and disable touch controls. The functionality
|
||||||
* is used with the conference audio-only mode.
|
* is used with the conference audio-only mode.
|
||||||
*/
|
*/
|
||||||
class ProximityModule extends ReactContextBaseJavaModule {
|
class ProximityModule
|
||||||
|
extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of {@code ProximityModule} to be used in the React Native
|
* The name of {@code ProximityModule} to be used in the React Native
|
||||||
* bridge.
|
* bridge.
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2018-present Atlassian Pty Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.jitsi.meet.sdk;
|
package org.jitsi.meet.sdk;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
@ -7,18 +23,19 @@ import com.facebook.react.ReactInstanceManager;
|
||||||
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class to encapsulate the work which needs to be done on Activity
|
* Helper class to encapsulate the work which needs to be done on
|
||||||
* lifecycle methods in order for the React side to be aware of it.
|
* {@link Activity} lifecycle methods in order for the React side to be aware of
|
||||||
|
* it.
|
||||||
*/
|
*/
|
||||||
class ReactActivityLifecycleAdapter {
|
public class ReactActivityLifecycleCallbacks {
|
||||||
/**
|
/**
|
||||||
* Activity lifecycle method which should be called from
|
* {@link Activity} lifecycle method which should be called from
|
||||||
* {@code Activity.onBackPressed} so we can do the required internal
|
* {@link Activity#onBackPressed} so we can do the required internal
|
||||||
* processing.
|
* processing.
|
||||||
*
|
*
|
||||||
* @return {@code true} if the back-press was processed; {@code false},
|
* @return {@code true} if the back-press was processed; {@code false},
|
||||||
* otherwise. If {@code false}, the application should call the parent's
|
* otherwise. If {@code false}, the application should call the
|
||||||
* implementation.
|
* {@code super}'s implementation.
|
||||||
*/
|
*/
|
||||||
public static boolean onBackPressed() {
|
public static boolean onBackPressed() {
|
||||||
ReactInstanceManager reactInstanceManager
|
ReactInstanceManager reactInstanceManager
|
||||||
|
@ -33,8 +50,8 @@ class ReactActivityLifecycleAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity lifecycle method which should be called from
|
* {@link Activity} lifecycle method which should be called from
|
||||||
* {@code Activity.onDestroy} so we can do the required internal
|
* {@code Activity#onDestroy} so we can do the required internal
|
||||||
* processing.
|
* processing.
|
||||||
*
|
*
|
||||||
* @param activity {@code Activity} being destroyed.
|
* @param activity {@code Activity} being destroyed.
|
||||||
|
@ -49,8 +66,8 @@ class ReactActivityLifecycleAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity lifecycle method which should be called from
|
* {@link Activity} lifecycle method which should be called from
|
||||||
* {@code Activity.onPause} so we can do the required internal processing.
|
* {@code Activity#onPause} so we can do the required internal processing.
|
||||||
*
|
*
|
||||||
* @param activity {@code Activity} being paused.
|
* @param activity {@code Activity} being paused.
|
||||||
*/
|
*/
|
||||||
|
@ -64,8 +81,8 @@ class ReactActivityLifecycleAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity lifecycle method which should be called from
|
* {@link Activity} lifecycle method which should be called from
|
||||||
* {@code Activity.onResume} so we can do the required internal processing.
|
* {@code Activity#onResume} so we can do the required internal processing.
|
||||||
*
|
*
|
||||||
* @param activity {@code Activity} being resumed.
|
* @param activity {@code Activity} being resumed.
|
||||||
*/
|
*/
|
||||||
|
@ -74,16 +91,16 @@ class ReactActivityLifecycleAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity lifecycle method which should be called from
|
* {@link Activity} lifecycle method which should be called from
|
||||||
* {@code Activity.onResume} so we can do the required internal processing.
|
* {@code Activity#onResume} so we can do the required internal processing.
|
||||||
*
|
*
|
||||||
* @param activity {@code Activity} being resumed.
|
* @param activity {@code Activity} being resumed.
|
||||||
* @param defaultBackButtonImpl a {@code DefaultHardwareBackBtnHandler} to
|
* @param defaultBackButtonImpl a {@link DefaultHardwareBackBtnHandler} to
|
||||||
* handle invoking the back button if no {@code JitsiMeetView} handles it.
|
* handle invoking the back button if no {@link BaseReactView} handles it.
|
||||||
*/
|
*/
|
||||||
public static void onHostResume(
|
public static void onHostResume(
|
||||||
Activity activity,
|
Activity activity,
|
||||||
DefaultHardwareBackBtnHandler defaultBackButtonImpl) {
|
DefaultHardwareBackBtnHandler defaultBackButtonImpl) {
|
||||||
ReactInstanceManager reactInstanceManager
|
ReactInstanceManager reactInstanceManager
|
||||||
= ReactInstanceManagerHolder.getReactInstanceManager();
|
= ReactInstanceManagerHolder.getReactInstanceManager();
|
||||||
|
|
||||||
|
@ -93,8 +110,8 @@ class ReactActivityLifecycleAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activity lifecycle method which should be called from
|
* {@link Activity} lifecycle method which should be called from
|
||||||
* {@code Activity.onNewIntent} so we can do the required internal
|
* {@code Activity#onNewIntent} so we can do the required internal
|
||||||
* processing. Note that this is only needed if the activity's "launchMode"
|
* processing. Note that this is only needed if the activity's "launchMode"
|
||||||
* was set to "singleTask". This is required for deep linking to work once
|
* was set to "singleTask". This is required for deep linking to work once
|
||||||
* the application is already running.
|
* the application is already running.
|
||||||
|
@ -109,5 +126,4 @@ class ReactActivityLifecycleAdapter {
|
||||||
reactInstanceManager.onNewIntent(intent);
|
reactInstanceManager.onNewIntent(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -28,7 +28,7 @@ import com.facebook.react.common.LifecycleState;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ReactInstanceManagerHolder {
|
class ReactInstanceManagerHolder {
|
||||||
/**
|
/**
|
||||||
* React Native bridge. The instance manager allows embedding applications
|
* React Native bridge. The instance manager allows embedding applications
|
||||||
* to create multiple root views off the same JavaScript bundle.
|
* to create multiple root views off the same JavaScript bundle.
|
||||||
|
|
|
@ -25,7 +25,9 @@ import com.facebook.react.uimanager.ViewManager;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ReactPackageAdapter implements ReactPackage {
|
class ReactPackageAdapter
|
||||||
|
implements ReactPackage {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<NativeModule> createNativeModules(
|
public List<NativeModule> createNativeModules(
|
||||||
ReactApplicationContext reactContext) {
|
ReactApplicationContext reactContext) {
|
||||||
|
|
|
@ -40,10 +40,12 @@ import java.util.Enumeration;
|
||||||
/**
|
/**
|
||||||
* Module exposing WiFi statistics.
|
* Module exposing WiFi statistics.
|
||||||
*
|
*
|
||||||
* Gathers rssi, signal in percentage, timestamp and the addresses
|
* Gathers rssi, signal in percentage, timestamp and the addresses of the wifi
|
||||||
* of the wifi device.
|
* device.
|
||||||
*/
|
*/
|
||||||
class WiFiStatsModule extends ReactContextBaseJavaModule {
|
class WiFiStatsModule
|
||||||
|
extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of {@code WiFiStatsModule} to be used in the React Native
|
* The name of {@code WiFiStatsModule} to be used in the React Native
|
||||||
* bridge.
|
* bridge.
|
||||||
|
@ -56,9 +58,8 @@ class WiFiStatsModule extends ReactContextBaseJavaModule {
|
||||||
static final String TAG = MODULE_NAME;
|
static final String TAG = MODULE_NAME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scale used for the signal value.
|
* The scale used for the signal value. A level of the signal, given in the
|
||||||
* A level of the signal, given in the range
|
* range of 0 to SIGNAL_LEVEL_SCALE-1 (both inclusive).
|
||||||
* of 0 to SIGNAL_LEVEL_SCALE-1 (both inclusive).
|
|
||||||
*/
|
*/
|
||||||
public final static int SIGNAL_LEVEL_SCALE = 101;
|
public final static int SIGNAL_LEVEL_SCALE = 101;
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ class WiFiStatsModule extends ReactContextBaseJavaModule {
|
||||||
* {@link Handler} for running all operations on the main thread.
|
* {@link Handler} for running all operations on the main thread.
|
||||||
*/
|
*/
|
||||||
private final Handler mainThreadHandler
|
private final Handler mainThreadHandler
|
||||||
= new Handler(Looper.getMainLooper());
|
= new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a new module instance. There shall be a single instance of
|
* Initializes a new module instance. There shall be a single instance of
|
||||||
|
@ -119,7 +120,6 @@ class WiFiStatsModule extends ReactContextBaseJavaModule {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
Context context
|
Context context
|
||||||
= getReactApplicationContext().getApplicationContext();
|
= getReactApplicationContext().getApplicationContext();
|
||||||
WifiManager wifiManager
|
WifiManager wifiManager
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class IncomingCallInfo {
|
||||||
/**
|
/**
|
||||||
* URL for the caller avatar.
|
* URL for the caller avatar.
|
||||||
*/
|
*/
|
||||||
private final String callerAvatarUrl;
|
private final String callerAvatarURL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caller's name.
|
* Caller's name.
|
||||||
|
@ -36,23 +36,25 @@ public class IncomingCallInfo {
|
||||||
|
|
||||||
public IncomingCallInfo(
|
public IncomingCallInfo(
|
||||||
@NonNull String callerName,
|
@NonNull String callerName,
|
||||||
@NonNull String callerAvatarUrl,
|
@NonNull String callerAvatarURL,
|
||||||
boolean hasVideo) {
|
boolean hasVideo) {
|
||||||
this.callerName = callerName;
|
this.callerName = callerName;
|
||||||
this.callerAvatarUrl = callerAvatarUrl;
|
this.callerAvatarURL = callerAvatarURL;
|
||||||
this.hasVideo = hasVideo;
|
this.hasVideo = hasVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the caller's avatar URL.
|
* Gets the caller's avatar URL.
|
||||||
|
*
|
||||||
* @return - The URL as a string.
|
* @return - The URL as a string.
|
||||||
*/
|
*/
|
||||||
public String getCallerAvatarUrl() {
|
public String getCallerAvatarURL() {
|
||||||
return callerAvatarUrl;
|
return callerAvatarURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the caller's name.
|
* Gets the caller's name.
|
||||||
|
*
|
||||||
* @return - The caller's name.
|
* @return - The caller's name.
|
||||||
*/
|
*/
|
||||||
public String getCallerName() {
|
public String getCallerName() {
|
||||||
|
@ -61,7 +63,8 @@ public class IncomingCallInfo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether the call is a video call or not.
|
* Gets whether the call is a video call or not.
|
||||||
* @return - True if this call has video, false otherwise.
|
*
|
||||||
|
* @return - {@code true} if this call has video; {@code false}, otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean hasVideo() {
|
public boolean hasVideo() {
|
||||||
return hasVideo;
|
return hasVideo;
|
||||||
|
|
|
@ -28,20 +28,15 @@ import org.jitsi.meet.sdk.ListenerUtils;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class IncomingCallView
|
||||||
|
extends BaseReactView<IncomingCallViewListener> {
|
||||||
|
|
||||||
public class IncomingCallView extends BaseReactView {
|
|
||||||
/**
|
/**
|
||||||
* The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
|
* The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
|
||||||
* redux action types.
|
* redux action types.
|
||||||
*/
|
*/
|
||||||
private static final Map<String, Method> LISTENER_METHODS
|
private static final Map<String, Method> LISTENER_METHODS
|
||||||
= ListenerUtils.slurpListenerMethods(IncomingCallViewListener.class);
|
= ListenerUtils.mapListenerMethods(IncomingCallViewListener.class);
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link IncomingCallViewListener} instance for reporting events occurring
|
|
||||||
* in Jitsi Meet.
|
|
||||||
*/
|
|
||||||
private IncomingCallViewListener listener;
|
|
||||||
|
|
||||||
public IncomingCallView(@NonNull Context context) {
|
public IncomingCallView(@NonNull Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
|
@ -50,27 +45,13 @@ public class IncomingCallView extends BaseReactView {
|
||||||
/**
|
/**
|
||||||
* Handler for {@link ExternalAPIModule} events.
|
* Handler for {@link ExternalAPIModule} events.
|
||||||
*
|
*
|
||||||
* @param name - Name of the event.
|
* @param name The name of the event.
|
||||||
* @param data - Event data.
|
* @param data The details/specifics of the event to send determined
|
||||||
|
* by/associated with the specified {@code name}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onExternalAPIEvent(String name, ReadableMap data) {
|
public void onExternalAPIEvent(String name, ReadableMap data) {
|
||||||
IncomingCallViewListener listener = getListener();
|
onExternalAPIEvent(LISTENER_METHODS, name, data);
|
||||||
if (listener != null) {
|
|
||||||
ListenerUtils.runListenerMethod(
|
|
||||||
listener, LISTENER_METHODS, name, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link IncomingCallViewListener} set on this
|
|
||||||
* {@code IncomingCallView}.
|
|
||||||
*
|
|
||||||
* @return The {@code IncomingCallViewListener} set on this
|
|
||||||
* {@code IncomingCallView}.
|
|
||||||
*/
|
|
||||||
public IncomingCallViewListener getListener() {
|
|
||||||
return listener;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,27 +59,15 @@ public class IncomingCallView extends BaseReactView {
|
||||||
* represents.
|
* represents.
|
||||||
*
|
*
|
||||||
* @param callInfo - {@link IncomingCallInfo} object representing the caller
|
* @param callInfo - {@link IncomingCallInfo} object representing the caller
|
||||||
* information.
|
* information.
|
||||||
*/
|
*/
|
||||||
public void setIncomingCallInfo(IncomingCallInfo callInfo) {
|
public void setIncomingCallInfo(IncomingCallInfo callInfo) {
|
||||||
Bundle props = new Bundle();
|
Bundle props = new Bundle();
|
||||||
|
|
||||||
props.putString("callerAvatarUrl", callInfo.getCallerAvatarUrl());
|
props.putString("callerAvatarURL", callInfo.getCallerAvatarURL());
|
||||||
props.putString("callerName", callInfo.getCallerName());
|
props.putString("callerName", callInfo.getCallerName());
|
||||||
props.putBoolean("hasVideo", callInfo.hasVideo());
|
props.putBoolean("hasVideo", callInfo.hasVideo());
|
||||||
|
|
||||||
createReactRootView("IncomingCallApp", props);
|
createReactRootView("IncomingCallApp", props);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a specific {@link IncomingCallViewListener} on this
|
|
||||||
* {@code IncomingCallView}.
|
|
||||||
*
|
|
||||||
* @param listener The {@code IncomingCallViewListener} to set on this
|
|
||||||
* {@code IncomingCallView}.
|
|
||||||
*/
|
|
||||||
public void setListener(IncomingCallViewListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for listening to events coming from Jitsi Meet, related to
|
* Interface for listening to events coming from Jitsi Meet, related to
|
||||||
* {@link IncomingCallView};
|
* {@link IncomingCallView}.
|
||||||
*/
|
*/
|
||||||
public interface IncomingCallViewListener {
|
public interface IncomingCallViewListener {
|
||||||
/**
|
/**
|
||||||
* Called when the user presses the "answer" button on the
|
* Called when the user presses the "Answer" button on the
|
||||||
* {@link IncomingCallView}.
|
* {@link IncomingCallView}.
|
||||||
*
|
*
|
||||||
* @param data - Unused at the moment.
|
* @param data - Unused at the moment.
|
||||||
|
@ -32,7 +32,7 @@ public interface IncomingCallViewListener {
|
||||||
void onIncomingCallAnswered(Map<String, Object> data);
|
void onIncomingCallAnswered(Map<String, Object> data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the user presses the "decline" button on the
|
* Called when the user presses the "Decline" button on the
|
||||||
* {@link IncomingCallView}.
|
* {@link IncomingCallView}.
|
||||||
*
|
*
|
||||||
* @param data - Unused at the moment.
|
* @param data - Unused at the moment.
|
||||||
|
|
|
@ -33,7 +33,8 @@ import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller object used by native code to query and submit user selections for the user invitation flow.
|
* Controller object used by native code to query and submit user selections for
|
||||||
|
* the user invitation flow.
|
||||||
*/
|
*/
|
||||||
public class AddPeopleController {
|
public class AddPeopleController {
|
||||||
|
|
||||||
|
@ -44,17 +45,18 @@ public class AddPeopleController {
|
||||||
private AddPeopleControllerListener listener;
|
private AddPeopleControllerListener listener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local cache of search query results. Used to re-hydrate the list
|
* Local cache of search query results. Used to re-hydrate the list of
|
||||||
* of selected items based on their ids passed to inviteById
|
* selected items based on their ids passed to inviteById in order to pass
|
||||||
* in order to pass the full item maps back to the JitsiMeetView during submission.
|
* the full item maps back to the JitsiMeetView during submission.
|
||||||
*/
|
*/
|
||||||
private final Map<String, ReadableMap> items = new HashMap<>();
|
private final Map<String, ReadableMap> items = new HashMap<>();
|
||||||
|
|
||||||
private final WeakReference<InviteController> owner;
|
private final WeakReference<InviteController> owner;
|
||||||
|
|
||||||
private final WeakReference<ReactApplicationContext> reactContext;
|
private final WeakReference<ReactApplicationContext> reactContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Randomly generated UUID, used for identification in the InviteModule
|
* Randomly generated UUID, used for identification in the InviteModule.
|
||||||
*/
|
*/
|
||||||
private final String uuid = UUID.randomUUID().toString();
|
private final String uuid = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
@ -158,10 +160,10 @@ public class AddPeopleController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches results received by the search into a local map for use
|
* Caches results received by the search into a local map for use later when
|
||||||
* later when the items are submitted. Submission requires the full
|
* the items are submitted. Submission requires the full map of
|
||||||
* map of information, but only the IDs are returned back to the delegate.
|
* information, but only the IDs are returned back to the delegate. Using
|
||||||
* Using this map means we don't have to send the whole map back to the delegate.
|
* this map means we don't have to send the whole map back to the delegate.
|
||||||
*
|
*
|
||||||
* @param results
|
* @param results
|
||||||
* @param query
|
* @param query
|
||||||
|
@ -179,10 +181,15 @@ public class AddPeopleController {
|
||||||
|
|
||||||
if(map.hasKey("id")) {
|
if(map.hasKey("id")) {
|
||||||
items.put(map.getString("id"), map);
|
items.put(map.getString("id"), map);
|
||||||
} else if(map.hasKey("type") && map.getString("type").equals("phone") && map.hasKey("number")) {
|
} else if(map.hasKey("type")
|
||||||
|
&& map.getString("type").equals("phone")
|
||||||
|
&& map.hasKey("number")) {
|
||||||
items.put(map.getString("number"), map);
|
items.put(map.getString("number"), map);
|
||||||
} else {
|
} else {
|
||||||
Log.w("AddPeopleController", "Received result without id and that was not a phone number, so not adding it to suggestions: " + map);
|
Log.w(
|
||||||
|
"AddPeopleController",
|
||||||
|
"Received result without id and that was not a phone number, so not adding it to suggestions: "
|
||||||
|
+ map);
|
||||||
}
|
}
|
||||||
|
|
||||||
jvmResults.add(map.toHashMap());
|
jvmResults.add(map.toHashMap());
|
||||||
|
|
|
@ -202,9 +202,9 @@ public class InviteController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a query for users to invite to the conference. Results will be
|
* Starts a query for users to invite to the conference. Results will be
|
||||||
* returned through the {@link AddPeopleControllerListener#onReceivedResults(AddPeopleController, List, String)}
|
* returned through
|
||||||
* method.
|
* {@link AddPeopleControllerListener#onReceivedResults(AddPeopleController, List, String)}.
|
||||||
*
|
*
|
||||||
* @param query {@code String} to use for the query
|
* @param query {@code String} to use for the query
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -20,10 +20,10 @@ public interface InviteControllerListener {
|
||||||
/**
|
/**
|
||||||
* Called when the add user button is tapped.
|
* Called when the add user button is tapped.
|
||||||
*
|
*
|
||||||
* @param addPeopleController {@code AddPeopleController} scoped
|
* @param addPeopleController {@code AddPeopleController} scoped for this
|
||||||
* for this user invite flow. The {@code AddPeopleController} is used
|
* user invite flow. The {@code AddPeopleController} is used to start user
|
||||||
* to start user queries and accepts an {@code AddPeopleControllerListener}
|
* queries and accepts an {@code AddPeopleControllerListener} for receiving
|
||||||
* for receiving user query responses.
|
* user query responses.
|
||||||
*/
|
*/
|
||||||
void beginAddPeople(AddPeopleController addPeopleController);
|
void beginAddPeople(AddPeopleController addPeopleController);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,9 @@ import org.jitsi.meet.sdk.JitsiMeetView;
|
||||||
/**
|
/**
|
||||||
* Implements the react-native module of the feature invite.
|
* Implements the react-native module of the feature invite.
|
||||||
*/
|
*/
|
||||||
public class InviteModule extends ReactContextBaseJavaModule {
|
public class InviteModule
|
||||||
|
extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
public InviteModule(ReactApplicationContext reactContext) {
|
public InviteModule(ReactApplicationContext reactContext) {
|
||||||
super(reactContext);
|
super(reactContext);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +70,8 @@ public class InviteModule extends ReactContextBaseJavaModule {
|
||||||
private InviteController findInviteControllerByExternalAPIScope(
|
private InviteController findInviteControllerByExternalAPIScope(
|
||||||
String externalAPIScope) {
|
String externalAPIScope) {
|
||||||
JitsiMeetView view
|
JitsiMeetView view
|
||||||
= (JitsiMeetView)BaseReactView.findViewByExternalAPIScope(externalAPIScope);
|
= (JitsiMeetView)
|
||||||
|
BaseReactView.findViewByExternalAPIScope(externalAPIScope);
|
||||||
|
|
||||||
return view == null ? null : view.getInviteController();
|
return view == null ? null : view.getInviteController();
|
||||||
}
|
}
|
||||||
|
@ -82,7 +85,8 @@ public class InviteModule extends ReactContextBaseJavaModule {
|
||||||
* Callback for invitation failures
|
* Callback for invitation failures
|
||||||
*
|
*
|
||||||
* @param failedInvitees the items for which the invitation failed
|
* @param failedInvitees the items for which the invitation failed
|
||||||
* @param addPeopleControllerScope a string that represents a connection to a specific AddPeopleController
|
* @param addPeopleControllerScope a string that represents a connection to
|
||||||
|
* a specific AddPeopleController
|
||||||
*/
|
*/
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void inviteSettled(
|
public void inviteSettled(
|
||||||
|
@ -124,7 +128,8 @@ public class InviteModule extends ReactContextBaseJavaModule {
|
||||||
*
|
*
|
||||||
* @param results the results in a ReadableArray of ReadableMap objects
|
* @param results the results in a ReadableArray of ReadableMap objects
|
||||||
* @param query the query associated with the search
|
* @param query the query associated with the search
|
||||||
* @param addPeopleControllerScope a string that represents a connection to a specific AddPeopleController
|
* @param addPeopleControllerScope a string that represents a connection to
|
||||||
|
* a specific AddPeopleController
|
||||||
*/
|
*/
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void receivedResults(
|
public void receivedResults(
|
||||||
|
|
|
@ -32,7 +32,9 @@ import java.net.UnknownHostException;
|
||||||
* [1]: https://tools.ietf.org/html/rfc6146
|
* [1]: https://tools.ietf.org/html/rfc6146
|
||||||
* [2]: https://tools.ietf.org/html/rfc6052
|
* [2]: https://tools.ietf.org/html/rfc6052
|
||||||
*/
|
*/
|
||||||
public class NAT64AddrInfoModule extends ReactContextBaseJavaModule {
|
public class NAT64AddrInfoModule
|
||||||
|
extends ReactContextBaseJavaModule {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The host for which the module wil try to resolve both IPv4 and IPv6
|
* The host for which the module wil try to resolve both IPv4 and IPv6
|
||||||
* addresses in order to figure out the NAT64 prefix.
|
* addresses in order to figure out the NAT64 prefix.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* The type of redux action to answer an incoming call.
|
* The type of redux action to answer an incoming call.
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
* type: INCOMING_CALL_ANSWERED,
|
* type: INCOMING_CALL_ANSWERED
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
export const INCOMING_CALL_ANSWERED = Symbol('INCOMING_CALL_ANSWERED');
|
export const INCOMING_CALL_ANSWERED = Symbol('INCOMING_CALL_ANSWERED');
|
||||||
|
@ -11,7 +11,7 @@ export const INCOMING_CALL_ANSWERED = Symbol('INCOMING_CALL_ANSWERED');
|
||||||
* The type of redux action to decline an incoming call.
|
* The type of redux action to decline an incoming call.
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
* type: INCOMING_CALL_DECLINED,
|
* type: INCOMING_CALL_DECLINED
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
export const INCOMING_CALL_DECLINED = Symbol('INCOMING_CALL_DECLINED');
|
export const INCOMING_CALL_DECLINED = Symbol('INCOMING_CALL_DECLINED');
|
||||||
|
|
|
@ -2,12 +2,15 @@
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { AbstractButton } from '../../../base/toolbox';
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n';
|
||||||
|
import { AbstractButton } from '../../../base/toolbox';
|
||||||
import type { AbstractButtonProps } from '../../../base/toolbox';
|
import type { AbstractButtonProps } from '../../../base/toolbox';
|
||||||
|
|
||||||
import { incomingCallAnswered } from '../actions';
|
import { incomingCallAnswered } from '../actions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} props of {@link AnswerButton}.
|
||||||
|
*/
|
||||||
type Props = AbstractButtonProps & {
|
type Props = AbstractButtonProps & {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +20,7 @@ type Props = AbstractButtonProps & {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of a button which accepts an incoming call.
|
* An implementation of a button which accepts/answers an incoming call.
|
||||||
*/
|
*/
|
||||||
class AnswerButton extends AbstractButton<Props, *> {
|
class AnswerButton extends AbstractButton<Props, *> {
|
||||||
accessibilityLabel = 'incomingCall.answer';
|
accessibilityLabel = 'incomingCall.answer';
|
||||||
|
@ -33,7 +36,6 @@ class AnswerButton extends AbstractButton<Props, *> {
|
||||||
_handleClick() {
|
_handleClick() {
|
||||||
this.props.dispatch(incomingCallAnswered());
|
this.props.dispatch(incomingCallAnswered());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect()(AnswerButton));
|
export default translate(connect()(AnswerButton));
|
||||||
|
|
|
@ -2,12 +2,15 @@
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { AbstractButton } from '../../../base/toolbox';
|
|
||||||
import { translate } from '../../../base/i18n';
|
import { translate } from '../../../base/i18n';
|
||||||
|
import { AbstractButton } from '../../../base/toolbox';
|
||||||
import type { AbstractButtonProps } from '../../../base/toolbox';
|
import type { AbstractButtonProps } from '../../../base/toolbox';
|
||||||
|
|
||||||
import { incomingCallDeclined } from '../actions';
|
import { incomingCallDeclined } from '../actions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} props of {@link DeclineButton}.
|
||||||
|
*/
|
||||||
type Props = AbstractButtonProps & {
|
type Props = AbstractButtonProps & {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +20,7 @@ type Props = AbstractButtonProps & {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of a button which rejects an incoming call.
|
* An implementation of a button which declines/rejects an incoming call.
|
||||||
*/
|
*/
|
||||||
class DeclineButton extends AbstractButton<Props, *> {
|
class DeclineButton extends AbstractButton<Props, *> {
|
||||||
accessibilityLabel = 'incomingCall.decline';
|
accessibilityLabel = 'incomingCall.decline';
|
||||||
|
@ -33,7 +36,6 @@ class DeclineButton extends AbstractButton<Props, *> {
|
||||||
_handleClick() {
|
_handleClick() {
|
||||||
this.props.dispatch(incomingCallDeclined());
|
this.props.dispatch(incomingCallDeclined());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default translate(connect()(DeclineButton));
|
export default translate(connect()(DeclineButton));
|
||||||
|
|
|
@ -3,15 +3,17 @@
|
||||||
import { BaseApp } from '../../../base/app';
|
import { BaseApp } from '../../../base/app';
|
||||||
|
|
||||||
import { incomingCallReceived } from '../actions';
|
import { incomingCallReceived } from '../actions';
|
||||||
|
|
||||||
import IncomingCallPage from './IncomingCallPage';
|
import IncomingCallPage from './IncomingCallPage';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} props of {@link IncomingCallApp}.
|
||||||
|
*/
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL of the avatar for the caller.
|
* URL of the avatar for the caller.
|
||||||
*/
|
*/
|
||||||
callerAvatarUrl: string,
|
callerAvatarURL: string,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the caller.
|
* Name of the caller.
|
||||||
|
@ -35,8 +37,9 @@ export default class IncomingCallApp extends BaseApp<Props> {
|
||||||
/**
|
/**
|
||||||
* Navigates to {@link IncomingCallPage} upon mount.
|
* Navigates to {@link IncomingCallPage} upon mount.
|
||||||
*
|
*
|
||||||
* NOTE: This was implmented here instead of in a middleware for
|
* NOTE: This was implmented here instead of in a middleware for the
|
||||||
* the APP_WILL_MOUNT action because that would run also for {@link App}.
|
* {@link APP_WILL_MOUNT} action because that would run also for
|
||||||
|
* {@link App}.
|
||||||
*
|
*
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
|
@ -46,15 +49,15 @@ export default class IncomingCallApp extends BaseApp<Props> {
|
||||||
this._init.then(() => {
|
this._init.then(() => {
|
||||||
const { dispatch } = this.state.store;
|
const { dispatch } = this.state.store;
|
||||||
const {
|
const {
|
||||||
callerAvatarUrl: avatarUrl,
|
callerAvatarURL: avatarUrl,
|
||||||
callerName: name,
|
callerName: name,
|
||||||
hasVideo
|
hasVideo
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
dispatch(incomingCallReceived({
|
dispatch(incomingCallReceived({
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
name,
|
hasVideo,
|
||||||
hasVideo
|
name
|
||||||
}));
|
}));
|
||||||
|
|
||||||
super._navigate({ component: IncomingCallPage });
|
super._navigate({ component: IncomingCallPage });
|
||||||
|
|
|
@ -24,7 +24,7 @@ type Props = {
|
||||||
/**
|
/**
|
||||||
* Caller's avatar URL.
|
* Caller's avatar URL.
|
||||||
*/
|
*/
|
||||||
_callerAvatarUrl: string,
|
_callerAvatarURL: string,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caller's name.
|
* Caller's name.
|
||||||
|
@ -63,7 +63,7 @@ class IncomingCallPage extends Component<Props> {
|
||||||
<View style = { styles.pageContainer }>
|
<View style = { styles.pageContainer }>
|
||||||
<View style = { styles.backgroundAvatar }>
|
<View style = { styles.backgroundAvatar }>
|
||||||
<Image
|
<Image
|
||||||
source = {{ uri: this.props._callerAvatarUrl }}
|
source = {{ uri: this.props._callerAvatarURL }}
|
||||||
style = { styles.backgroundAvatarImage } />
|
style = { styles.backgroundAvatarImage } />
|
||||||
</View>
|
</View>
|
||||||
<LinearGradient
|
<LinearGradient
|
||||||
|
@ -86,27 +86,6 @@ class IncomingCallPage extends Component<Props> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders caller avatar.
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @returns {React$Node}
|
|
||||||
*/
|
|
||||||
_renderCallerAvatar() {
|
|
||||||
return (
|
|
||||||
<View style = { styles.avatarContainer }>
|
|
||||||
<LinearGradient
|
|
||||||
colors = { AVATAR_BORDER_GRADIENT }
|
|
||||||
style = { styles.avatarBorder } />
|
|
||||||
<View style = { styles.avatar }>
|
|
||||||
<Avatar
|
|
||||||
size = { CALLER_AVATAR_SIZE }
|
|
||||||
uri = { this.props._callerAvatarUrl } />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders buttons.
|
* Renders buttons.
|
||||||
*
|
*
|
||||||
|
@ -135,6 +114,27 @@ class IncomingCallPage extends Component<Props> {
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders caller avatar.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @returns {React$Node}
|
||||||
|
*/
|
||||||
|
_renderCallerAvatar() {
|
||||||
|
return (
|
||||||
|
<View style = { styles.avatarContainer }>
|
||||||
|
<LinearGradient
|
||||||
|
colors = { AVATAR_BORDER_GRADIENT }
|
||||||
|
style = { styles.avatarBorder } />
|
||||||
|
<View style = { styles.avatar }>
|
||||||
|
<Avatar
|
||||||
|
size = { CALLER_AVATAR_SIZE }
|
||||||
|
uri = { this.props._callerAvatarURL } />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,8 +144,8 @@ class IncomingCallPage extends Component<Props> {
|
||||||
* @param {Object} ownProps - The component's own props.
|
* @param {Object} ownProps - The component's own props.
|
||||||
* @private
|
* @private
|
||||||
* @returns {{
|
* @returns {{
|
||||||
|
* _callerAvatarURL: string,
|
||||||
* _callerName: string,
|
* _callerName: string,
|
||||||
* _callerAvatarUrl: string,
|
|
||||||
* _hasVideo: boolean
|
* _hasVideo: boolean
|
||||||
* }}
|
* }}
|
||||||
*/
|
*/
|
||||||
|
@ -159,7 +159,7 @@ function _mapStateToProps(state) {
|
||||||
* @private
|
* @private
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
_callerAvatarUrl: caller.avatarUrl,
|
_callerAvatarURL: caller.avatarUrl,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The caller's name.
|
* The caller's name.
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import {
|
import { ColorPalette, createStyleSheet } from '../../../base/styles';
|
||||||
ColorPalette,
|
|
||||||
createStyleSheet
|
|
||||||
} from '../../../base/styles';
|
|
||||||
|
|
||||||
export const AVATAR_BORDER_GRADIENT = [ '#4C9AFF', '#0052CC' ];
|
export const AVATAR_BORDER_GRADIENT = [ '#4C9AFF', '#0052CC' ];
|
||||||
|
|
||||||
|
@ -9,17 +6,17 @@ export const BACKGROUND_OVERLAY_GRADIENT = [ '#0052CC', '#4C9AFF' ];
|
||||||
|
|
||||||
const BUTTON_SIZE = 56;
|
const BUTTON_SIZE = 56;
|
||||||
|
|
||||||
export const CALLER_AVATAR_SIZE = 128;
|
|
||||||
|
|
||||||
const CALLER_AVATAR_BORDER_WIDTH = 3;
|
const CALLER_AVATAR_BORDER_WIDTH = 3;
|
||||||
|
|
||||||
|
export const CALLER_AVATAR_SIZE = 128;
|
||||||
|
|
||||||
const CALLER_AVATAR_CIRCLE_SIZE
|
const CALLER_AVATAR_CIRCLE_SIZE
|
||||||
= CALLER_AVATAR_SIZE + (2 * CALLER_AVATAR_BORDER_WIDTH);
|
= CALLER_AVATAR_SIZE + (2 * CALLER_AVATAR_BORDER_WIDTH);
|
||||||
|
|
||||||
const PAGE_PADDING = 48;
|
|
||||||
|
|
||||||
const LINE_SPACING = 8;
|
const LINE_SPACING = 8;
|
||||||
|
|
||||||
|
const PAGE_PADDING = 48;
|
||||||
|
|
||||||
const _icon = {
|
const _icon = {
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
color: ColorPalette.white,
|
color: ColorPalette.white,
|
||||||
|
@ -58,9 +55,9 @@ export default createStyleSheet({
|
||||||
},
|
},
|
||||||
|
|
||||||
avatar: {
|
avatar: {
|
||||||
position: 'absolute',
|
|
||||||
marginLeft: CALLER_AVATAR_BORDER_WIDTH,
|
marginLeft: CALLER_AVATAR_BORDER_WIDTH,
|
||||||
marginTop: CALLER_AVATAR_BORDER_WIDTH
|
marginTop: CALLER_AVATAR_BORDER_WIDTH,
|
||||||
|
position: 'absolute'
|
||||||
},
|
},
|
||||||
|
|
||||||
avatarBorder: {
|
avatarBorder: {
|
||||||
|
|
|
@ -5,14 +5,11 @@ import { getSymbolDescription } from '../../base/util';
|
||||||
|
|
||||||
import { sendEvent } from '../external-api';
|
import { sendEvent } from '../external-api';
|
||||||
|
|
||||||
import {
|
import { INCOMING_CALL_ANSWERED, INCOMING_CALL_DECLINED } from './actionTypes';
|
||||||
INCOMING_CALL_ANSWERED,
|
|
||||||
INCOMING_CALL_DECLINED
|
|
||||||
} from './actionTypes';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Middleware that captures Redux actions and uses the IncomingCallExternalAPI
|
* Middleware that captures redux actions and uses the ExternalAPI module to
|
||||||
* module to turn them into native events so the application knows about them.
|
* turn them into native events so the app knows about them.
|
||||||
*
|
*
|
||||||
* @param {Store} store - The redux store.
|
* @param {Store} store - The redux store.
|
||||||
* @returns {Function}
|
* @returns {Function}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* @flow */
|
// @flow
|
||||||
|
|
||||||
import { assign, ReducerRegistry } from '../../base/redux';
|
import { ReducerRegistry, set } from '../../base/redux';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
INCOMING_CALL_ANSWERED,
|
INCOMING_CALL_ANSWERED,
|
||||||
|
@ -13,13 +13,10 @@ ReducerRegistry.register(
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case INCOMING_CALL_ANSWERED:
|
case INCOMING_CALL_ANSWERED:
|
||||||
case INCOMING_CALL_DECLINED:
|
case INCOMING_CALL_DECLINED:
|
||||||
return assign(state, {
|
return set(state, 'caller', undefined);
|
||||||
caller: undefined
|
|
||||||
});
|
|
||||||
case INCOMING_CALL_RECEIVED:
|
case INCOMING_CALL_RECEIVED:
|
||||||
return assign(state, {
|
return set(state, 'caller', action.caller);
|
||||||
caller: action.caller
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
|
|
@ -21,6 +21,9 @@ import { App } from './features/app';
|
||||||
import { equals } from './features/base/redux';
|
import { equals } from './features/base/redux';
|
||||||
import { IncomingCallApp } from './features/mobile/incoming-call';
|
import { IncomingCallApp } from './features/mobile/incoming-call';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} props of {@link Root}.
|
||||||
|
*/
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,6 +32,9 @@ type Props = {
|
||||||
url: Object | string
|
url: Object | string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of the React {@code Component} state of {@link Root}.
|
||||||
|
*/
|
||||||
type State = {
|
type State = {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,8 +147,8 @@ class Root extends Component<Props, State> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the main/root Component.
|
// Register the main/root Component of JitsiMeetView.
|
||||||
AppRegistry.registerComponent('App', () => Root);
|
AppRegistry.registerComponent('App', () => Root);
|
||||||
|
|
||||||
// Register the incoming call Component.
|
// Register the main/root Component of IncomingCallView.
|
||||||
AppRegistry.registerComponent('IncomingCallApp', () => IncomingCallApp);
|
AppRegistry.registerComponent('IncomingCallApp', () => IncomingCallApp);
|
||||||
|
|
Loading…
Reference in New Issue