html2apk 0.1.0 → 0.3.0
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/README.md +318 -3
- package/examples/minimal/app.json +5 -0
- package/examples/minimal/dist/MeuApp-1.0.0-debug.apk +0 -0
- package/package.json +3 -2
- package/src/cli/index.js +22 -1
- package/src/cordova/config-xml.js +98 -6
- package/src/core/build-apk.js +150 -1
- package/src/core/config.js +74 -5
- package/src/core/defaults.js +15 -1
- package/src/desktop/main.js +30 -4
- package/src/desktop/preload.js +1 -0
- package/src/desktop/renderer/index.html +69 -2
- package/src/desktop/renderer/renderer.js +583 -2
- package/src/desktop/renderer/styles.css +131 -4
- package/src/templates/cordova-plugin-html2apk-bridge/plugin.xml +6 -0
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/FloatingIconService.java +141 -0
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/Html2ApkBridge.java +1674 -45
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/NotificationReceiver.java +19 -5
- package/src/templates/cordova-plugin-html2apk-bridge/src/android/NotificationStore.java +13 -1
- package/src/templates/cordova-plugin-html2apk-bridge/www/html2apk-bridge.js +525 -1
- package/src/templates/html2apk-auto-theme.js +144 -0
- package/src/templates/html2apk-onesignal.js +155 -0
|
@@ -381,7 +381,9 @@ h2 {
|
|
|
381
381
|
.toggle-grid,
|
|
382
382
|
.pipeline,
|
|
383
383
|
.review-grid,
|
|
384
|
-
.help-grid
|
|
384
|
+
.help-grid,
|
|
385
|
+
.permission-grid,
|
|
386
|
+
.code-grid {
|
|
385
387
|
display: grid;
|
|
386
388
|
gap: 16px;
|
|
387
389
|
}
|
|
@@ -489,10 +491,62 @@ h2 {
|
|
|
489
491
|
outline: none;
|
|
490
492
|
}
|
|
491
493
|
|
|
492
|
-
.icon-field
|
|
494
|
+
.icon-field,
|
|
495
|
+
.onesignal-field,
|
|
496
|
+
.permissions-field {
|
|
493
497
|
grid-column: span 2;
|
|
494
498
|
}
|
|
495
499
|
|
|
500
|
+
.field small {
|
|
501
|
+
color: var(--muted);
|
|
502
|
+
line-height: 1.4;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
.permission-grid {
|
|
506
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
507
|
+
gap: 10px;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
.permission-option {
|
|
511
|
+
min-height: 74px;
|
|
512
|
+
border: 1px solid var(--line);
|
|
513
|
+
border-radius: 8px;
|
|
514
|
+
padding: 12px;
|
|
515
|
+
display: flex;
|
|
516
|
+
gap: 10px;
|
|
517
|
+
align-items: center;
|
|
518
|
+
background: var(--bg);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.permission-option input {
|
|
522
|
+
width: 20px;
|
|
523
|
+
height: 20px;
|
|
524
|
+
accent-color: var(--blue);
|
|
525
|
+
flex: 0 0 auto;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.permission-option strong,
|
|
529
|
+
.permission-option small {
|
|
530
|
+
display: block;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.permission-option small {
|
|
534
|
+
margin-top: 4px;
|
|
535
|
+
color: var(--muted);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.color-picker {
|
|
539
|
+
display: grid;
|
|
540
|
+
grid-template-columns: 64px minmax(0, 1fr);
|
|
541
|
+
gap: 10px;
|
|
542
|
+
align-items: center;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.field .color-picker input[type="color"] {
|
|
546
|
+
width: 64px;
|
|
547
|
+
padding: 4px;
|
|
548
|
+
}
|
|
549
|
+
|
|
496
550
|
.icon-picker {
|
|
497
551
|
display: grid;
|
|
498
552
|
grid-template-columns: 86px minmax(0, 1fr);
|
|
@@ -800,6 +854,75 @@ h2 {
|
|
|
800
854
|
padding: 20px;
|
|
801
855
|
}
|
|
802
856
|
|
|
857
|
+
.creator-card {
|
|
858
|
+
display: grid;
|
|
859
|
+
align-content: start;
|
|
860
|
+
gap: 12px;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
.creator-card p {
|
|
864
|
+
margin: 0;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
.instagram-action {
|
|
868
|
+
justify-self: start;
|
|
869
|
+
margin-top: 4px;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
.view-intro {
|
|
873
|
+
max-width: 760px;
|
|
874
|
+
color: var(--muted);
|
|
875
|
+
margin-bottom: 18px;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.code-grid {
|
|
879
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.code-card {
|
|
883
|
+
border: 1px solid var(--line);
|
|
884
|
+
border-radius: 8px;
|
|
885
|
+
background: var(--panel);
|
|
886
|
+
box-shadow: var(--shadow);
|
|
887
|
+
padding: 16px;
|
|
888
|
+
display: grid;
|
|
889
|
+
gap: 10px;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
.code-card code {
|
|
893
|
+
overflow-wrap: anywhere;
|
|
894
|
+
color: #d6e4f7;
|
|
895
|
+
background: #0c1117;
|
|
896
|
+
border-radius: 7px;
|
|
897
|
+
padding: 10px;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
.code-card span {
|
|
901
|
+
color: var(--blue);
|
|
902
|
+
font-weight: 800;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
.code-card p {
|
|
906
|
+
margin: 0;
|
|
907
|
+
color: var(--muted);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.code-card small {
|
|
911
|
+
display: block;
|
|
912
|
+
color: var(--green);
|
|
913
|
+
line-height: 1.45;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.code-card small strong {
|
|
917
|
+
color: var(--text);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
.code-card .handling {
|
|
921
|
+
color: var(--muted);
|
|
922
|
+
border-top: 1px solid var(--line);
|
|
923
|
+
padding-top: 10px;
|
|
924
|
+
}
|
|
925
|
+
|
|
803
926
|
.success-view {
|
|
804
927
|
min-height: 100%;
|
|
805
928
|
display: none;
|
|
@@ -1152,11 +1275,15 @@ body.logs-visible .bottom-log-bar {
|
|
|
1152
1275
|
.toggle-grid,
|
|
1153
1276
|
.pipeline,
|
|
1154
1277
|
.review-grid,
|
|
1155
|
-
.help-grid
|
|
1278
|
+
.help-grid,
|
|
1279
|
+
.permission-grid,
|
|
1280
|
+
.code-grid {
|
|
1156
1281
|
grid-template-columns: 1fr;
|
|
1157
1282
|
}
|
|
1158
1283
|
|
|
1159
|
-
.icon-field
|
|
1284
|
+
.icon-field,
|
|
1285
|
+
.onesignal-field,
|
|
1286
|
+
.permissions-field {
|
|
1160
1287
|
grid-column: span 1;
|
|
1161
1288
|
}
|
|
1162
1289
|
|
|
@@ -16,11 +16,16 @@
|
|
|
16
16
|
<config-file target="AndroidManifest.xml" parent="/manifest">
|
|
17
17
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
18
18
|
<uses-permission android:name="android.permission.VIBRATE" />
|
|
19
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
20
|
+
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
21
|
+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
22
|
+
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
|
|
19
23
|
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
|
20
24
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
|
21
25
|
</config-file>
|
|
22
26
|
|
|
23
27
|
<config-file target="AndroidManifest.xml" parent="/manifest/application">
|
|
28
|
+
<service android:name="dev.html2apk.bridge.FloatingIconService" android:exported="false" />
|
|
24
29
|
<receiver android:name="dev.html2apk.bridge.NotificationReceiver" android:exported="false" />
|
|
25
30
|
<receiver android:name="dev.html2apk.bridge.BootReceiver" android:enabled="true" android:exported="true">
|
|
26
31
|
<intent-filter>
|
|
@@ -31,6 +36,7 @@
|
|
|
31
36
|
</config-file>
|
|
32
37
|
|
|
33
38
|
<source-file src="src/android/Html2ApkBridge.java" target-dir="app/src/main/java/dev/html2apk/bridge" />
|
|
39
|
+
<source-file src="src/android/FloatingIconService.java" target-dir="app/src/main/java/dev/html2apk/bridge" />
|
|
34
40
|
<source-file src="src/android/NotificationReceiver.java" target-dir="app/src/main/java/dev/html2apk/bridge" />
|
|
35
41
|
<source-file src="src/android/BootReceiver.java" target-dir="app/src/main/java/dev/html2apk/bridge" />
|
|
36
42
|
<source-file src="src/android/NotificationStore.java" target-dir="app/src/main/java/dev/html2apk/bridge" />
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
package dev.html2apk.bridge;
|
|
2
|
+
|
|
3
|
+
import android.app.Service;
|
|
4
|
+
import android.content.Intent;
|
|
5
|
+
import android.graphics.PixelFormat;
|
|
6
|
+
import android.graphics.drawable.GradientDrawable;
|
|
7
|
+
import android.os.Build;
|
|
8
|
+
import android.os.IBinder;
|
|
9
|
+
import android.provider.Settings;
|
|
10
|
+
import android.view.Gravity;
|
|
11
|
+
import android.view.MotionEvent;
|
|
12
|
+
import android.view.View;
|
|
13
|
+
import android.view.WindowManager;
|
|
14
|
+
import android.widget.ImageView;
|
|
15
|
+
|
|
16
|
+
public class FloatingIconService extends Service {
|
|
17
|
+
private WindowManager windowManager;
|
|
18
|
+
private View floatingView;
|
|
19
|
+
private WindowManager.LayoutParams params;
|
|
20
|
+
private int startX;
|
|
21
|
+
private int startY;
|
|
22
|
+
private float touchStartX;
|
|
23
|
+
private float touchStartY;
|
|
24
|
+
|
|
25
|
+
@Override
|
|
26
|
+
public IBinder onBind(Intent intent) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Override
|
|
31
|
+
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
32
|
+
showFloatingIcon();
|
|
33
|
+
return START_STICKY;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Override
|
|
37
|
+
public void onDestroy() {
|
|
38
|
+
removeFloatingIcon();
|
|
39
|
+
super.onDestroy();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private void showFloatingIcon() {
|
|
43
|
+
if (floatingView != null) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
|
|
48
|
+
stopSelf();
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
|
53
|
+
if (windowManager == null) {
|
|
54
|
+
stopSelf();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
ImageView icon = new ImageView(this);
|
|
59
|
+
int size = dp(58);
|
|
60
|
+
int padding = dp(8);
|
|
61
|
+
icon.setImageDrawable(getApplicationInfo().loadIcon(getPackageManager()));
|
|
62
|
+
icon.setPadding(padding, padding, padding, padding);
|
|
63
|
+
|
|
64
|
+
GradientDrawable background = new GradientDrawable();
|
|
65
|
+
background.setShape(GradientDrawable.OVAL);
|
|
66
|
+
background.setColor(0xff126fff);
|
|
67
|
+
icon.setBackground(background);
|
|
68
|
+
|
|
69
|
+
int windowType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
|
70
|
+
? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
|
|
71
|
+
: WindowManager.LayoutParams.TYPE_PHONE;
|
|
72
|
+
|
|
73
|
+
params = new WindowManager.LayoutParams(
|
|
74
|
+
size,
|
|
75
|
+
size,
|
|
76
|
+
windowType,
|
|
77
|
+
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
|
|
78
|
+
PixelFormat.TRANSLUCENT
|
|
79
|
+
);
|
|
80
|
+
params.gravity = Gravity.TOP | Gravity.START;
|
|
81
|
+
params.x = dp(16);
|
|
82
|
+
params.y = dp(96);
|
|
83
|
+
|
|
84
|
+
icon.setOnTouchListener(new View.OnTouchListener() {
|
|
85
|
+
@Override
|
|
86
|
+
public boolean onTouch(View view, MotionEvent event) {
|
|
87
|
+
switch (event.getAction()) {
|
|
88
|
+
case MotionEvent.ACTION_DOWN:
|
|
89
|
+
startX = params.x;
|
|
90
|
+
startY = params.y;
|
|
91
|
+
touchStartX = event.getRawX();
|
|
92
|
+
touchStartY = event.getRawY();
|
|
93
|
+
return true;
|
|
94
|
+
case MotionEvent.ACTION_MOVE:
|
|
95
|
+
params.x = startX + Math.round(event.getRawX() - touchStartX);
|
|
96
|
+
params.y = startY + Math.round(event.getRawY() - touchStartY);
|
|
97
|
+
windowManager.updateViewLayout(floatingView, params);
|
|
98
|
+
return true;
|
|
99
|
+
case MotionEvent.ACTION_UP:
|
|
100
|
+
float deltaX = Math.abs(event.getRawX() - touchStartX);
|
|
101
|
+
float deltaY = Math.abs(event.getRawY() - touchStartY);
|
|
102
|
+
if (deltaX < dp(6) && deltaY < dp(6)) {
|
|
103
|
+
openApp();
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
default:
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
floatingView = icon;
|
|
113
|
+
try {
|
|
114
|
+
windowManager.addView(floatingView, params);
|
|
115
|
+
} catch (RuntimeException error) {
|
|
116
|
+
floatingView = null;
|
|
117
|
+
stopSelf();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private void removeFloatingIcon() {
|
|
122
|
+
if (windowManager != null && floatingView != null) {
|
|
123
|
+
windowManager.removeView(floatingView);
|
|
124
|
+
}
|
|
125
|
+
floatingView = null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private void openApp() {
|
|
129
|
+
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(getPackageName());
|
|
130
|
+
if (launchIntent == null) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
135
|
+
startActivity(launchIntent);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
private int dp(int value) {
|
|
139
|
+
return Math.round(value * getResources().getDisplayMetrics().density);
|
|
140
|
+
}
|
|
141
|
+
}
|