@amazon-devices/react-native-safe-area-context 2.0.9000000000 → 2.0.9000000001
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SystemBundles/{85c8d24b7f717b77a2deb00e32cc2aaa293a5a16c46eecebca21e95bda425730.bundle → 51fc85bf8d38b1dffede0d601b4549191dcfd495b78de3007c0b6f0f183163ac.bundle} +805 -2723
- package/SystemBundles/51fc85bf8d38b1dffede0d601b4549191dcfd495b78de3007c0b6f0f183163ac.map +3579 -0
- package/SystemModules/amzn__react-native-safe-area-context-2.modules.txt +1 -37
- package/SystemModules/amzn__react-native-safe-area-context-2.private.modules.txt +29 -36
- package/kepler-compatibility.json +3 -2
- package/lib/commonjs/CompatNativeSafeAreaProvider.js.map +1 -1
- package/lib/commonjs/InitialWindow.js.map +1 -1
- package/lib/commonjs/InitialWindow.kepler.js.map +1 -1
- package/lib/commonjs/InitialWindow.native.js.map +1 -1
- package/lib/commonjs/NativeSafeAreaProvider.js +3 -0
- package/lib/commonjs/NativeSafeAreaProvider.js.map +1 -1
- package/lib/commonjs/NativeSafeAreaProvider.kepler.js.map +1 -1
- package/lib/commonjs/NativeSafeAreaProvider.macos.js.map +1 -1
- package/lib/commonjs/NativeSafeAreaProvider.native.js.map +1 -1
- package/lib/commonjs/NativeSafeAreaProvider.windows.js.map +1 -1
- package/lib/commonjs/SafeArea.types.js.map +1 -1
- package/lib/commonjs/SafeAreaContext.js +2 -3
- package/lib/commonjs/SafeAreaContext.js.map +1 -1
- package/lib/commonjs/SafeAreaView.js.map +1 -1
- package/lib/commonjs/SafeAreaView.kepler.js.map +1 -1
- package/lib/commonjs/SafeAreaView.macos.js.map +1 -1
- package/lib/commonjs/SafeAreaView.native.js.map +1 -1
- package/lib/commonjs/SafeAreaView.windows.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/useWindowDimensions.js.map +1 -1
- package/lib/module/CompatNativeSafeAreaProvider.js.map +1 -1
- package/lib/module/InitialWindow.js.map +1 -1
- package/lib/module/InitialWindow.kepler.js.map +1 -1
- package/lib/module/InitialWindow.native.js.map +1 -1
- package/lib/module/NativeSafeAreaProvider.js +2 -0
- package/lib/module/NativeSafeAreaProvider.js.map +1 -1
- package/lib/module/NativeSafeAreaProvider.kepler.js.map +1 -1
- package/lib/module/NativeSafeAreaProvider.macos.js.map +1 -1
- package/lib/module/NativeSafeAreaProvider.native.js.map +1 -1
- package/lib/module/NativeSafeAreaProvider.windows.js.map +1 -1
- package/lib/module/SafeArea.types.js.map +1 -1
- package/lib/module/SafeAreaContext.js +2 -3
- package/lib/module/SafeAreaContext.js.map +1 -1
- package/lib/module/SafeAreaView.js.map +1 -1
- package/lib/module/SafeAreaView.kepler.js.map +1 -1
- package/lib/module/SafeAreaView.macos.js.map +1 -1
- package/lib/module/SafeAreaView.native.js.map +1 -1
- package/lib/module/SafeAreaView.windows.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/useWindowDimensions.js.map +1 -1
- package/lib/typescript/CompatNativeSafeAreaProvider.d.ts +4 -0
- package/lib/typescript/CompatNativeSafeAreaProvider.d.ts.map +1 -0
- package/lib/typescript/{src/InitialWindow.d.ts → InitialWindow.d.ts} +2 -1
- package/lib/typescript/InitialWindow.d.ts.map +1 -0
- package/lib/typescript/{src/InitialWindow.kepler.d.ts → InitialWindow.kepler.d.ts} +1 -0
- package/lib/typescript/InitialWindow.kepler.d.ts.map +1 -0
- package/lib/typescript/{src/InitialWindow.native.d.ts → InitialWindow.native.d.ts} +1 -0
- package/lib/typescript/InitialWindow.native.d.ts.map +1 -0
- package/lib/typescript/NativeSafeAreaProvider.d.ts +4 -0
- package/lib/typescript/NativeSafeAreaProvider.d.ts.map +1 -0
- package/lib/typescript/{src/NativeSafeAreaProvider.kepler.d.ts → NativeSafeAreaProvider.kepler.d.ts} +1 -0
- package/lib/typescript/NativeSafeAreaProvider.kepler.d.ts.map +1 -0
- package/lib/typescript/{src/NativeSafeAreaProvider.macos.d.ts → NativeSafeAreaProvider.macos.d.ts} +1 -0
- package/lib/typescript/NativeSafeAreaProvider.macos.d.ts.map +1 -0
- package/lib/typescript/{src/NativeSafeAreaProvider.native.d.ts → NativeSafeAreaProvider.native.d.ts} +1 -0
- package/lib/typescript/NativeSafeAreaProvider.native.d.ts.map +1 -0
- package/lib/typescript/{src/NativeSafeAreaProvider.windows.d.ts → NativeSafeAreaProvider.windows.d.ts} +1 -0
- package/lib/typescript/NativeSafeAreaProvider.windows.d.ts.map +1 -0
- package/lib/typescript/{src/SafeArea.types.d.ts → SafeArea.types.d.ts} +2 -1
- package/lib/typescript/SafeArea.types.d.ts.map +1 -0
- package/lib/typescript/{src/SafeAreaContext.d.ts → SafeAreaContext.d.ts} +4 -3
- package/lib/typescript/SafeAreaContext.d.ts.map +1 -0
- package/lib/typescript/SafeAreaView.d.ts +4 -0
- package/lib/typescript/SafeAreaView.d.ts.map +1 -0
- package/lib/typescript/{src/SafeAreaView.kepler.d.ts → SafeAreaView.kepler.d.ts} +1 -0
- package/lib/typescript/SafeAreaView.kepler.d.ts.map +1 -0
- package/lib/typescript/{src/SafeAreaView.macos.d.ts → SafeAreaView.macos.d.ts} +1 -0
- package/lib/typescript/SafeAreaView.macos.d.ts.map +1 -0
- package/lib/typescript/{src/SafeAreaView.native.d.ts → SafeAreaView.native.d.ts} +1 -0
- package/lib/typescript/SafeAreaView.native.d.ts.map +1 -0
- package/lib/typescript/{src/SafeAreaView.windows.d.ts → SafeAreaView.windows.d.ts} +1 -0
- package/lib/typescript/SafeAreaView.windows.d.ts.map +1 -0
- package/lib/typescript/{src/index.d.ts → index.d.ts} +1 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/{src/useWindowDimensions.d.ts → useWindowDimensions.d.ts} +1 -0
- package/lib/typescript/useWindowDimensions.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/InitialWindow.ts +1 -1
- package/src/NativeSafeAreaProvider.tsx +3 -1
- package/src/SafeArea.types.ts +1 -1
- package/src/SafeAreaContext.tsx +2 -2
- package/src/SafeAreaView.tsx +1 -1
- package/src/__tests__/InitialWindow-test.tsx +47 -0
- package/src/__tests__/SafeAreaContext-test.tsx +121 -0
- package/src/__tests__/SafeAreaView-test.tsx +35 -0
- package/src/__tests__/__snapshots__/SafeAreaContext-test.tsx.snap +183 -0
- package/src/__tests__/__snapshots__/SafeAreaView-test.tsx.snap +43 -0
- package/SystemBundles/85c8d24b7f717b77a2deb00e32cc2aaa293a5a16c46eecebca21e95bda425730.map +0 -4335
- package/android/build.gradle +0 -46
- package/android/src/main/AndroidManifest.xml +0 -6
- package/android/src/main/java/com/th3rdwave/safeareacontext/EdgeInsets.java +0 -22
- package/android/src/main/java/com/th3rdwave/safeareacontext/InsetsChangeEvent.java +0 -33
- package/android/src/main/java/com/th3rdwave/safeareacontext/Rect.java +0 -22
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaContextPackage.java +0 -31
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaProvider.java +0 -66
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaProviderManager.java +0 -94
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaUtils.java +0 -82
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaView.java +0 -159
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaViewEdges.java +0 -8
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaViewLocalData.java +0 -27
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaViewManager.java +0 -72
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaViewMode.java +0 -6
- package/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaViewShadowNode.java +0 -201
- package/android/src/main/java/com/th3rdwave/safeareacontext/SerializationUtils.java +0 -52
- package/ios/SafeAreaView/RCTView+SafeAreaCompat.h +0 -16
- package/ios/SafeAreaView/RCTView+SafeAreaCompat.m +0 -57
- package/ios/SafeAreaView/RNCSafeAreaProvider.h +0 -13
- package/ios/SafeAreaView/RNCSafeAreaProvider.m +0 -65
- package/ios/SafeAreaView/RNCSafeAreaProviderManager.h +0 -9
- package/ios/SafeAreaView/RNCSafeAreaProviderManager.m +0 -61
- package/ios/SafeAreaView/RNCSafeAreaShadowView.h +0 -9
- package/ios/SafeAreaView/RNCSafeAreaShadowView.m +0 -180
- package/ios/SafeAreaView/RNCSafeAreaView.h +0 -21
- package/ios/SafeAreaView/RNCSafeAreaView.m +0 -118
- package/ios/SafeAreaView/RNCSafeAreaViewEdges.h +0 -9
- package/ios/SafeAreaView/RNCSafeAreaViewEdges.m +0 -13
- package/ios/SafeAreaView/RNCSafeAreaViewLocalData.h +0 -18
- package/ios/SafeAreaView/RNCSafeAreaViewLocalData.m +0 -16
- package/ios/SafeAreaView/RNCSafeAreaViewManager.h +0 -9
- package/ios/SafeAreaView/RNCSafeAreaViewManager.m +0 -25
- package/ios/SafeAreaView/RNCSafeAreaViewMode.h +0 -7
- package/ios/SafeAreaView/RNCSafeAreaViewMode.m +0 -11
- package/ios/SafeAreaView.xcodeproj/project.pbxproj +0 -338
- package/lib/typescript/src/CompatNativeSafeAreaProvider.d.ts +0 -2
- package/lib/typescript/src/NativeSafeAreaProvider.d.ts +0 -2
- package/lib/typescript/src/SafeAreaView.d.ts +0 -2
- package/react-native-safe-area-context.podspec +0 -19
package/android/build.gradle
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
def getExtOrDefault(name, defaultValue) {
|
|
2
|
-
return rootProject.ext.has(name) ? rootProject.ext.get(name) : defaultValue
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
buildscript {
|
|
6
|
-
// The Android Gradle plugin is only required when opening the android folder stand-alone.
|
|
7
|
-
// This avoids unnecessary downloads and potential conflicts when the library is included as a
|
|
8
|
-
// module dependency in an application project.
|
|
9
|
-
if (project == rootProject) {
|
|
10
|
-
repositories {
|
|
11
|
-
google()
|
|
12
|
-
jcenter()
|
|
13
|
-
}
|
|
14
|
-
dependencies {
|
|
15
|
-
classpath 'com.android.tools.build:gradle:4.1.2'
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
apply plugin: 'com.android.library'
|
|
21
|
-
|
|
22
|
-
android {
|
|
23
|
-
compileSdkVersion getExtOrDefault('compileSdkVersion', 28)
|
|
24
|
-
|
|
25
|
-
defaultConfig {
|
|
26
|
-
minSdkVersion getExtOrDefault('minSdkVersion', 16)
|
|
27
|
-
targetSdkVersion getExtOrDefault('targetSdkVersion', 28)
|
|
28
|
-
}
|
|
29
|
-
lintOptions{
|
|
30
|
-
abortOnError false
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
repositories {
|
|
35
|
-
google()
|
|
36
|
-
maven {
|
|
37
|
-
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
|
38
|
-
url "$rootDir/../node_modules/react-native/android"
|
|
39
|
-
}
|
|
40
|
-
jcenter()
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
dependencies {
|
|
44
|
-
//noinspection GradleDynamicVersion
|
|
45
|
-
implementation 'com.facebook.react:react-native:+'
|
|
46
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
/* package */ class EdgeInsets {
|
|
4
|
-
float top;
|
|
5
|
-
float right;
|
|
6
|
-
float bottom;
|
|
7
|
-
float left;
|
|
8
|
-
|
|
9
|
-
EdgeInsets(float top, float right, float bottom, float left) {
|
|
10
|
-
this.top = top;
|
|
11
|
-
this.right = right;
|
|
12
|
-
this.bottom = bottom;
|
|
13
|
-
this.left = left;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
boolean equalsToEdgeInsets(EdgeInsets other) {
|
|
17
|
-
if (this == other) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
return this.top == other.top && this.right == other.right && this.bottom == other.bottom && this.left == other.left;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
import com.facebook.react.bridge.Arguments;
|
|
4
|
-
import com.facebook.react.bridge.WritableMap;
|
|
5
|
-
import com.facebook.react.uimanager.events.Event;
|
|
6
|
-
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
|
7
|
-
|
|
8
|
-
/* package */ class InsetsChangeEvent extends Event<InsetsChangeEvent> {
|
|
9
|
-
static final String EVENT_NAME = "topInsetsChange";
|
|
10
|
-
|
|
11
|
-
private EdgeInsets mInsets;
|
|
12
|
-
private Rect mFrame;
|
|
13
|
-
|
|
14
|
-
InsetsChangeEvent(int viewTag, EdgeInsets insets, Rect frame) {
|
|
15
|
-
super(viewTag);
|
|
16
|
-
|
|
17
|
-
mInsets = insets;
|
|
18
|
-
mFrame = frame;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@Override
|
|
22
|
-
public String getEventName() {
|
|
23
|
-
return EVENT_NAME;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@Override
|
|
27
|
-
public void dispatch(RCTEventEmitter rctEventEmitter) {
|
|
28
|
-
WritableMap event = Arguments.createMap();
|
|
29
|
-
event.putMap("insets", SerializationUtils.edgeInsetsToJsMap(mInsets));
|
|
30
|
-
event.putMap("frame", SerializationUtils.rectToJsMap(mFrame));
|
|
31
|
-
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), event);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
/* package */ class Rect {
|
|
4
|
-
float x;
|
|
5
|
-
float y;
|
|
6
|
-
float width;
|
|
7
|
-
float height;
|
|
8
|
-
|
|
9
|
-
Rect(float x, float y, float width, float height) {
|
|
10
|
-
this.x = x;
|
|
11
|
-
this.y = y;
|
|
12
|
-
this.width = width;
|
|
13
|
-
this.height = height;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
boolean equalsToRect(Rect other) {
|
|
17
|
-
if (this == other) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
return this.x == other.x && this.y == other.y && this.width == other.width && this.height == other.height;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
import androidx.annotation.NonNull;
|
|
4
|
-
|
|
5
|
-
import com.facebook.react.ReactPackage;
|
|
6
|
-
import com.facebook.react.bridge.NativeModule;
|
|
7
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
-
import com.facebook.react.uimanager.ViewManager;
|
|
9
|
-
|
|
10
|
-
import java.util.Arrays;
|
|
11
|
-
import java.util.Collections;
|
|
12
|
-
import java.util.List;
|
|
13
|
-
|
|
14
|
-
public class SafeAreaContextPackage implements ReactPackage {
|
|
15
|
-
|
|
16
|
-
@NonNull
|
|
17
|
-
@Override
|
|
18
|
-
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
|
19
|
-
return Collections.emptyList();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
@NonNull
|
|
23
|
-
@Override
|
|
24
|
-
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
|
25
|
-
return Arrays.<ViewManager>asList(
|
|
26
|
-
new SafeAreaProviderManager(reactContext),
|
|
27
|
-
new SafeAreaViewManager()
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
import android.annotation.SuppressLint;
|
|
4
|
-
import android.content.Context;
|
|
5
|
-
import android.view.ViewGroup;
|
|
6
|
-
import android.view.ViewTreeObserver;
|
|
7
|
-
|
|
8
|
-
import com.facebook.infer.annotation.Assertions;
|
|
9
|
-
import com.facebook.react.views.view.ReactViewGroup;
|
|
10
|
-
|
|
11
|
-
import androidx.annotation.Nullable;
|
|
12
|
-
|
|
13
|
-
@SuppressLint("ViewConstructor")
|
|
14
|
-
public class SafeAreaProvider extends ReactViewGroup implements ViewTreeObserver.OnPreDrawListener {
|
|
15
|
-
public interface OnInsetsChangeListener {
|
|
16
|
-
void onInsetsChange(SafeAreaProvider view, EdgeInsets insets, Rect frame);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
private @Nullable OnInsetsChangeListener mInsetsChangeListener;
|
|
20
|
-
private @Nullable EdgeInsets mLastInsets;
|
|
21
|
-
private @Nullable Rect mLastFrame;
|
|
22
|
-
|
|
23
|
-
public SafeAreaProvider(Context context) {
|
|
24
|
-
super(context);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
private void maybeUpdateInsets() {
|
|
28
|
-
EdgeInsets edgeInsets = SafeAreaUtils.getSafeAreaInsets(this);
|
|
29
|
-
Rect frame = SafeAreaUtils.getFrame((ViewGroup) getRootView(), this);
|
|
30
|
-
if (edgeInsets != null && frame != null &&
|
|
31
|
-
(mLastInsets == null ||
|
|
32
|
-
mLastFrame == null ||
|
|
33
|
-
!mLastInsets.equalsToEdgeInsets(edgeInsets) ||
|
|
34
|
-
!mLastFrame.equalsToRect(frame))) {
|
|
35
|
-
Assertions.assertNotNull(mInsetsChangeListener).onInsetsChange(this, edgeInsets, frame);
|
|
36
|
-
mLastInsets = edgeInsets;
|
|
37
|
-
mLastFrame = frame;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@Override
|
|
42
|
-
protected void onAttachedToWindow() {
|
|
43
|
-
super.onAttachedToWindow();
|
|
44
|
-
|
|
45
|
-
getViewTreeObserver().addOnPreDrawListener(this);
|
|
46
|
-
maybeUpdateInsets();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@Override
|
|
50
|
-
protected void onDetachedFromWindow() {
|
|
51
|
-
super.onDetachedFromWindow();
|
|
52
|
-
|
|
53
|
-
getViewTreeObserver().removeOnPreDrawListener(this);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
@Override
|
|
57
|
-
public boolean onPreDraw() {
|
|
58
|
-
maybeUpdateInsets();
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
public void setOnInsetsChangeListener(OnInsetsChangeListener listener) {
|
|
64
|
-
mInsetsChangeListener = listener;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
import android.app.Activity;
|
|
4
|
-
import android.view.View;
|
|
5
|
-
import android.view.ViewGroup;
|
|
6
|
-
|
|
7
|
-
import com.facebook.react.bridge.ReactApplicationContext;
|
|
8
|
-
import com.facebook.react.common.MapBuilder;
|
|
9
|
-
import com.facebook.react.uimanager.ThemedReactContext;
|
|
10
|
-
import com.facebook.react.uimanager.UIManagerModule;
|
|
11
|
-
import com.facebook.react.uimanager.ViewGroupManager;
|
|
12
|
-
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
13
|
-
|
|
14
|
-
import java.util.Map;
|
|
15
|
-
|
|
16
|
-
import androidx.annotation.NonNull;
|
|
17
|
-
import androidx.annotation.Nullable;
|
|
18
|
-
|
|
19
|
-
public class SafeAreaProviderManager extends ViewGroupManager<SafeAreaProvider> {
|
|
20
|
-
private final ReactApplicationContext mContext;
|
|
21
|
-
|
|
22
|
-
public SafeAreaProviderManager(ReactApplicationContext context) {
|
|
23
|
-
super();
|
|
24
|
-
|
|
25
|
-
mContext = context;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
@Override
|
|
29
|
-
@NonNull
|
|
30
|
-
public String getName() {
|
|
31
|
-
return "RNCSafeAreaProvider";
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@Override
|
|
35
|
-
@NonNull
|
|
36
|
-
public SafeAreaProvider createViewInstance(@NonNull ThemedReactContext context) {
|
|
37
|
-
return new SafeAreaProvider(context);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@Override
|
|
41
|
-
protected void addEventEmitters(@NonNull ThemedReactContext reactContext, @NonNull final SafeAreaProvider view) {
|
|
42
|
-
final EventDispatcher dispatcher =
|
|
43
|
-
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
|
|
44
|
-
view.setOnInsetsChangeListener(new SafeAreaProvider.OnInsetsChangeListener() {
|
|
45
|
-
@Override
|
|
46
|
-
public void onInsetsChange(SafeAreaProvider view, EdgeInsets insets, Rect frame) {
|
|
47
|
-
dispatcher.dispatchEvent(new InsetsChangeEvent(view.getId(), insets, frame));
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@Override
|
|
53
|
-
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
|
54
|
-
return MapBuilder.<String, Object>builder()
|
|
55
|
-
.put(InsetsChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onInsetsChange"))
|
|
56
|
-
.build();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private @Nullable Map<String, Object> getInitialWindowMetrics() {
|
|
60
|
-
Activity activity = mContext.getCurrentActivity();
|
|
61
|
-
if (activity == null) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
|
|
66
|
-
if (decorView == null) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
View contentView = decorView.findViewById(android.R.id.content);
|
|
71
|
-
if (contentView == null) {
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
EdgeInsets insets = SafeAreaUtils.getSafeAreaInsets(decorView);
|
|
75
|
-
Rect frame = SafeAreaUtils.getFrame(decorView, contentView);
|
|
76
|
-
if (insets == null || frame == null) {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
return MapBuilder.<String, Object>of(
|
|
80
|
-
"insets",
|
|
81
|
-
SerializationUtils.edgeInsetsToJavaMap(insets),
|
|
82
|
-
"frame",
|
|
83
|
-
SerializationUtils.rectToJavaMap(frame));
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
@Nullable
|
|
87
|
-
@Override
|
|
88
|
-
public Map<String, Object> getExportedViewConstants() {
|
|
89
|
-
return MapBuilder.<String, Object>of(
|
|
90
|
-
"initialWindowMetrics",
|
|
91
|
-
getInitialWindowMetrics());
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
import android.graphics.Rect;
|
|
4
|
-
import android.os.Build;
|
|
5
|
-
import android.view.View;
|
|
6
|
-
import android.view.ViewGroup;
|
|
7
|
-
import android.view.WindowInsets;
|
|
8
|
-
|
|
9
|
-
import androidx.annotation.Nullable;
|
|
10
|
-
|
|
11
|
-
/* package */ class SafeAreaUtils {
|
|
12
|
-
|
|
13
|
-
private static @Nullable EdgeInsets getRootWindowInsetsCompat(View rootView) {
|
|
14
|
-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
15
|
-
WindowInsets insets = rootView.getRootWindowInsets();
|
|
16
|
-
if (insets == null) {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
return new EdgeInsets(
|
|
20
|
-
insets.getSystemWindowInsetTop(),
|
|
21
|
-
insets.getSystemWindowInsetRight(),
|
|
22
|
-
// System insets are more reliable to account for notches but the
|
|
23
|
-
// system inset for bottom includes the soft keyboard which we don't
|
|
24
|
-
// want to be consistent with iOS. Using the min value makes sure we
|
|
25
|
-
// never get the keyboard offset while still working with devices that
|
|
26
|
-
// hide the navigation bar.
|
|
27
|
-
Math.min(insets.getSystemWindowInsetBottom(), insets.getStableInsetBottom()),
|
|
28
|
-
insets.getSystemWindowInsetLeft());
|
|
29
|
-
} else {
|
|
30
|
-
Rect visibleRect = new Rect();
|
|
31
|
-
rootView.getWindowVisibleDisplayFrame(visibleRect);
|
|
32
|
-
return new EdgeInsets(
|
|
33
|
-
visibleRect.top,
|
|
34
|
-
rootView.getWidth() - visibleRect.right,
|
|
35
|
-
rootView.getHeight() - visibleRect.bottom,
|
|
36
|
-
visibleRect.left);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
static @Nullable EdgeInsets getSafeAreaInsets(View view) {
|
|
41
|
-
// The view has not been layout yet.
|
|
42
|
-
if (view.getHeight() == 0) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
View rootView = view.getRootView();
|
|
46
|
-
EdgeInsets windowInsets = getRootWindowInsetsCompat(rootView);
|
|
47
|
-
if (windowInsets == null) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Calculate the part of the view that overlaps with window insets.
|
|
52
|
-
float windowWidth = rootView.getWidth();
|
|
53
|
-
float windowHeight = rootView.getHeight();
|
|
54
|
-
Rect visibleRect = new Rect();
|
|
55
|
-
view.getGlobalVisibleRect(visibleRect);
|
|
56
|
-
|
|
57
|
-
windowInsets.top = Math.max(windowInsets.top - visibleRect.top, 0);
|
|
58
|
-
windowInsets.left = Math.max(windowInsets.left - visibleRect.left, 0);
|
|
59
|
-
windowInsets.bottom = Math.max(Math.min(visibleRect.top + view.getHeight() - windowHeight, 0) + windowInsets.bottom, 0);
|
|
60
|
-
windowInsets.right = Math.max(Math.min(visibleRect.left + view.getWidth() - windowWidth, 0) + windowInsets.right, 0);
|
|
61
|
-
return windowInsets;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
static @Nullable com.th3rdwave.safeareacontext.Rect getFrame(ViewGroup rootView, View view) {
|
|
65
|
-
// This can happen while the view gets unmounted.
|
|
66
|
-
if (view.getParent() == null) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
Rect offset = new Rect();
|
|
70
|
-
view.getDrawingRect(offset);
|
|
71
|
-
try {
|
|
72
|
-
rootView.offsetDescendantRectToMyCoords(view, offset);
|
|
73
|
-
} catch (IllegalArgumentException ex) {
|
|
74
|
-
// This can throw if the view is not a descendant of rootView. This should not
|
|
75
|
-
// happen but avoid potential crashes.
|
|
76
|
-
ex.printStackTrace();
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return new com.th3rdwave.safeareacontext.Rect(offset.left, offset.top, view.getWidth(), view.getHeight());
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
import android.annotation.SuppressLint;
|
|
4
|
-
import android.content.Context;
|
|
5
|
-
import android.content.ContextWrapper;
|
|
6
|
-
import android.util.Log;
|
|
7
|
-
import android.view.View;
|
|
8
|
-
import android.view.ViewParent;
|
|
9
|
-
import android.view.ViewTreeObserver;
|
|
10
|
-
|
|
11
|
-
import com.facebook.react.bridge.ReactContext;
|
|
12
|
-
import com.facebook.react.uimanager.UIManagerModule;
|
|
13
|
-
import com.facebook.react.views.view.ReactViewGroup;
|
|
14
|
-
|
|
15
|
-
import java.util.EnumSet;
|
|
16
|
-
import java.util.concurrent.atomic.AtomicBoolean;
|
|
17
|
-
|
|
18
|
-
import androidx.annotation.Nullable;
|
|
19
|
-
|
|
20
|
-
@SuppressLint("ViewConstructor")
|
|
21
|
-
public class SafeAreaView extends ReactViewGroup implements ViewTreeObserver.OnPreDrawListener {
|
|
22
|
-
private SafeAreaViewMode mMode = SafeAreaViewMode.PADDING;
|
|
23
|
-
private @Nullable EdgeInsets mInsets;
|
|
24
|
-
private @Nullable EnumSet<SafeAreaViewEdges> mEdges;
|
|
25
|
-
private @Nullable View mProviderView;
|
|
26
|
-
|
|
27
|
-
public SafeAreaView(Context context) {
|
|
28
|
-
super(context);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* UIManagerHelper.getReactContext only exists in RN 0.63+ so vendor it here for a while.
|
|
33
|
-
*/
|
|
34
|
-
private static ReactContext getReactContext(View view) {
|
|
35
|
-
Context context = view.getContext();
|
|
36
|
-
if (!(context instanceof ReactContext) && context instanceof ContextWrapper) {
|
|
37
|
-
context = ((ContextWrapper) context).getBaseContext();
|
|
38
|
-
}
|
|
39
|
-
return (ReactContext) context;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private void updateInsets() {
|
|
43
|
-
if (mInsets != null) {
|
|
44
|
-
EnumSet<SafeAreaViewEdges> edges = mEdges != null
|
|
45
|
-
? mEdges
|
|
46
|
-
: EnumSet.allOf(SafeAreaViewEdges.class);
|
|
47
|
-
|
|
48
|
-
SafeAreaViewLocalData localData = new SafeAreaViewLocalData(mInsets, mMode, edges);
|
|
49
|
-
|
|
50
|
-
ReactContext reactContext = getReactContext(this);
|
|
51
|
-
UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class);
|
|
52
|
-
if (uiManager != null) {
|
|
53
|
-
uiManager.setViewLocalData(getId(), localData);
|
|
54
|
-
waitForReactLayout();
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private static final long MAX_WAIT_TIME_NANO = 500000000L; // 500ms
|
|
60
|
-
|
|
61
|
-
private void waitForReactLayout() {
|
|
62
|
-
// Block the main thread until the native module thread is finished with
|
|
63
|
-
// its current tasks. To do this we use the done boolean as a lock and enqueue
|
|
64
|
-
// a task on the native modules thread. When the task runs we can unblock the
|
|
65
|
-
// main thread. This should be safe as long as the native modules thread
|
|
66
|
-
// does not block waiting on the main thread.
|
|
67
|
-
final AtomicBoolean done = new AtomicBoolean(false);
|
|
68
|
-
final long startTime = System.nanoTime();
|
|
69
|
-
long waitTime = 0L;
|
|
70
|
-
getReactContext(this).runOnNativeModulesQueueThread(new Runnable() {
|
|
71
|
-
@Override
|
|
72
|
-
public void run() {
|
|
73
|
-
synchronized (done) {
|
|
74
|
-
if (done.compareAndSet(false, true)) {
|
|
75
|
-
done.notify();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
synchronized (done) {
|
|
81
|
-
while (!done.get() && waitTime < MAX_WAIT_TIME_NANO) {
|
|
82
|
-
try {
|
|
83
|
-
done.wait(MAX_WAIT_TIME_NANO / 1000000L);
|
|
84
|
-
} catch (InterruptedException e) {
|
|
85
|
-
// In case of an interrupt just give up waiting.
|
|
86
|
-
done.set(true);
|
|
87
|
-
}
|
|
88
|
-
waitTime += System.nanoTime() - startTime;
|
|
89
|
-
}
|
|
90
|
-
// Timed out waiting.
|
|
91
|
-
if (waitTime >= MAX_WAIT_TIME_NANO) {
|
|
92
|
-
Log.w("SafeAreaView", "Timed out waiting for layout.");
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
public void setMode(SafeAreaViewMode mode) {
|
|
98
|
-
mMode = mode;
|
|
99
|
-
updateInsets();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
public void setEdges(EnumSet<SafeAreaViewEdges> edges) {
|
|
103
|
-
mEdges = edges;
|
|
104
|
-
updateInsets();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private boolean maybeUpdateInsets() {
|
|
108
|
-
if (mProviderView == null) {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
EdgeInsets edgeInsets = SafeAreaUtils.getSafeAreaInsets(mProviderView);
|
|
112
|
-
if (edgeInsets != null && (mInsets == null || !mInsets.equalsToEdgeInsets(edgeInsets))) {
|
|
113
|
-
mInsets = edgeInsets;
|
|
114
|
-
updateInsets();
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private View findProvider() {
|
|
121
|
-
ViewParent current = getParent();
|
|
122
|
-
while (current != null) {
|
|
123
|
-
if (current instanceof SafeAreaProvider) {
|
|
124
|
-
return (View) current;
|
|
125
|
-
}
|
|
126
|
-
current = current.getParent();
|
|
127
|
-
}
|
|
128
|
-
return this;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
@Override
|
|
132
|
-
protected void onAttachedToWindow() {
|
|
133
|
-
super.onAttachedToWindow();
|
|
134
|
-
|
|
135
|
-
mProviderView = findProvider();
|
|
136
|
-
|
|
137
|
-
mProviderView.getViewTreeObserver().addOnPreDrawListener(this);
|
|
138
|
-
maybeUpdateInsets();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
@Override
|
|
142
|
-
protected void onDetachedFromWindow() {
|
|
143
|
-
super.onDetachedFromWindow();
|
|
144
|
-
|
|
145
|
-
if (mProviderView != null) {
|
|
146
|
-
mProviderView.getViewTreeObserver().removeOnPreDrawListener(this);
|
|
147
|
-
}
|
|
148
|
-
mProviderView = null;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
@Override
|
|
152
|
-
public boolean onPreDraw() {
|
|
153
|
-
boolean didUpdate = maybeUpdateInsets();
|
|
154
|
-
if (didUpdate) {
|
|
155
|
-
requestLayout();
|
|
156
|
-
}
|
|
157
|
-
return !didUpdate;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
import java.util.EnumSet;
|
|
4
|
-
|
|
5
|
-
public class SafeAreaViewLocalData {
|
|
6
|
-
private EdgeInsets mInsets;
|
|
7
|
-
private SafeAreaViewMode mMode;
|
|
8
|
-
private EnumSet<SafeAreaViewEdges> mEdges;
|
|
9
|
-
|
|
10
|
-
public SafeAreaViewLocalData(EdgeInsets insets, SafeAreaViewMode mode, EnumSet<SafeAreaViewEdges> edges) {
|
|
11
|
-
mInsets = insets;
|
|
12
|
-
mMode = mode;
|
|
13
|
-
mEdges = edges;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public EdgeInsets getInsets() {
|
|
17
|
-
return mInsets;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
public SafeAreaViewMode getMode() {
|
|
21
|
-
return mMode;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public EnumSet<SafeAreaViewEdges> getEdges() {
|
|
25
|
-
return mEdges;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
package com.th3rdwave.safeareacontext;
|
|
2
|
-
|
|
3
|
-
import androidx.annotation.NonNull;
|
|
4
|
-
import androidx.annotation.Nullable;
|
|
5
|
-
|
|
6
|
-
import com.facebook.react.bridge.ReadableArray;
|
|
7
|
-
import com.facebook.react.uimanager.LayoutShadowNode;
|
|
8
|
-
import com.facebook.react.uimanager.ThemedReactContext;
|
|
9
|
-
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
10
|
-
import com.facebook.react.views.view.ReactViewManager;
|
|
11
|
-
|
|
12
|
-
import java.util.EnumSet;
|
|
13
|
-
|
|
14
|
-
public class SafeAreaViewManager extends ReactViewManager {
|
|
15
|
-
public SafeAreaViewManager() {
|
|
16
|
-
super();
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
@Override
|
|
20
|
-
@NonNull
|
|
21
|
-
public String getName() {
|
|
22
|
-
return "RNCSafeAreaView";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@Override
|
|
26
|
-
@NonNull
|
|
27
|
-
public SafeAreaView createViewInstance(@NonNull ThemedReactContext context) {
|
|
28
|
-
return new SafeAreaView(context);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@Override
|
|
32
|
-
@NonNull
|
|
33
|
-
public SafeAreaViewShadowNode createShadowNodeInstance() {
|
|
34
|
-
return new SafeAreaViewShadowNode();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@Override
|
|
38
|
-
public Class<? extends LayoutShadowNode> getShadowNodeClass() {
|
|
39
|
-
return SafeAreaViewShadowNode.class;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
@ReactProp(name = "mode")
|
|
43
|
-
public void setMode(SafeAreaView view, @Nullable String mode) {
|
|
44
|
-
if ("padding".equals(mode)) {
|
|
45
|
-
view.setMode(SafeAreaViewMode.PADDING);
|
|
46
|
-
} else if ("margin".equals(mode)) {
|
|
47
|
-
view.setMode(SafeAreaViewMode.MARGIN);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@ReactProp(name = "edges")
|
|
52
|
-
public void setEdges(SafeAreaView view, @Nullable ReadableArray propList) {
|
|
53
|
-
EnumSet<SafeAreaViewEdges> edges = EnumSet.noneOf(SafeAreaViewEdges.class);
|
|
54
|
-
|
|
55
|
-
if (propList != null) {
|
|
56
|
-
for (int i = 0; i < propList.size(); i += 1) {
|
|
57
|
-
String edgeName = propList.getString(i);
|
|
58
|
-
if ("top".equals(edgeName)) {
|
|
59
|
-
edges.add(SafeAreaViewEdges.TOP);
|
|
60
|
-
} else if ("right".equals(edgeName)) {
|
|
61
|
-
edges.add(SafeAreaViewEdges.RIGHT);
|
|
62
|
-
} else if ("bottom".equals(edgeName)) {
|
|
63
|
-
edges.add(SafeAreaViewEdges.BOTTOM);
|
|
64
|
-
} else if ("left".equals(edgeName)) {
|
|
65
|
-
edges.add(SafeAreaViewEdges.LEFT);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
view.setEdges(edges);
|
|
71
|
-
}
|
|
72
|
-
}
|