@saltcorn/mobile-app 1.1.0-beta.20 → 1.1.0-beta.22

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.
@@ -4,22 +4,35 @@ const { readFileSync, writeFileSync } = require("fs");
4
4
  console.log("Writing gradle config");
5
5
  console.log("args", process.argv);
6
6
 
7
+ const hasKeyStoreFile = process.argv.some((arg) =>
8
+ arg.includes("keyStoreFile")
9
+ );
7
10
  const args = process.argv.slice(2);
8
- const keyStoreFile = args[0].split("=")[1];
9
- const keyStoreAlias = args[1].split("=")[1];
10
- const keyStorePassword = args[2].split("=")[1];
11
+ const appVersion = args[0].split("=")[1];
12
+ const keyStoreFile = hasKeyStoreFile ? args[1].split("=")[1] : null;
13
+ const keyStoreAlias = hasKeyStoreFile ? args[2].split("=")[1] : null;
14
+ const keyStorePassword = hasKeyStoreFile ? args[3].split("=")[1] : null;
11
15
 
12
16
  const gradleFile = join(__dirname, "..", "android", "app", "build.gradle");
13
17
  const gradleContent = readFileSync(gradleFile, "utf8");
14
- const newGradleContent = gradleContent
15
- .replace(
16
- /release\s*{/,
17
- `release {
18
+
19
+ // generate versionCode from appVersion
20
+ const parts = appVersion.split(".");
21
+ const versionCode =
22
+ parseInt(parts[0]) * 1000000 + parseInt(parts[1]) * 1000 + parseInt(parts[2]);
23
+ let newGradleContent = gradleContent
24
+ .replace(/versionName "1.0"/, `versionName "${appVersion}"`)
25
+ .replace(/versionCode 1/, `versionCode ${versionCode}`);
26
+ if (hasKeyStoreFile) {
27
+ newGradleContent = gradleContent
28
+ .replace(
29
+ /release\s*{/,
30
+ `release {
18
31
  signingConfig signingConfigs.release`
19
- )
20
- .replace(
21
- /buildTypes\s*{/,
22
- `
32
+ )
33
+ .replace(
34
+ /buildTypes\s*{/,
35
+ `
23
36
  signingConfigs {
24
37
  release {
25
38
  keyAlias '${keyStoreAlias}'
@@ -29,6 +42,7 @@ const newGradleContent = gradleContent
29
42
  }
30
43
  }
31
44
  buildTypes {`
32
- );
45
+ );
46
+ }
33
47
  console.log("newGradleContent", newGradleContent);
34
48
  writeFileSync(gradleFile, newGradleContent, "utf8");
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.1.0-beta.20",
4
+ "version": "1.1.0-beta.22",
5
5
  "description": "Apache Cordova application with @saltcorn/markup",
6
6
  "main": "index.js",
7
7
  "scripts": {
@@ -3,6 +3,9 @@
3
3
  import { apiCall } from "./api";
4
4
  import { Camera, CameraResultType } from "@capacitor/camera";
5
5
  import { Geolocation } from "@capacitor/geolocation";
6
+ import { ScreenOrientation } from "@capacitor/screen-orientation";
7
+
8
+ const orientationChangeListeners = new Set();
6
9
 
7
10
  export function clearAlerts() {
8
11
  const iframe = document.getElementById("content-iframe");
@@ -173,3 +176,14 @@ export async function getGeolocation(successCb, errorCb) {
173
176
  return null;
174
177
  }
175
178
  }
179
+
180
+ export function registerScreenOrientationListener(name, listener) {
181
+ if (!orientationChangeListeners.has(name)) {
182
+ orientationChangeListeners.add(name, listener);
183
+ ScreenOrientation.addListener("screenOrientationChange", listener);
184
+ } else console.warn(`Listener with name ${name} already registered.`);
185
+ }
186
+
187
+ export async function getScreenOrientation() {
188
+ return await ScreenOrientation.orientation();
189
+ }
@@ -43,6 +43,23 @@ export function addQueryParam(key, value) {
43
43
  }
44
44
  }
45
45
 
46
+ export function setAnchor(anchor) {
47
+ if (routingHistory.length === 0)
48
+ throw new Error("No current route to set anchor");
49
+ else {
50
+ const current = routingHistory[routingHistory.length - 1];
51
+ current.anchor = anchor;
52
+ }
53
+ }
54
+
55
+ export function getAnchor() {
56
+ if (routingHistory.length === 0) return undefined;
57
+ else {
58
+ const current = routingHistory[routingHistory.length - 1];
59
+ return current.anchor;
60
+ }
61
+ }
62
+
46
63
  export function addRoute(routeEntry) {
47
64
  routingHistory.push(routeEntry);
48
65
  }
@@ -2,5 +2,5 @@ import { MobileRequest } from "../mocks/request";
2
2
  import { wrapContents } from "../utils";
3
3
 
4
4
  export const getErrorView = async (context) => {
5
- return wrapContents("", "Error", context, new MobileRequest());
5
+ return await wrapContents("", "Error", context, new MobileRequest());
6
6
  };
@@ -108,6 +108,6 @@ export const getPage = async (context) => {
108
108
  return { content, title: "title", replaceIframe: true, isFile: true };
109
109
  } else {
110
110
  const title = "title"; // TODO
111
- return wrapContents(contents, title, context, req);
111
+ return await wrapContents(contents, title, context, req);
112
112
  }
113
113
  };
@@ -4,7 +4,7 @@ import { MobileRequest } from "../mocks/request";
4
4
  import { wrapContents } from "../utils";
5
5
 
6
6
  // get/sync/sync_settings
7
- export const getSyncSettingsView = (context) => {
7
+ export const getSyncSettingsView = async (context) => {
8
8
  const state = saltcorn.data.state.getState();
9
9
  const { isOfflineMode } = state.mobileConfig;
10
10
  const content = saltcorn.markup.div(
@@ -98,11 +98,16 @@ export const getSyncSettingsView = (context) => {
98
98
  ),
99
99
  saltcorn.markup.hr()
100
100
  );
101
- return wrapContents(content, "Sync Settings", context, new MobileRequest());
101
+ return await wrapContents(
102
+ content,
103
+ "Sync Settings",
104
+ context,
105
+ new MobileRequest()
106
+ );
102
107
  };
103
108
 
104
109
  // get/sync/ask_upload_not_ended
105
- export const getAskUploadNotEnded = (context) => {
110
+ export const getAskUploadNotEnded = async (context) => {
106
111
  const content = saltcorn.markup.div(
107
112
  saltcorn.markup.div(
108
113
  { class: "mb-3 h6" },
@@ -126,11 +131,11 @@ export const getAskUploadNotEnded = (context) => {
126
131
  "Upload anyway"
127
132
  )
128
133
  );
129
- return wrapContents(content, "Warning", context, new MobileRequest());
134
+ return await wrapContents(content, "Warning", context, new MobileRequest());
130
135
  };
131
136
 
132
137
  // get/sync/ask_delete_offline_data
133
- export const getAskDeleteOfflineData = (context) => {
138
+ export const getAskDeleteOfflineData = async (context) => {
134
139
  const content = saltcorn.markup.div(
135
140
  saltcorn.markup.div(
136
141
  { class: "mb-3 h6" },
@@ -154,5 +159,5 @@ export const getAskDeleteOfflineData = (context) => {
154
159
  "Delete"
155
160
  )
156
161
  );
157
- return wrapContents(content, "Warning", context, new MobileRequest());
162
+ return await wrapContents(content, "Warning", context, new MobileRequest());
158
163
  };
@@ -53,7 +53,7 @@ export const postView = async (context) => {
53
53
  if (mobileCfg.isOfflineMode) await setHasOfflineData(true);
54
54
  const wrapped = res.getWrapHtml();
55
55
  if (wrapped) {
56
- return wrapContents(
56
+ return await wrapContents(
57
57
  wrapped,
58
58
  res.getWrapViewName() || "viewname",
59
59
  context,
@@ -100,7 +100,7 @@ export const postViewRoute = async (context) => {
100
100
  if (isOfflineMode) await setHasOfflineData(true);
101
101
  const wrapped = res.getWrapHtml();
102
102
  if (wrapped)
103
- return wrapContents(
103
+ return await wrapContents(
104
104
  wrapped,
105
105
  res.getWrapViewName() || "viewname",
106
106
  context,
@@ -156,7 +156,7 @@ export const getView = async (context) => {
156
156
  }
157
157
  const wrapped = res.getWrapHtml();
158
158
  if (wrapped)
159
- return wrapContents(
159
+ return await wrapContents(
160
160
  wrapped,
161
161
  res.getWrapViewName() || "viewname",
162
162
  context,
@@ -181,6 +181,6 @@ export const getView = async (context) => {
181
181
  )
182
182
  : contents0;
183
183
 
184
- return wrapContents(contents, viewname, context, req);
184
+ return await wrapContents(contents, viewname, context, req);
185
185
  }
186
186
  };
@@ -1,6 +1,7 @@
1
1
  /*global saltcorn */
2
2
 
3
3
  import { getOfflineMsg } from "../helpers/offline_mode";
4
+ import { getScreenOrientation } from "../helpers/common";
4
5
 
5
6
  export const getHeaders = () => {
6
7
  const state = saltcorn.data.state.getState();
@@ -131,7 +132,8 @@ const prepareAlerts = (context, req) => {
131
132
  return [...(context.alerts || []), ...req.flashMessages()];
132
133
  };
133
134
 
134
- export const wrapContents = (contents, title, context, req) => {
135
+ export const wrapContents = async (contents, title, context, req) => {
136
+ const orientation = await getScreenOrientation();
135
137
  const state = saltcorn.data.state.getState();
136
138
  const body = {
137
139
  above: [
@@ -159,6 +161,7 @@ export const wrapContents = (contents, title, context, req) => {
159
161
  },
160
162
  bodyClass: "",
161
163
  currentUrl: "",
164
+ orientation: orientation?.type,
162
165
  })
163
166
  : layout().renderBody({
164
167
  title: title,
@@ -28,7 +28,10 @@ async function execLink(url, linkSrc) {
28
28
  try {
29
29
  if (document.getElementById("scspinner")) return;
30
30
  showLoadSpinner();
31
- if (url.startsWith("javascript:")) eval(url.substring(11));
31
+ if (url.startsWith("#")) {
32
+ const anchor = url.substring(1);
33
+ parent.saltcorn.mobileApp.navigation.setAnchor(anchor);
34
+ } else if (url.startsWith("javascript:")) eval(url.substring(11));
32
35
  else {
33
36
  const { path, query } =
34
37
  parent.saltcorn.mobileApp.navigation.splitPathQuery(url);
@@ -40,6 +43,8 @@ async function execLink(url, linkSrc) {
40
43
  query
41
44
  );
42
45
  }
46
+ } catch (error) {
47
+ parent.saltcorn.mobileApp.common.errorAlert(error);
43
48
  } finally {
44
49
  removeLoadSpinner();
45
50
  }