html2apk 0.2.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.
@@ -71,6 +71,15 @@ function normalizeMinSdkVersion(value) {
71
71
  : DEFAULT_ANDROID_MIN_SDK_VERSION;
72
72
  }
73
73
 
74
+ function normalizeThemeMode(value) {
75
+ return String(value || "").trim().toLowerCase() === "auto" ? "auto" : "fixed";
76
+ }
77
+
78
+ function normalizeThemeColor(value) {
79
+ const color = String(value || "").trim();
80
+ return /^#[0-9a-fA-F]{6}$/.test(color) ? color : "#126fff";
81
+ }
82
+
74
83
  function normalizeOptions(options) {
75
84
  const normalized = { ...options };
76
85
 
@@ -85,6 +94,13 @@ function normalizeOptions(options) {
85
94
  : "default";
86
95
  normalized.debug = Boolean(normalized.debug);
87
96
  normalized.release = Boolean(normalized.release);
97
+ const themeColorText = String(normalized.themeColor || "").trim().toLowerCase();
98
+ const themeModeText = String(normalized.themeMode || "").trim().toLowerCase();
99
+ const themeText = String(normalized.theme || "").trim().toLowerCase();
100
+ normalized.themeMode = themeModeText === "auto" || themeText === "auto" || themeColorText === "auto" ? "auto" : "fixed";
101
+ normalized.theme = normalized.themeMode;
102
+ normalized.themeColor = normalizeThemeColor(themeColorText === "auto" ? normalized.backgroundColor : normalized.themeColor);
103
+ normalized.oneSignalAppId = normalizeOneSignalAppId(normalized.oneSignalAppId || normalized.onesignalAppId || normalized.oneSignal?.appId || normalized.onesignal?.appId);
88
104
  normalized.minSdkVersion = normalizeMinSdkVersion(normalized.minSdkVersion || normalized.androidMinSdkVersion);
89
105
  normalized.permissions = Array.isArray(normalized.permissions)
90
106
  ? normalized.permissions.map((permission) => String(permission).trim()).filter(Boolean)
@@ -92,12 +108,39 @@ function normalizeOptions(options) {
92
108
  normalized.plugins = Array.isArray(normalized.plugins)
93
109
  ? normalized.plugins.map((plugin) => String(plugin).trim()).filter(Boolean)
94
110
  : [];
111
+ normalized.deepLinks = normalizeDeepLinks(normalized.deepLinks);
95
112
  normalized.entryFile = normalized.entryFile || "index.html";
96
113
  normalized.webRoot = normalized.webRoot || ".";
97
114
 
98
115
  return normalized;
99
116
  }
100
117
 
118
+ function normalizeOneSignalAppId(value) {
119
+ return String(value || "").trim();
120
+ }
121
+
122
+ function normalizeDeepLinks(value) {
123
+ const input = value && typeof value === "object" ? value : {};
124
+ const schemes = Array.isArray(input.schemes)
125
+ ? input.schemes.map((scheme) => String(scheme).trim()).filter(Boolean)
126
+ : [];
127
+ const appLinks = Array.isArray(input.appLinks)
128
+ ? input.appLinks
129
+ .filter((item) => item && typeof item === "object" && item.host)
130
+ .map((item) => ({
131
+ scheme: item.scheme || "https",
132
+ host: String(item.host).trim(),
133
+ paths: Array.isArray(item.paths) ? item.paths.map((pathItem) => String(pathItem).trim()).filter(Boolean) : [],
134
+ autoVerify: Boolean(item.autoVerify)
135
+ }))
136
+ : [];
137
+
138
+ return {
139
+ schemes,
140
+ appLinks
141
+ };
142
+ }
143
+
101
144
  async function resolveBuildOptions(overrides = {}) {
102
145
  const projectRoot = path.resolve(overrides.projectRoot || process.cwd());
103
146
  const { config, configPath } = await loadProjectConfig(projectRoot);
@@ -118,5 +161,8 @@ module.exports = {
118
161
  resolveBuildOptions,
119
162
  mergeDeep,
120
163
  normalizeOptions,
121
- normalizeMinSdkVersion
164
+ normalizeMinSdkVersion,
165
+ normalizeThemeMode,
166
+ normalizeOneSignalAppId,
167
+ normalizeDeepLinks
122
168
  };
@@ -31,6 +31,12 @@ function createDefaultOptions(projectRoot) {
31
31
  androidPlatform: "android@15.0.0",
32
32
  minSdkVersion: DEFAULT_ANDROID_MIN_SDK_VERSION,
33
33
  themeColor: "#126fff",
34
+ themeMode: "fixed",
35
+ oneSignalAppId: "",
36
+ deepLinks: {
37
+ schemes: [],
38
+ appLinks: []
39
+ },
34
40
  files: null,
35
41
  entryFile: "index.html",
36
42
  webRoot: ".",
@@ -22,6 +22,7 @@ const WINDOW_BACKGROUNDS = {
22
22
  };
23
23
 
24
24
  app.commandLine.appendSwitch("disable-crash-reporter");
25
+ process.title = APP_NAME;
25
26
  app.setName(APP_NAME);
26
27
 
27
28
  if (process.platform === "win32") {
@@ -141,7 +142,7 @@ function cleanBuildOptions(options = {}) {
141
142
  release: Boolean(options.release)
142
143
  };
143
144
 
144
- for (const key of ["mode", "appName", "packageId", "version", "icon", "androidPlatform", "minSdkVersion", "themeColor", "orientation", "permissions"]) {
145
+ for (const key of ["mode", "appName", "packageId", "version", "icon", "androidPlatform", "minSdkVersion", "themeColor", "themeMode", "theme", "oneSignalAppId", "orientation", "permissions", "deepLinks"]) {
145
146
  if (Array.isArray(options[key]) || options[key]) {
146
147
  output[key] = options[key];
147
148
  }
@@ -350,6 +351,10 @@ async function installWithWingetAndroidCli(sender) {
350
351
  }
351
352
 
352
353
  app.whenReady().then(() => {
354
+ app.setName(APP_NAME);
355
+ if (process.platform === "win32") {
356
+ app.setAppUserModelId(APP_ID);
357
+ }
353
358
  createWindow();
354
359
 
355
360
  app.on("activate", () => {
@@ -527,3 +532,17 @@ ipcMain.handle("shell:show-item", async (_event, targetPath) => {
527
532
  shell.showItemInFolder(targetPath);
528
533
  return true;
529
534
  });
535
+
536
+ ipcMain.handle("shell:open-external", async (_event, targetUrl) => {
537
+ if (!targetUrl) {
538
+ return false;
539
+ }
540
+
541
+ const url = new URL(String(targetUrl));
542
+ if (!["https:", "http:"].includes(url.protocol)) {
543
+ return false;
544
+ }
545
+
546
+ await shell.openExternal(url.toString());
547
+ return true;
548
+ });
@@ -12,6 +12,7 @@ contextBridge.exposeInMainWorld("html2apkDesktop", {
12
12
  runBuild: (options) => ipcRenderer.invoke("build:run", options),
13
13
  openPath: (targetPath) => ipcRenderer.invoke("shell:open-path", targetPath),
14
14
  showItem: (targetPath) => ipcRenderer.invoke("shell:show-item", targetPath),
15
+ openExternalUrl: (targetUrl) => ipcRenderer.invoke("shell:open-external", targetUrl),
15
16
  minimizeWindow: () => ipcRenderer.invoke("window:minimize"),
16
17
  toggleMaximizeWindow: () => ipcRenderer.invoke("window:toggle-maximize"),
17
18
  closeWindow: () => ipcRenderer.invoke("window:close"),
@@ -176,6 +176,13 @@
176
176
  <span>cordova-android</span>
177
177
  <input id="androidPlatformInput" type="text" placeholder="android@15.0.0">
178
178
  </label>
179
+ <label class="field">
180
+ <span data-i18n="themeMode">Tema do APK</span>
181
+ <select id="themeModeInput">
182
+ <option value="fixed" data-i18n="themeModeFixed">Cor fixa</option>
183
+ <option value="auto" data-i18n="themeModeAuto">Automatico pela tela</option>
184
+ </select>
185
+ </label>
179
186
  <label class="field color-field">
180
187
  <span data-i18n="appThemeColor">Cor do tema do app</span>
181
188
  <div class="color-picker">
@@ -183,6 +190,11 @@
183
190
  <input id="themeColorTextInput" type="text" value="#126fff" maxlength="7">
184
191
  </div>
185
192
  </label>
193
+ <label class="field onesignal-field">
194
+ <span data-i18n="oneSignalAppId">OneSignal App ID</span>
195
+ <input id="oneSignalAppIdInput" type="text" placeholder="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">
196
+ <small data-i18n="oneSignalAppIdHint">Opcional. Use o App ID do OneSignal, nao a REST API Key.</small>
197
+ </label>
186
198
  <div class="field icon-field">
187
199
  <span data-i18n="appIcon">Icone do app</span>
188
200
  <div class="icon-picker">
@@ -345,6 +357,11 @@
345
357
  <strong data-i18n="helpDepsTitle">Dependencias no EXE</strong>
346
358
  <p data-i18n="helpDeps">O executavel empacota html2apk, a interface e dependencias Node/Cordova. JDK e Android SDK ainda precisam existir na maquina por tamanho e licenca.</p>
347
359
  </article>
360
+ <article class="creator-card">
361
+ <strong data-i18n="helpCreatorTitle">Criador</strong>
362
+ <p data-i18n="helpCreatorText">Conheca o Dev Caio Multiversando, criador desta linda aplicacao html2apk.</p>
363
+ <button id="devInstagramButton" class="secondary-action instagram-action" type="button" data-i18n="openInstagram">Conhecer o dev</button>
364
+ </article>
348
365
  </div>
349
366
  </section>
350
367
  </main>