@saltcorn/mobile-app 1.6.0-alpha.0 → 1.6.0-alpha.10
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/add_entitlements.rb +16 -0
- package/optional_sources/notifications.js +4 -2
- package/package.json +11 -3
- package/src/helpers/navigation.js +24 -2
- package/src/init.js +18 -11
- package/src/routing/utils.js +1 -0
- package/webpack.config.js +3 -1
- package/www/index.html +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'xcodeproj'
|
|
2
|
+
|
|
3
|
+
project_path = 'ios/App/App.xcodeproj'
|
|
4
|
+
target_name = 'App'
|
|
5
|
+
entitlements_relative_path = 'App/App.entitlements'
|
|
6
|
+
|
|
7
|
+
project = Xcodeproj::Project.open(project_path)
|
|
8
|
+
target = project.targets.find { |t| t.name == target_name }
|
|
9
|
+
abort("Target '#{target_name}' not found") unless target
|
|
10
|
+
|
|
11
|
+
target.build_configurations.each do |config|
|
|
12
|
+
config.build_settings['CODE_SIGN_ENTITLEMENTS'] = entitlements_relative_path
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
project.save
|
|
16
|
+
puts "Entitlements configured successfully for target '#{target_name}'"
|
|
@@ -12,11 +12,12 @@ import { Device } from "@capacitor/device";
|
|
|
12
12
|
async function notifyTokenApi(config, isSubscribe) {
|
|
13
13
|
console.log("notifyTokenApi subscribe:", isSubscribe);
|
|
14
14
|
const { token, deviceId } = config.pushConfiguration;
|
|
15
|
+
const platform = Capacitor.getPlatform();
|
|
15
16
|
try {
|
|
16
17
|
const response = await apiCall({
|
|
17
18
|
method: "POST",
|
|
18
19
|
path: `/notifications/mobile-${isSubscribe ? "subscribe" : "remove-subscription"}`,
|
|
19
|
-
body: { token, deviceId },
|
|
20
|
+
body: { token, deviceId, platform },
|
|
20
21
|
});
|
|
21
22
|
const data = response.data;
|
|
22
23
|
if (data.success === "ok")
|
|
@@ -45,11 +46,12 @@ async function notifyTokenApi(config, isSubscribe) {
|
|
|
45
46
|
async function syncTokenApi(config, isSubscribe) {
|
|
46
47
|
console.log("syncTokenApi subscribe:", isSubscribe);
|
|
47
48
|
const { token, deviceId } = config.pushConfiguration;
|
|
49
|
+
const platform = Capacitor.getPlatform();
|
|
48
50
|
try {
|
|
49
51
|
const response = await apiCall({
|
|
50
52
|
method: "POST",
|
|
51
53
|
path: `/sync/push_${isSubscribe ? "subscribe" : "unsubscribe"}`,
|
|
52
|
-
body: { token, deviceId, synchedTables: config.synchedTables },
|
|
54
|
+
body: { token, deviceId, synchedTables: config.synchedTables, platform },
|
|
53
55
|
});
|
|
54
56
|
const data = response.data;
|
|
55
57
|
if (data.success === "ok")
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saltcorn/mobile-app",
|
|
3
3
|
"displayName": "Saltcorn mobile app",
|
|
4
|
-
"version": "1.6.0-alpha.
|
|
4
|
+
"version": "1.6.0-alpha.10",
|
|
5
5
|
"description": "Saltcorn mobile app for Android and iOS",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
@@ -22,7 +22,11 @@
|
|
|
22
22
|
"i18next-sprintf-postprocessor": "0.2.2",
|
|
23
23
|
"crypto-browserify": "3.12.1",
|
|
24
24
|
"vm-browserify": "1.1.2",
|
|
25
|
-
"
|
|
25
|
+
"string_decoder": "1.3.0",
|
|
26
|
+
"buffer": "6.0.3",
|
|
27
|
+
"events": "3.3.0",
|
|
28
|
+
"stream-browserify": "3.0.0",
|
|
29
|
+
"jeep-sqlite": "^2.8.0"
|
|
26
30
|
},
|
|
27
31
|
"devDependencies": {
|
|
28
32
|
"xml2js": "0.6.2",
|
|
@@ -30,6 +34,10 @@
|
|
|
30
34
|
"@babel/preset-env": "^7.26.7",
|
|
31
35
|
"babel-loader": "^9.2.1",
|
|
32
36
|
"webpack": "5.97.1",
|
|
33
|
-
"webpack-cli": "6.0.1"
|
|
37
|
+
"webpack-cli": "6.0.1",
|
|
38
|
+
"typescript": "5.9.2",
|
|
39
|
+
"kleur": "4.1.5",
|
|
40
|
+
"@ionic/cli-framework-output": "2.2.8",
|
|
41
|
+
"@ionic/utils-terminal": "2.3.5"
|
|
34
42
|
}
|
|
35
43
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*global saltcorn*/
|
|
1
|
+
/*global saltcorn, Capacitor*/
|
|
2
2
|
import i18next from "i18next";
|
|
3
3
|
|
|
4
4
|
import { router } from "../routing/index";
|
|
@@ -80,7 +80,11 @@ export async function goBack(steps = 1, exitOnFirstPage = false) {
|
|
|
80
80
|
routingHistory.length === 0 ||
|
|
81
81
|
(exitOnFirstPage && routingHistory.length === 1)
|
|
82
82
|
) {
|
|
83
|
-
|
|
83
|
+
if (Capacitor.getPlatform() === "android") {
|
|
84
|
+
navigator.app.exitApp();
|
|
85
|
+
} else if (Capacitor.getPlatform() === "ios") {
|
|
86
|
+
console.log("iOS app exit not supported");
|
|
87
|
+
}
|
|
84
88
|
} else if (routingHistory.length <= steps) {
|
|
85
89
|
try {
|
|
86
90
|
if (iframe?.contentWindow?.showLoadSpinner)
|
|
@@ -262,9 +266,27 @@ export async function gotoEntryView() {
|
|
|
262
266
|
}
|
|
263
267
|
}
|
|
264
268
|
|
|
269
|
+
const iosSwipeBackHandler = () => {
|
|
270
|
+
const iframe = document.getElementById("content-iframe");
|
|
271
|
+
let touchStartX = 0;
|
|
272
|
+
const doc = iframe.contentDocument || iframe.contentWindow.document;
|
|
273
|
+
doc.addEventListener("pointerdown", (e) => {
|
|
274
|
+
touchStartX = e.clientX;
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
doc.addEventListener("pointerup", (e) => {
|
|
278
|
+
const deltaX = e.clientX - touchStartX;
|
|
279
|
+
if (touchStartX < 20 && deltaX > 100) {
|
|
280
|
+
saltcorn.mobileApp.navigation.goBack(1, true);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
|
|
265
285
|
export async function replaceIframe(content, isFile = false) {
|
|
266
286
|
const iframe = document.getElementById("content-iframe");
|
|
267
287
|
iframe.srcdoc = content;
|
|
288
|
+
if (Capacitor.getPlatform() === "ios")
|
|
289
|
+
iframe.addEventListener("load", iosSwipeBackHandler);
|
|
268
290
|
if (isFile) {
|
|
269
291
|
iframe.setAttribute("is-html-file", true);
|
|
270
292
|
await new Promise((resolve, reject) => {
|
package/src/init.js
CHANGED
|
@@ -211,14 +211,10 @@ const showErrorPage = async (error) => {
|
|
|
211
211
|
const onResume = async () => {
|
|
212
212
|
if (typeof saltcorn === "undefined") return;
|
|
213
213
|
const mobileConfig = saltcorn.data.state.getState().mobileConfig;
|
|
214
|
-
if (mobileConfig?.allowOfflineMode) {
|
|
214
|
+
if (mobileConfig?.allowOfflineMode && mobileConfig.jwt) {
|
|
215
215
|
const netStatus = await Network.getStatus();
|
|
216
216
|
mobileConfig.networkState = netStatus.connectionType;
|
|
217
|
-
if (
|
|
218
|
-
mobileConfig.networkState === "none" &&
|
|
219
|
-
!mobileConfig.isOfflineMode &&
|
|
220
|
-
mobileConfig.jwt
|
|
221
|
-
) {
|
|
217
|
+
if (mobileConfig.networkState === "none" && !mobileConfig.isOfflineMode) {
|
|
222
218
|
try {
|
|
223
219
|
await startOfflineMode();
|
|
224
220
|
clearHistory();
|
|
@@ -226,6 +222,15 @@ const onResume = async () => {
|
|
|
226
222
|
} catch (error) {
|
|
227
223
|
await showErrorPage(error);
|
|
228
224
|
}
|
|
225
|
+
} else if (
|
|
226
|
+
mobileConfig.networkState !== "none" &&
|
|
227
|
+
mobileConfig.syncOnAppResume
|
|
228
|
+
) {
|
|
229
|
+
try {
|
|
230
|
+
await sync(false, false, []);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
await showErrorPage(error);
|
|
233
|
+
}
|
|
229
234
|
}
|
|
230
235
|
}
|
|
231
236
|
};
|
|
@@ -362,17 +367,19 @@ const getEntryPoint = (roleId, state, mobileConfig) => {
|
|
|
362
367
|
// device is ready
|
|
363
368
|
export async function init(mobileConfig) {
|
|
364
369
|
try {
|
|
365
|
-
|
|
370
|
+
const platform = Capacitor.getPlatform();
|
|
371
|
+
if (platform === "web") {
|
|
366
372
|
defineCustomElements(window);
|
|
367
373
|
await customElements.whenDefined("jeep-sqlite");
|
|
368
374
|
const jeepSqlite = document.createElement("jeep-sqlite");
|
|
369
375
|
document.body.appendChild(jeepSqlite);
|
|
370
376
|
await jeepSqlite.componentOnReady();
|
|
377
|
+
} else if (platform === "android") {
|
|
378
|
+
App.addListener("backButton", async ({ canGoBack }) => {
|
|
379
|
+
await saltcorn.mobileApp.navigation.goBack(1, true);
|
|
380
|
+
});
|
|
371
381
|
}
|
|
372
|
-
|
|
373
|
-
App.addListener("backButton", async ({ canGoBack }) => {
|
|
374
|
-
await saltcorn.mobileApp.navigation.goBack(1, true);
|
|
375
|
-
});
|
|
382
|
+
// see navigation.js for ios
|
|
376
383
|
|
|
377
384
|
App.addListener("appUrlOpen", async (event) => {
|
|
378
385
|
try {
|
package/src/routing/utils.js
CHANGED
|
@@ -9,6 +9,7 @@ export const getHeaders = () => {
|
|
|
9
9
|
const versionTag = config.version_tag;
|
|
10
10
|
const stdHeaders = [
|
|
11
11
|
{ css: `static_assets/${versionTag}/saltcorn.css` },
|
|
12
|
+
{ css: `static_assets/${versionTag}/saltcorn-mobile.css` },
|
|
12
13
|
{ script: `static_assets/${versionTag}/saltcorn-common.js` },
|
|
13
14
|
{ script: `static_assets/${versionTag}/dayjs.min.js` },
|
|
14
15
|
{ script: `static_assets/${versionTag}/socket.io.min.js` },
|
package/webpack.config.js
CHANGED
|
@@ -42,7 +42,9 @@ module.exports = {
|
|
|
42
42
|
"crypto": require.resolve("crypto-browserify"),
|
|
43
43
|
vm: require.resolve("vm-browserify"),
|
|
44
44
|
stream: require.resolve("stream-browserify"),
|
|
45
|
-
|
|
45
|
+
string_decoder: require.resolve("string_decoder/"),
|
|
46
|
+
buffer: require.resolve("buffer/"),
|
|
47
|
+
events: require.resolve("events/"),
|
|
46
48
|
}
|
|
47
49
|
},
|
|
48
50
|
target: "web", // Use web target for browser compatibility
|
package/www/index.html
CHANGED