html2apk 0.5.0 → 0.8.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.
@@ -492,6 +492,7 @@ h2 {
492
492
  }
493
493
 
494
494
  .icon-field,
495
+ .keystore-field,
495
496
  .onesignal-field,
496
497
  .permissions-field {
497
498
  grid-column: span 2;
@@ -569,6 +570,24 @@ h2 {
569
570
  gap: 10px;
570
571
  }
571
572
 
573
+ .keystore-grid {
574
+ display: grid;
575
+ grid-template-columns: repeat(2, minmax(0, 1fr));
576
+ gap: 12px;
577
+ }
578
+
579
+ .keystore-grid label {
580
+ display: grid;
581
+ gap: 8px;
582
+ }
583
+
584
+ .inline-picker {
585
+ display: grid;
586
+ grid-template-columns: minmax(0, 1fr) auto;
587
+ gap: 10px;
588
+ align-items: center;
589
+ }
590
+
572
591
  .validation-panel {
573
592
  margin-top: 16px;
574
593
  border: 1px solid color-mix(in srgb, var(--red) 42%, var(--line));
@@ -621,6 +640,165 @@ h2 {
621
640
  color: var(--muted);
622
641
  }
623
642
 
643
+ .file-editor-layout {
644
+ display: grid;
645
+ grid-template-columns: minmax(220px, 290px) minmax(0, 1fr);
646
+ gap: 16px;
647
+ min-height: 620px;
648
+ }
649
+
650
+ .file-tree-panel,
651
+ .file-editor-panel {
652
+ border: 1px solid var(--line);
653
+ background: var(--panel);
654
+ border-radius: 8px;
655
+ box-shadow: var(--shadow);
656
+ }
657
+
658
+ .file-tree-panel {
659
+ padding: 14px;
660
+ overflow: auto;
661
+ }
662
+
663
+ .file-tree-panel > strong {
664
+ display: block;
665
+ margin-bottom: 12px;
666
+ }
667
+
668
+ .file-tree {
669
+ display: grid;
670
+ gap: 4px;
671
+ }
672
+
673
+ .file-tree-empty {
674
+ color: var(--muted);
675
+ line-height: 1.45;
676
+ }
677
+
678
+ .file-row {
679
+ width: 100%;
680
+ min-height: 34px;
681
+ border: 0;
682
+ border-radius: 7px;
683
+ padding: 0 8px;
684
+ background: transparent;
685
+ color: var(--text);
686
+ display: flex;
687
+ align-items: center;
688
+ gap: 8px;
689
+ text-align: left;
690
+ }
691
+
692
+ .file-row:hover,
693
+ .file-row.active {
694
+ background: var(--blue-soft);
695
+ color: var(--blue);
696
+ }
697
+
698
+ .file-row:disabled {
699
+ cursor: not-allowed;
700
+ color: var(--muted);
701
+ opacity: .62;
702
+ }
703
+
704
+ .folder-row {
705
+ margin-top: 8px;
706
+ min-height: 28px;
707
+ color: var(--muted);
708
+ font-size: 12px;
709
+ font-weight: 800;
710
+ text-transform: uppercase;
711
+ }
712
+
713
+ .file-editor-panel {
714
+ display: grid;
715
+ grid-template-rows: auto minmax(280px, 1fr) minmax(180px, 240px);
716
+ overflow: hidden;
717
+ }
718
+
719
+ .file-editor-meta {
720
+ min-height: 50px;
721
+ border-bottom: 1px solid var(--line);
722
+ padding: 12px 14px;
723
+ display: flex;
724
+ align-items: center;
725
+ justify-content: space-between;
726
+ gap: 12px;
727
+ }
728
+
729
+ .file-editor-meta strong {
730
+ overflow: hidden;
731
+ text-overflow: ellipsis;
732
+ white-space: nowrap;
733
+ }
734
+
735
+ #fileLanguageBadge {
736
+ flex: 0 0 auto;
737
+ min-width: 46px;
738
+ min-height: 26px;
739
+ padding: 5px 9px;
740
+ border-radius: 8px;
741
+ background: var(--blue-soft);
742
+ color: var(--blue);
743
+ text-align: center;
744
+ font-size: 12px;
745
+ font-weight: 800;
746
+ }
747
+
748
+ #fileEditorInput {
749
+ width: 100%;
750
+ min-height: 0;
751
+ resize: none;
752
+ border: 0;
753
+ border-bottom: 1px solid var(--line);
754
+ outline: none;
755
+ padding: 16px;
756
+ background: var(--bg);
757
+ color: var(--text);
758
+ font: 13px/1.55 ui-monospace, SFMono-Regular, Consolas, monospace;
759
+ tab-size: 2;
760
+ }
761
+
762
+ .syntax-preview-wrap {
763
+ min-height: 0;
764
+ display: grid;
765
+ grid-template-rows: auto minmax(0, 1fr);
766
+ background: color-mix(in srgb, var(--panel-soft) 55%, var(--panel));
767
+ }
768
+
769
+ .syntax-preview-wrap > strong {
770
+ padding: 10px 14px 0;
771
+ color: var(--muted);
772
+ font-size: 12px;
773
+ }
774
+
775
+ .syntax-preview {
776
+ margin: 0;
777
+ padding: 12px 14px 16px;
778
+ overflow: auto;
779
+ color: var(--text);
780
+ font: 12px/1.55 ui-monospace, SFMono-Regular, Consolas, monospace;
781
+ }
782
+
783
+ .syntax-token-tag,
784
+ .syntax-token-keyword {
785
+ color: var(--blue);
786
+ font-weight: 800;
787
+ }
788
+
789
+ .syntax-token-string {
790
+ color: var(--green);
791
+ }
792
+
793
+ .syntax-token-comment {
794
+ color: var(--muted);
795
+ font-style: italic;
796
+ }
797
+
798
+ .syntax-token-number {
799
+ color: var(--amber);
800
+ }
801
+
624
802
  .preference-row {
625
803
  min-height: 112px;
626
804
  padding: 20px;
@@ -1340,11 +1518,22 @@ body.logs-visible .bottom-log-bar {
1340
1518
  }
1341
1519
 
1342
1520
  .icon-field,
1521
+ .keystore-field,
1343
1522
  .onesignal-field,
1344
1523
  .permissions-field {
1345
1524
  grid-column: span 1;
1346
1525
  }
1347
1526
 
1527
+ .keystore-grid,
1528
+ .inline-picker,
1529
+ .file-editor-layout {
1530
+ grid-template-columns: 1fr;
1531
+ }
1532
+
1533
+ .file-editor-layout {
1534
+ min-height: 820px;
1535
+ }
1536
+
1348
1537
  .view-header,
1349
1538
  .result-panel,
1350
1539
  .progress-panel,
@@ -425,6 +425,22 @@ public class Html2ApkBridge extends CordovaPlugin {
425
425
  return false;
426
426
  }
427
427
 
428
+ private void rejectBusyCallback(CallbackContext callbackContext, String operation) {
429
+ callbackContext.error(operation + " is already waiting for Android. Wait for the previous call to finish.");
430
+ }
431
+
432
+ private boolean hasPendingNotificationPermissionRequest() {
433
+ return pendingNotificationCallback != null || notificationPermissionCallback != null;
434
+ }
435
+
436
+ private boolean hasPendingCameraPermissionRequest() {
437
+ return pendingFlashlightCallback != null || cameraPermissionCallback != null;
438
+ }
439
+
440
+ private boolean hasPendingMicrophonePermissionRequest() {
441
+ return pendingMicStartCallback != null || microphonePermissionCallback != null;
442
+ }
443
+
428
444
  @Override
429
445
  public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
430
446
  if (requestCode == REQUEST_CAMERA) {
@@ -761,6 +777,10 @@ public class Html2ApkBridge extends CordovaPlugin {
761
777
  callbackContext.success(notificationPermissionStatus());
762
778
  return;
763
779
  }
780
+ if (hasPendingNotificationPermissionRequest()) {
781
+ rejectBusyCallback(callbackContext, "POST_NOTIFICATIONS permission");
782
+ return;
783
+ }
764
784
 
765
785
  notificationPermissionCallback = callbackContext;
766
786
  rememberRuntimePermissionRequest(Manifest.permission.POST_NOTIFICATIONS);
@@ -776,6 +796,10 @@ public class Html2ApkBridge extends CordovaPlugin {
776
796
  if (hasNotificationPermission()) {
777
797
  return false;
778
798
  }
799
+ if (hasPendingNotificationPermissionRequest()) {
800
+ rejectBusyCallback(callbackContext, "POST_NOTIFICATIONS permission");
801
+ return true;
802
+ }
779
803
 
780
804
  pendingNotificationOptions = options;
781
805
  pendingNotificationSchedule = schedule;
@@ -1063,6 +1087,10 @@ public class Html2ApkBridge extends CordovaPlugin {
1063
1087
  callbackContext.success(runtimePermissionResult(Manifest.permission.CAMERA, true, false, true));
1064
1088
  return;
1065
1089
  }
1090
+ if (hasPendingCameraPermissionRequest()) {
1091
+ rejectBusyCallback(callbackContext, "CAMERA permission");
1092
+ return;
1093
+ }
1066
1094
 
1067
1095
  cameraPermissionCallback = callbackContext;
1068
1096
  rememberRuntimePermissionRequest(Manifest.permission.CAMERA);
@@ -1081,6 +1109,10 @@ public class Html2ApkBridge extends CordovaPlugin {
1081
1109
  callbackContext.success(result);
1082
1110
  return;
1083
1111
  }
1112
+ if (hasPendingMicrophonePermissionRequest()) {
1113
+ rejectBusyCallback(callbackContext, "RECORD_AUDIO permission");
1114
+ return;
1115
+ }
1084
1116
 
1085
1117
  microphonePermissionCallback = callbackContext;
1086
1118
  rememberRuntimePermissionRequest(Manifest.permission.RECORD_AUDIO);
@@ -1116,6 +1148,10 @@ public class Html2ApkBridge extends CordovaPlugin {
1116
1148
  }
1117
1149
 
1118
1150
  if (!hasMicrophonePermission()) {
1151
+ if (hasPendingMicrophonePermissionRequest()) {
1152
+ rejectBusyCallback(callbackContext, "RECORD_AUDIO permission");
1153
+ return;
1154
+ }
1119
1155
  pendingMicStartCallback = callbackContext;
1120
1156
  rememberRuntimePermissionRequest(Manifest.permission.RECORD_AUDIO);
1121
1157
  cordova.requestPermission(this, REQUEST_RECORD_AUDIO, Manifest.permission.RECORD_AUDIO);
@@ -1299,6 +1335,10 @@ public class Html2ApkBridge extends CordovaPlugin {
1299
1335
 
1300
1336
  private void setFlashlightWithPermission(boolean enabled, boolean toggle, CallbackContext callbackContext) throws Exception {
1301
1337
  if (!hasCameraPermission()) {
1338
+ if (hasPendingCameraPermissionRequest()) {
1339
+ rejectBusyCallback(callbackContext, "CAMERA permission");
1340
+ return;
1341
+ }
1302
1342
  pendingFlashlightCallback = callbackContext;
1303
1343
  pendingFlashlightEnabled = enabled;
1304
1344
  pendingFlashlightToggle = toggle;
@@ -1397,6 +1437,11 @@ public class Html2ApkBridge extends CordovaPlugin {
1397
1437
  }
1398
1438
 
1399
1439
  private void pickFile(JSONObject options, CallbackContext callbackContext) {
1440
+ if (filePickerCallback != null) {
1441
+ rejectBusyCallback(callbackContext, "File picker");
1442
+ return;
1443
+ }
1444
+
1400
1445
  JSONObject safeOptions = options == null ? new JSONObject() : options;
1401
1446
  String kind = safeOptions.optString("tipo", safeOptions.optString("kind", "file"));
1402
1447
  boolean multiple = safeOptions.optBoolean("multiplo", safeOptions.optBoolean("multiple", false));
@@ -1438,12 +1483,22 @@ public class Html2ApkBridge extends CordovaPlugin {
1438
1483
  }
1439
1484
 
1440
1485
  private void pickFolder(CallbackContext callbackContext) {
1486
+ if (folderPickerCallback != null) {
1487
+ rejectBusyCallback(callbackContext, "Folder picker");
1488
+ return;
1489
+ }
1490
+
1441
1491
  Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
1442
1492
  folderPickerCallback = callbackContext;
1443
1493
  cordova.startActivityForResult(this, intent, REQUEST_PICK_FOLDER);
1444
1494
  }
1445
1495
 
1446
1496
  private void saveFile(JSONObject options, CallbackContext callbackContext) throws Exception {
1497
+ if (saveFileCallback != null) {
1498
+ rejectBusyCallback(callbackContext, "File save dialog");
1499
+ return;
1500
+ }
1501
+
1447
1502
  JSONObject safeOptions = options == null ? new JSONObject() : options;
1448
1503
  String name = safeOptions.optString("nome", safeOptions.optString("name", "arquivo.txt"));
1449
1504
  String mimeType = safeOptions.optString("mimeType", "text/plain");