@totalpave/cordova-plugin-insets 0.2.0 → 0.3.1
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/CHANGELOG.md +50 -1
- package/README.md +1 -1
- package/docs.md +100 -17
- package/package.json +4 -4
- package/plugin.xml +6 -6
- package/plugin.xml.ejs +5 -5
- package/src/android/com/totalpave/cordova/inset/Inset.java +337 -0
- package/src/www/IInset.ts +22 -0
- package/src/www/IInsetCallbackFunc.ts +19 -0
- package/src/www/IInsetConfiguration.ts +32 -0
- package/src/www/Inset.ts +234 -0
- package/src/www/InsetMask.ts +38 -0
- package/src/www/api.ts +6 -5
- package/www/IInset.d.ts +6 -0
- package/www/IInsetCallbackFunc.d.ts +2 -0
- package/www/IInsetConfiguration.d.ts +15 -0
- package/www/Inset.d.ts +93 -0
- package/www/InsetMask.d.ts +22 -0
- package/www/api.d.ts +5 -1
- package/www/insets.js +180 -48
- package/www/insets.js.map +1 -1
- package/src/android/com/totalpave/cordova/insets/Insets.java +0 -136
- package/src/www/Insets.ts +0 -118
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,56 @@
|
|
|
4
4
|
|
|
5
5
|
# Changelog
|
|
6
6
|
|
|
7
|
-
## 0.
|
|
7
|
+
## 0.3.0 (TBD)
|
|
8
|
+
|
|
9
|
+
### Breaking Changes:
|
|
10
|
+
|
|
11
|
+
#### Depluralize symbols
|
|
12
|
+
|
|
13
|
+
Several symbols were written in plural form which goes against common naming
|
|
14
|
+
conventions. In effort to make the API a bit cleaner, this was corrected.
|
|
15
|
+
|
|
16
|
+
|Old Name|New Name|
|
|
17
|
+
|---|---|
|
|
18
|
+
|`Insets`|`Inset`|
|
|
19
|
+
|`IInsets`|`IInset`|
|
|
20
|
+
|
|
21
|
+
`window.totalpave.Insets` has been renamed to `window.totalpave.Inset`
|
|
22
|
+
|
|
23
|
+
The typescript global typedefs have been updated accordingly.
|
|
24
|
+
|
|
25
|
+
#### IInsetAPI
|
|
26
|
+
|
|
27
|
+
This type interface was removed, the `Inset` class can be referenced instead.
|
|
28
|
+
|
|
29
|
+
#### Inset API is no longer static
|
|
30
|
+
|
|
31
|
+
The static `addListener`, `removeListener`, and `getInsets` APIs have been
|
|
32
|
+
removed and replaced with non-static versions. Two new static methods are introduced:
|
|
33
|
+
|
|
34
|
+
- `Inset.create`
|
|
35
|
+
- `Inset.free`
|
|
36
|
+
|
|
37
|
+
It is now the application's responsibility to create their own `Inset` instance via
|
|
38
|
+
`Inset.create`, passing
|
|
39
|
+
in their own configuration object. An instance of `Inset` will be returned that
|
|
40
|
+
can be used like before.
|
|
41
|
+
|
|
42
|
+
Once the inset instance is no longer needed it will be desirable to free resources
|
|
43
|
+
by calling `inset.free()` which will free up retained references allowing the
|
|
44
|
+
objects to be garbage collected.
|
|
45
|
+
|
|
46
|
+
Most use cases only calls for a single instance to be created for the application,
|
|
47
|
+
but it is valid to create several `Inset` instances with different configuration
|
|
48
|
+
parameters.
|
|
49
|
+
|
|
50
|
+
A non-static version of `getInsets` as noted above was introduced replacing the
|
|
51
|
+
static method. However `getInsets` is also deprecated in effort to de-pluralize
|
|
52
|
+
the API for better naming conventions. It will be removed in a future release.
|
|
53
|
+
|
|
54
|
+
Any usages of `getInsets` should use `getInset` instead.
|
|
55
|
+
|
|
56
|
+
## 0.2.0 (December 6, 2023)
|
|
8
57
|
|
|
9
58
|
### Breaking Changes:
|
|
10
59
|
|
package/README.md
CHANGED
package/docs.md
CHANGED
|
@@ -8,15 +8,19 @@ This document describes the public API available to library consumers.
|
|
|
8
8
|
- [1.0 - General Notes](#10---general-notes)
|
|
9
9
|
- [1.1 - TypeScript](#11---typescript)
|
|
10
10
|
- [2.0 - Interfaces](#20---interfaces)
|
|
11
|
-
- [2.1 -
|
|
12
|
-
- [2.2 - IInsetCallbackFunc]()
|
|
13
|
-
- [3
|
|
14
|
-
- [
|
|
15
|
-
|
|
16
|
-
- [3.
|
|
11
|
+
- [2.1 - IInset](#21---iinset)
|
|
12
|
+
- [2.2 - IInsetCallbackFunc](#22---iinsertcallbackfunc)
|
|
13
|
+
- [2.3 - IInsetConfiguration](#23---iinsetconfiguration)
|
|
14
|
+
- [2.4 - InsetMask](#24---insetmask)
|
|
15
|
+
- [3.0 - Inset](#30---inset)
|
|
16
|
+
- [3.1 - create](#31---create)
|
|
17
|
+
- [3.2 - free](#32---free)
|
|
18
|
+
- [3.3 - addListener](#33---addlistener)
|
|
19
|
+
- [3.4 - removeListener](#34---removelistener)
|
|
20
|
+
- [3.5 - getInset](#35---getinset)
|
|
17
21
|
|
|
18
22
|
## 1.0 - General Notes
|
|
19
|
-
The namespace of this plugin is `totalpave.
|
|
23
|
+
The namespace of this plugin is `window.totalpave.Inset`. It will become available after the `deviceready` event. Throughout this document, I'll refer to the `totalpave.Inset` object as `Inset`.
|
|
20
24
|
|
|
21
25
|
### 1.1 - TypeScript
|
|
22
26
|
|
|
@@ -47,23 +51,102 @@ A type that describes the callback signature to [addListener](#31---addlistener)
|
|
|
47
51
|
type IInsetCallbackFunc = (inset: IInsets) => void;
|
|
48
52
|
```
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
### 2.3 - IInsetConfiguration
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
A type that describes the configuration object used when creating new `Inset` provider instances. All fields are optional.
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
Structure:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
interface IInsetConfiguration {
|
|
62
|
+
mask?: number;
|
|
63
|
+
includeRoundedCorners?: boolean;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If `mask` is not set, the default will be `DISPLAY_CUTOUT | SYSTEM_BARS`.
|
|
68
|
+
If `includeRoundedCorners` is not set, the default will be `true`.
|
|
69
|
+
|
|
70
|
+
### 2.4 - InsetMask
|
|
71
|
+
|
|
72
|
+
An enumeration of mask values. These correlate to [WindowInsetsCompat.Type](https://developer.android.com/reference/androidx/core/view/WindowInsetsCompat.Type) though the values may not match, they are mapped during runtime.
|
|
73
|
+
|
|
74
|
+
Currently the following mask values are supported:
|
|
75
|
+
|
|
76
|
+
- CAPTION_BAR
|
|
77
|
+
- DISPLAY_CUTOUT
|
|
78
|
+
- IME
|
|
79
|
+
- MANDATORY_SYSTEM_GESTURES
|
|
80
|
+
- NAVIGATION_BARS
|
|
81
|
+
- STATUS_BARS
|
|
82
|
+
- SYSTEM_BARS
|
|
83
|
+
- SYSTEM_GESTURES
|
|
84
|
+
- TAPPABLE_ELEMENT
|
|
85
|
+
|
|
86
|
+
If the android SDK introduces any newer ones, feel free to open a PR.
|
|
87
|
+
|
|
88
|
+
## 3.0 - Inset
|
|
89
|
+
|
|
90
|
+
`Inset` is a class that provides the APIs to retrieve and to listen for inset changes. It serves as a provider object and wil hold the configuration state as well as a collection of inset listeners. It is valid to have more than one `Inset` object alive in your application, with different configurations though it will be recommended to keep the instance count low for performance reasons.
|
|
91
|
+
|
|
92
|
+
Direct access to the `Inset` constructor is forbidden but an instance can be created via the static `create` method. If the `Inset` provider instance is no
|
|
93
|
+
longer used, it should be freed via `Insets.free(inset)` which will clean up
|
|
94
|
+
references to objects and allow them to be garbage collected, both in the webview
|
|
95
|
+
and in the Java/Native runtime. Additionally if your application holds any references to listener functions, they should also be cleaned up.
|
|
96
|
+
|
|
97
|
+
Note that the configuration parameters cannot be modified on an inset provider
|
|
98
|
+
instance.
|
|
99
|
+
|
|
100
|
+
### 3.1 - create
|
|
101
|
+
|
|
102
|
+
Creates a new `Inset` provider object with the given configuration. If the configuration object is missing, default values are used as indicated in [IInsetConfiguration](#23---iinsetconfiguration).
|
|
103
|
+
|
|
104
|
+
The returned `Inset` instance can be used to attach listeners on for inset
|
|
105
|
+
update notifications. When the provider is no longer needed, it should be freed by calling [free()](#32---free).
|
|
106
|
+
|
|
107
|
+
Creating `Inset` objects will trigger a layout request, triggering an update on
|
|
108
|
+
all inset providers.
|
|
109
|
+
|
|
110
|
+
##### Signature
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
static create(config?: IInsetConfiguration): Promise<Inset>;
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 3.2 - free
|
|
117
|
+
|
|
118
|
+
Frees an inset provider, cleaning up references to allow objects to be
|
|
119
|
+
garbage collected. Once freed, it will be unhooked from the global listener system
|
|
120
|
+
and that inset provider instance will no longer receive inset updates.
|
|
121
|
+
|
|
122
|
+
It's the applications responsibility to clean up any retained `IInsetCallbackFunc`
|
|
123
|
+
listener functions.
|
|
124
|
+
|
|
125
|
+
##### Signature
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
static free(inset: Inset): Promise<void>;
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Alternatively, the inset can be freed by calling the instance member `free`.
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
free(): Promise<void>;
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 3.3 - addListener
|
|
55
138
|
|
|
56
139
|
Attaches a new handler which will be invoked when the view layout/inset information changes. The reference of `callback` must be retained by the user for the [removeListener](#32---removelistener) call.
|
|
57
140
|
|
|
58
|
-
When the callback is invoked, it will receive an [
|
|
141
|
+
When the callback is invoked, it will receive an [IInset](#21---iinset) object as an argument.
|
|
59
142
|
|
|
60
143
|
##### Signature
|
|
61
144
|
|
|
62
145
|
```typescript
|
|
63
|
-
|
|
146
|
+
addListener(callback: IInsetCallbackFunc): void;
|
|
64
147
|
```
|
|
65
148
|
|
|
66
|
-
### 3.
|
|
149
|
+
### 3.4 - removeListener
|
|
67
150
|
|
|
68
151
|
Removes an attached handler from the listener pool.
|
|
69
152
|
This will be a no-op if the `callback` is not in the listener pool.
|
|
@@ -71,15 +154,15 @@ This will be a no-op if the `callback` is not in the listener pool.
|
|
|
71
154
|
##### Signature
|
|
72
155
|
|
|
73
156
|
```typescript
|
|
74
|
-
|
|
157
|
+
removeListener(callback: IInsetCallbackFunc): void;
|
|
75
158
|
```
|
|
76
159
|
|
|
77
|
-
### 3.
|
|
160
|
+
### 3.5 - getInset
|
|
78
161
|
|
|
79
|
-
Returns the last known [
|
|
162
|
+
Returns the last known [IInset](#21---iinset) object.
|
|
80
163
|
|
|
81
164
|
##### Signature
|
|
82
165
|
|
|
83
166
|
```typescript
|
|
84
|
-
|
|
167
|
+
getInset(): IInset;
|
|
85
168
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totalpave/cordova-plugin-insets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Cordova Android Plugin to receive native information regarding the unsafe area insets.",
|
|
5
5
|
"main": "www/insets.js",
|
|
6
6
|
"types": "www/api.d.ts",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"@rollup/plugin-node-resolve": "15.2.3",
|
|
31
31
|
"@types/cordova": "11.0.3",
|
|
32
32
|
"ejs": "3.1.9",
|
|
33
|
-
"rollup": "4.
|
|
33
|
+
"rollup": "4.9.2",
|
|
34
34
|
"rollup-plugin-progress": "1.1.2",
|
|
35
35
|
"rollup-plugin-typescript2": "0.36.0",
|
|
36
|
-
"ts-node": "10.9.
|
|
37
|
-
"typescript": "5.3.
|
|
36
|
+
"ts-node": "10.9.2",
|
|
37
|
+
"typescript": "5.3.3"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
|
40
40
|
"cordovaDependencies": {
|
package/plugin.xml
CHANGED
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
<plugin
|
|
3
3
|
xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
4
4
|
id="@totalpave/cordova-plugin-insets"
|
|
5
|
-
version="0.
|
|
5
|
+
version="0.3.1"
|
|
6
6
|
>
|
|
7
7
|
<name>cordova-plugin-insets</name>
|
|
8
8
|
<description>Cordova Android Plugin to receive native information regarding the unsafe area insets</description>
|
|
9
9
|
<author>Total Pave Inc.</author>
|
|
10
10
|
<license>Apache 2.0</license>
|
|
11
11
|
<keywords>cordova,cordova-android,unsafe-inset</keywords>
|
|
12
|
-
<repo>https://github.com/totalpaveinc/cordova-plugin-
|
|
12
|
+
<repo>https://github.com/totalpaveinc/cordova-plugin-insets</repo>
|
|
13
13
|
|
|
14
|
-
<js-module src="www/insets.js" name="
|
|
14
|
+
<js-module src="www/insets.js" name="Inset">
|
|
15
15
|
<merges target="totalpave" />
|
|
16
16
|
</js-module>
|
|
17
17
|
|
|
18
18
|
<platform name="android">
|
|
19
19
|
<config-file target="res/xml/config.xml" parent="/*">
|
|
20
|
-
<feature name="
|
|
21
|
-
<param name="android-package" value="com.totalpave.cordova.
|
|
20
|
+
<feature name="Inset">
|
|
21
|
+
<param name="android-package" value="com.totalpave.cordova.inset.Inset" />
|
|
22
22
|
</feature>
|
|
23
23
|
</config-file>
|
|
24
24
|
|
|
25
|
-
<source-file src="src/android/com/totalpave/cordova/
|
|
25
|
+
<source-file src="src/android/com/totalpave/cordova/inset/Inset.java" target-dir="src/com/totalpave/cordova/inset" />
|
|
26
26
|
</platform>
|
|
27
27
|
</plugin>
|
package/plugin.xml.ejs
CHANGED
|
@@ -9,19 +9,19 @@
|
|
|
9
9
|
<author>Total Pave Inc.</author>
|
|
10
10
|
<license>Apache 2.0</license>
|
|
11
11
|
<keywords>cordova,cordova-android,unsafe-inset</keywords>
|
|
12
|
-
<repo>https://github.com/totalpaveinc/cordova-plugin-
|
|
12
|
+
<repo>https://github.com/totalpaveinc/cordova-plugin-insets</repo>
|
|
13
13
|
|
|
14
|
-
<js-module src="www/insets.js" name="
|
|
14
|
+
<js-module src="www/insets.js" name="Inset">
|
|
15
15
|
<merges target="totalpave" />
|
|
16
16
|
</js-module>
|
|
17
17
|
|
|
18
18
|
<platform name="android">
|
|
19
19
|
<config-file target="res/xml/config.xml" parent="/*">
|
|
20
|
-
<feature name="
|
|
21
|
-
<param name="android-package" value="com.totalpave.cordova.
|
|
20
|
+
<feature name="Inset">
|
|
21
|
+
<param name="android-package" value="com.totalpave.cordova.inset.Inset" />
|
|
22
22
|
</feature>
|
|
23
23
|
</config-file>
|
|
24
24
|
|
|
25
|
-
<source-file src="src/android/com/totalpave/cordova/
|
|
25
|
+
<source-file src="src/android/com/totalpave/cordova/inset/Inset.java" target-dir="src/com/totalpave/cordova/inset" />
|
|
26
26
|
</platform>
|
|
27
27
|
</plugin>
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2019 Total Pave Inc.
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
package com.totalpave.cordova.inset;
|
|
18
|
+
|
|
19
|
+
import android.content.res.Configuration;
|
|
20
|
+
import android.content.Context;
|
|
21
|
+
import android.os.Build;
|
|
22
|
+
import android.view.RoundedCorner;
|
|
23
|
+
import android.view.WindowInsets;
|
|
24
|
+
import androidx.core.view.ViewCompat;
|
|
25
|
+
import androidx.core.view.WindowInsetsCompat;
|
|
26
|
+
import org.apache.cordova.CallbackContext;
|
|
27
|
+
import org.apache.cordova.CordovaPlugin;
|
|
28
|
+
import org.apache.cordova.PluginResult.Status;
|
|
29
|
+
import org.apache.cordova.PluginResult;
|
|
30
|
+
import org.json.JSONArray;
|
|
31
|
+
import org.json.JSONObject;
|
|
32
|
+
import org.json.JSONException;
|
|
33
|
+
import java.lang.NumberFormatException;
|
|
34
|
+
import java.util.ArrayList;
|
|
35
|
+
import java.util.HashMap;
|
|
36
|
+
import java.util.UUID;
|
|
37
|
+
|
|
38
|
+
public class Inset extends CordovaPlugin {
|
|
39
|
+
public static final int DEFAULT_INSET_MASK = WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.systemBars();
|
|
40
|
+
public static final boolean DEFAULT_INCLUDE_ROUNDED_CORNERS = true;
|
|
41
|
+
|
|
42
|
+
public static class WebviewMask {
|
|
43
|
+
private WebviewMask() {}
|
|
44
|
+
|
|
45
|
+
public static final int CAPTION_BAR = 1;
|
|
46
|
+
public static final int DISPLAY_CUTOUT = 1 << 1;
|
|
47
|
+
public static final int IME = 1 << 2;
|
|
48
|
+
public static final int MANDATORY_SYSTEM_GESTURES = 1 << 3;
|
|
49
|
+
public static final int NAVIGATION_BARS = 1 << 4;
|
|
50
|
+
public static final int STATUS_BARS = 1 << 5;
|
|
51
|
+
public static final int SYSTEM_BARS = 1 << 6;
|
|
52
|
+
public static final int SYSTEM_GESTURES = 1 << 7;
|
|
53
|
+
public static final int TAPPABLE_ELEMENT = 1 << 8;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public static class ListenerConfiguration {
|
|
57
|
+
public Integer mask;
|
|
58
|
+
public boolean includeRoundedCorners;
|
|
59
|
+
|
|
60
|
+
public ListenerConfiguration() {
|
|
61
|
+
mask = null;
|
|
62
|
+
includeRoundedCorners = DEFAULT_INCLUDE_ROUNDED_CORNERS;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public static class Listener {
|
|
67
|
+
private final Context $context;
|
|
68
|
+
private final CallbackContext $callback;
|
|
69
|
+
private JSONObject $currentInset;
|
|
70
|
+
private final int $mask;
|
|
71
|
+
private final boolean $includeRoundedCorners;
|
|
72
|
+
private final UUID $id;
|
|
73
|
+
|
|
74
|
+
public Listener(Context context, CallbackContext callback, ListenerConfiguration config) {
|
|
75
|
+
$id = UUID.randomUUID();
|
|
76
|
+
$context = context;
|
|
77
|
+
$callback = callback;
|
|
78
|
+
if (config.mask == null) {
|
|
79
|
+
$mask = DEFAULT_INSET_MASK;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
$mask = $mapMask(config.mask);
|
|
83
|
+
}
|
|
84
|
+
$includeRoundedCorners = config.includeRoundedCorners;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public String getID() {
|
|
88
|
+
return $id.toString();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public void onInsetUpdate(WindowInsetsCompat insetProvider) {
|
|
92
|
+
JSONObject result = new JSONObject();
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
float density = $context.getResources().getDisplayMetrics().density;
|
|
96
|
+
|
|
97
|
+
// Ideally, we'd import this, but it shares the same name as our plugin
|
|
98
|
+
androidx.core.graphics.Insets insets = insetProvider.getInsets($mask);
|
|
99
|
+
|
|
100
|
+
double topLeftRadius = 0.0;
|
|
101
|
+
double topRightRadius = 0.0;
|
|
102
|
+
double botLeftRadius = 0.0;
|
|
103
|
+
double botRightRadius = 0.0;
|
|
104
|
+
|
|
105
|
+
if ($includeRoundedCorners && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
106
|
+
WindowInsets sourceInsets = insetProvider.toWindowInsets();
|
|
107
|
+
if (sourceInsets != null) {
|
|
108
|
+
RoundedCorner topLeft = sourceInsets.getRoundedCorner(RoundedCorner.POSITION_TOP_LEFT);
|
|
109
|
+
RoundedCorner topRight = sourceInsets.getRoundedCorner(RoundedCorner.POSITION_TOP_RIGHT);
|
|
110
|
+
RoundedCorner botLeft = sourceInsets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
|
|
111
|
+
RoundedCorner botRight = sourceInsets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
|
|
112
|
+
|
|
113
|
+
if (topLeft != null) {
|
|
114
|
+
int radius = topLeft.getRadius();
|
|
115
|
+
topLeftRadius = (double) radius / density;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (topRight != null) {
|
|
119
|
+
int radius = topRight.getRadius();
|
|
120
|
+
topRightRadius = (double) radius / density;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (botLeft != null) {
|
|
124
|
+
int radius = botLeft.getRadius();
|
|
125
|
+
botLeftRadius = (double) radius / density;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (botRight != null) {
|
|
129
|
+
int radius = botRight.getRadius();
|
|
130
|
+
botRightRadius = (double) radius / density;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
double top = insets.top / density;
|
|
136
|
+
double right = insets.right / density;
|
|
137
|
+
double bottom = insets.bottom / density;
|
|
138
|
+
double left = insets.left / density;
|
|
139
|
+
|
|
140
|
+
// First we will get the screen orientation. This may be locked by the user, so it
|
|
141
|
+
// may not match the physical orientation. If the orientation cannot be determined,
|
|
142
|
+
// we will assume PORTRAIT
|
|
143
|
+
int orientation = Configuration.ORIENTATION_UNDEFINED;
|
|
144
|
+
|
|
145
|
+
// There are other orientation types, albeit deprecated and supposedly no longer
|
|
146
|
+
// used, but this limits us from handling only portrait and landscape.
|
|
147
|
+
switch ($context.getResources().getConfiguration().orientation) {
|
|
148
|
+
case Configuration.ORIENTATION_LANDSCAPE:
|
|
149
|
+
case Configuration.ORIENTATION_PORTRAIT:
|
|
150
|
+
orientation = $context.getResources().getConfiguration().orientation;
|
|
151
|
+
break;
|
|
152
|
+
case Configuration.ORIENTATION_SQUARE:
|
|
153
|
+
case Configuration.ORIENTATION_UNDEFINED:
|
|
154
|
+
// SQUARE is not used anymore since API 16, but included just to satisfy
|
|
155
|
+
// lint warnings. If undefined, then fallback to PORTRAIT
|
|
156
|
+
orientation = Configuration.ORIENTATION_PORTRAIT;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Insets do not include rounded corner radius. If an inset is present, it
|
|
161
|
+
// generally will be big enough to cover the rounded corner. This is a coincidence,
|
|
162
|
+
// not a designed thing. In either case, we need to determine how much space is
|
|
163
|
+
// required to cover the rounded corner and take the higher between the inset and
|
|
164
|
+
// the rounded corner.
|
|
165
|
+
|
|
166
|
+
// If portrait, then top-left & top-right is applied to the top inset,
|
|
167
|
+
// and bot-left & bot-right is applied to the bottom inset
|
|
168
|
+
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
|
|
169
|
+
top = Math.max(Math.max(top, topLeftRadius), topRightRadius);
|
|
170
|
+
bottom = Math.max(Math.max(bottom, botLeftRadius), botRightRadius);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
left = Math.max(Math.max(left, topLeftRadius), botLeftRadius);
|
|
174
|
+
right = Math.max(Math.max(right, topRightRadius), botRightRadius);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
result.put("top", top);
|
|
178
|
+
result.put("right", right);
|
|
179
|
+
result.put("bottom", bottom);
|
|
180
|
+
result.put("left", left);
|
|
181
|
+
}
|
|
182
|
+
catch (JSONException e) {
|
|
183
|
+
e.printStackTrace();
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this.$currentInset = result;
|
|
188
|
+
|
|
189
|
+
JSONObject update = new JSONObject();
|
|
190
|
+
try {
|
|
191
|
+
update.put("type", "update");
|
|
192
|
+
update.put("id", this.getID());
|
|
193
|
+
update.put("data", this.$currentInset);
|
|
194
|
+
}
|
|
195
|
+
catch (JSONException ex) {
|
|
196
|
+
throw new RuntimeException(ex);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
PluginResult response = new PluginResult(Status.OK, update);
|
|
200
|
+
response.setKeepCallback(true);
|
|
201
|
+
$callback.sendPluginResult(response);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private int $mapMask(int webviewMask) {
|
|
205
|
+
int insetTypeMask = 0;
|
|
206
|
+
|
|
207
|
+
if ((webviewMask & WebviewMask.CAPTION_BAR) != 0) {
|
|
208
|
+
insetTypeMask |= WindowInsetsCompat.Type.captionBar();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if ((webviewMask & WebviewMask.DISPLAY_CUTOUT) != 0) {
|
|
212
|
+
insetTypeMask |= WindowInsetsCompat.Type.displayCutout();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if ((webviewMask & WebviewMask.IME) != 0) {
|
|
216
|
+
insetTypeMask |= WindowInsetsCompat.Type.ime();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if ((webviewMask & WebviewMask.MANDATORY_SYSTEM_GESTURES) != 0) {
|
|
220
|
+
insetTypeMask |= WindowInsetsCompat.Type.mandatorySystemGestures();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if ((webviewMask & WebviewMask.NAVIGATION_BARS) != 0) {
|
|
224
|
+
insetTypeMask |= WindowInsetsCompat.Type.navigationBars();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if ((webviewMask & WebviewMask.STATUS_BARS) != 0) {
|
|
228
|
+
insetTypeMask |= WindowInsetsCompat.Type.statusBars();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if ((webviewMask & WebviewMask.SYSTEM_BARS) != 0) {
|
|
232
|
+
insetTypeMask |= WindowInsetsCompat.Type.systemBars();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if ((webviewMask & WebviewMask.SYSTEM_GESTURES) != 0) {
|
|
236
|
+
insetTypeMask |= WindowInsetsCompat.Type.systemGestures();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if ((webviewMask & WebviewMask.TAPPABLE_ELEMENT) != 0) {
|
|
240
|
+
insetTypeMask |= WindowInsetsCompat.Type.tappableElement();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return insetTypeMask;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private ArrayList<Listener> $listeners;
|
|
248
|
+
private HashMap<String, Listener> $listenerMap;
|
|
249
|
+
private final Object $listenerLock = new Object();
|
|
250
|
+
|
|
251
|
+
@Override
|
|
252
|
+
protected void pluginInitialize() {
|
|
253
|
+
$listeners = new ArrayList<>();
|
|
254
|
+
$listenerMap = new HashMap<>();
|
|
255
|
+
|
|
256
|
+
ViewCompat.setOnApplyWindowInsetsListener(
|
|
257
|
+
this.cordova.getActivity().findViewById(android.R.id.content), (v, insetProvider) -> {
|
|
258
|
+
|
|
259
|
+
synchronized($listenerLock) {
|
|
260
|
+
for (Listener listener : $listeners) {
|
|
261
|
+
listener.onInsetUpdate(insetProvider);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return WindowInsetsCompat.CONSUMED;
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private void $createNewListener(CallbackContext callback, JSONArray args) {
|
|
271
|
+
ListenerConfiguration config = new ListenerConfiguration();
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
JSONObject params = args.getJSONObject(0);
|
|
275
|
+
if (params.has("mask")) {
|
|
276
|
+
config.mask = params.getInt("mask");
|
|
277
|
+
}
|
|
278
|
+
if (params.has("includeRoundedCorners")) {
|
|
279
|
+
config.includeRoundedCorners = params.getBoolean("includeRoundedCorners");
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch (JSONException ex) {
|
|
283
|
+
ex.printStackTrace();
|
|
284
|
+
callback.error(ex.getMessage());
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
Listener listener = new Listener(cordova.getActivity(), callback, config);
|
|
288
|
+
synchronized ($listenerLock) {
|
|
289
|
+
$listeners.add(listener);
|
|
290
|
+
$listenerMap.put(listener.getID(), listener);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
cordova.getActivity().runOnUiThread(() -> {
|
|
294
|
+
ViewCompat.requestApplyInsets(cordova.getActivity().findViewById(android.R.id.content));
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
JSONObject responseData = new JSONObject();
|
|
298
|
+
try {
|
|
299
|
+
responseData.put("type", "init");
|
|
300
|
+
responseData.put("data", listener.getID());
|
|
301
|
+
}
|
|
302
|
+
catch(JSONException e) {
|
|
303
|
+
throw new RuntimeException("Could not build listener creation response", e);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
PluginResult result = new PluginResult(Status.OK, responseData);
|
|
307
|
+
result.setKeepCallback(true);
|
|
308
|
+
callback.sendPluginResult(result);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
private void $freeListener(CallbackContext callback, JSONArray args) throws JSONException {
|
|
312
|
+
String id = args.getString(0);
|
|
313
|
+
|
|
314
|
+
synchronized ($listenerLock) {
|
|
315
|
+
Listener listener = $listenerMap.remove(id);
|
|
316
|
+
if (listener != null) {
|
|
317
|
+
$listeners.remove(listener);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
callback.success();
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
@Override
|
|
325
|
+
public boolean execute(String action, JSONArray args, CallbackContext callback) throws JSONException, NumberFormatException {
|
|
326
|
+
if (action.equals("create")) {
|
|
327
|
+
$createNewListener(callback, args);
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
else if (action.equals("delete")) {
|
|
331
|
+
$freeListener(callback, args);
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2022-2024 Total Pave Inc.
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export interface IInset {
|
|
18
|
+
top: number;
|
|
19
|
+
right: number;
|
|
20
|
+
bottom: number;
|
|
21
|
+
left: number;
|
|
22
|
+
}
|