diff --git a/config.xml b/config.xml
index 18100a284..499ee606f 100644
--- a/config.xml
+++ b/config.xml
@@ -1,5 +1,8 @@
-
+
Network Canvas Interviewer
A tool for conducting Network Canvas Interviews.
@@ -16,6 +19,7 @@
+
@@ -81,4 +85,4 @@
-
\ No newline at end of file
+
diff --git a/package-lock.json b/package-lock.json
index cbc91f9ba..72bd56ae4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,14 +1,15 @@
{
"name": "network-canvas-interviewer",
- "version": "6.5.1",
+ "version": "6.5.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "network-canvas-interviewer",
- "version": "6.5.1",
+ "version": "6.5.2",
"dependencies": {
"@babel/runtime": "7.10.1",
+ "@xmldom/xmldom": "~0.8.10",
"archiver": "^4.0.1",
"d3-force": "~3.0.0",
"dmg-builder": "~23.6.0",
@@ -51,8 +52,8 @@
"connected-react-router": "^6.8.0",
"cordova-android": "~12.0.0",
"cordova-ios": "~7.0.0",
- "cordova-plugin-file": "github:apache/cordova-plugin-file",
- "cordova-plugin-file-transfer": "github:apache/cordova-plugin-file-transfer",
+ "cordova-plugin-file": "github:apache/cordova-plugin-file#265a932",
+ "cordova-plugin-file-transfer": "github:apache/cordova-plugin-file-transfer#f12b73e",
"cordova-plugin-fullscreen": "github:mesmotronic/cordova-plugin-fullscreen",
"cordova-plugin-ionic-keyboard": "github:ionic-team/cordova-plugin-ionic-keyboard",
"cordova-plugin-network-canvas-client": "github:complexdatacollective/cordova-plugin-network-canvas-client",
@@ -149,7 +150,6 @@
"whatwg-fetch": "2.0.3",
"worker-loader": "^2.0.0",
"xml2js": "~0.4.23",
- "xmldom": "~0.1.27",
"xss": "^0.3.4"
},
"engines": {
@@ -157,11 +157,6 @@
"npm": "8.19.4"
}
},
- "../cordova-plugin-network-canvas-client": {
- "version": "0.0.2",
- "extraneous": true,
- "license": "GPL-3.0-or-later"
- },
"node_modules/@ampproject/remapping": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz",
@@ -6034,6 +6029,14 @@
"@xtuc/long": "4.2.2"
}
},
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.8.10",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+ "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@@ -9928,8 +9931,8 @@
}
},
"node_modules/cordova-plugin-file": {
- "version": "8.0.1-dev",
- "resolved": "git+ssh://git@github.com/apache/cordova-plugin-file.git#faba1bf0f1479cafe5ed256bc0181fe10768527f",
+ "version": "8.0.2-dev",
+ "resolved": "git+ssh://git@github.com/apache/cordova-plugin-file.git#265a932f3b5d11739fd08c0437477f441f6212c7",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -9950,8 +9953,8 @@
}
},
"node_modules/cordova-plugin-file-transfer": {
- "version": "2.0.0-dev",
- "resolved": "git+ssh://git@github.com/apache/cordova-plugin-file-transfer.git#06335fea28f7ad4d815aa621e02823a63b0a9bc6",
+ "version": "2.0.1-dev",
+ "resolved": "git+ssh://git@github.com/apache/cordova-plugin-file-transfer.git#f12b73eb0ba70536072eeab89843c96082fce512",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -9985,7 +9988,7 @@
},
"node_modules/cordova-plugin-network-canvas-client": {
"version": "0.0.2",
- "resolved": "git+ssh://git@github.com/complexdatacollective/cordova-plugin-network-canvas-client.git#4bf75df4d6bf975a26d85ce2db02c23541b7e6aa",
+ "resolved": "git+ssh://git@github.com/complexdatacollective/cordova-plugin-network-canvas-client.git#364662b79e1a97ac88ec0b0e520e497e810b1f0f",
"dev": true,
"license": "GPL-3.0-or-later"
},
@@ -36298,16 +36301,6 @@
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"dev": true
},
- "node_modules/xmldom": {
- "version": "0.1.27",
- "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
- "integrity": "sha512-7WpJBYwyhvsddFJA51SOIU0Be9W44sbGGjc6Z3ly8Wx/Wl7nriMPZ5xf6Np9ASlJ6gACfXcTLukm4DtX372lFw==",
- "deprecated": "Deprecated due to CVE-2021-21366 resolved in 0.5.0",
- "dev": true,
- "engines": {
- "node": ">=0.1"
- }
- },
"node_modules/xss": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/xss/-/xss-0.3.8.tgz",
@@ -40709,6 +40702,11 @@
"@xtuc/long": "4.2.2"
}
},
+ "@xmldom/xmldom": {
+ "version": "0.8.10",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
+ "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw=="
+ },
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@@ -43780,14 +43778,14 @@
}
},
"cordova-plugin-file": {
- "version": "git+ssh://git@github.com/apache/cordova-plugin-file.git#faba1bf0f1479cafe5ed256bc0181fe10768527f",
+ "version": "git+ssh://git@github.com/apache/cordova-plugin-file.git#265a932f3b5d11739fd08c0437477f441f6212c7",
"dev": true,
- "from": "cordova-plugin-file@github:apache/cordova-plugin-file"
+ "from": "cordova-plugin-file@github:apache/cordova-plugin-file#265a932"
},
"cordova-plugin-file-transfer": {
- "version": "git+ssh://git@github.com/apache/cordova-plugin-file-transfer.git#06335fea28f7ad4d815aa621e02823a63b0a9bc6",
+ "version": "git+ssh://git@github.com/apache/cordova-plugin-file-transfer.git#f12b73eb0ba70536072eeab89843c96082fce512",
"dev": true,
- "from": "cordova-plugin-file-transfer@github:apache/cordova-plugin-file-transfer"
+ "from": "cordova-plugin-file-transfer@github:apache/cordova-plugin-file-transfer#f12b73e"
},
"cordova-plugin-fullscreen": {
"version": "git+ssh://git@github.com/mesmotronic/cordova-plugin-fullscreen.git#942a9592e5ffd23b588661bfbaed708d0b56f1ca",
@@ -43800,7 +43798,7 @@
"from": "cordova-plugin-ionic-keyboard@github:ionic-team/cordova-plugin-ionic-keyboard"
},
"cordova-plugin-network-canvas-client": {
- "version": "git+ssh://git@github.com/complexdatacollective/cordova-plugin-network-canvas-client.git#4bf75df4d6bf975a26d85ce2db02c23541b7e6aa",
+ "version": "git+ssh://git@github.com/complexdatacollective/cordova-plugin-network-canvas-client.git#364662b79e1a97ac88ec0b0e520e497e810b1f0f",
"dev": true,
"from": "cordova-plugin-network-canvas-client@github:complexdatacollective/cordova-plugin-network-canvas-client"
},
@@ -64423,12 +64421,6 @@
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"dev": true
},
- "xmldom": {
- "version": "0.1.27",
- "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
- "integrity": "sha512-7WpJBYwyhvsddFJA51SOIU0Be9W44sbGGjc6Z3ly8Wx/Wl7nriMPZ5xf6Np9ASlJ6gACfXcTLukm4DtX372lFw==",
- "dev": true
- },
"xss": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/xss/-/xss-0.3.8.tgz",
diff --git a/package.json b/package.json
index c098239ba..0e7613adf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "network-canvas-interviewer",
- "version": "6.5.1",
+ "version": "6.5.2",
"productName": "Network Canvas Interviewer",
"description": "A tool for conducting Network Canvas Interviews.",
"author": "Complex Data Collective",
@@ -78,8 +78,8 @@
"connected-react-router": "^6.8.0",
"cordova-android": "~12.0.0",
"cordova-ios": "~7.0.0",
- "cordova-plugin-file": "github:apache/cordova-plugin-file",
- "cordova-plugin-file-transfer": "github:apache/cordova-plugin-file-transfer",
+ "cordova-plugin-file": "github:apache/cordova-plugin-file#265a932",
+ "cordova-plugin-file-transfer": "github:apache/cordova-plugin-file-transfer#f12b73e",
"cordova-plugin-fullscreen": "github:mesmotronic/cordova-plugin-fullscreen",
"cordova-plugin-ionic-keyboard": "github:ionic-team/cordova-plugin-ionic-keyboard",
"cordova-plugin-network-canvas-client": "github:complexdatacollective/cordova-plugin-network-canvas-client",
@@ -176,11 +176,11 @@
"whatwg-fetch": "2.0.3",
"worker-loader": "^2.0.0",
"xml2js": "~0.4.23",
- "xmldom": "~0.1.27",
"xss": "^0.3.4"
},
"dependencies": {
"@babel/runtime": "7.10.1",
+ "@xmldom/xmldom": "~0.8.10",
"archiver": "^4.0.1",
"d3-force": "~3.0.0",
"dmg-builder": "~23.6.0",
diff --git a/public/package.json b/public/package.json
index 7ab23555b..bef634fc5 100644
--- a/public/package.json
+++ b/public/package.json
@@ -1,6 +1,6 @@
{
"name": "network-canvas-interviewer",
- "version": "6.5.1",
+ "version": "6.5.2",
"productName": "Network Canvas Interviewer",
"description": "A tool for conducting Network Canvas Interviews.",
"author": "Complex Data Collective",
diff --git a/src/containers/SessionManagementScreen/SessionManagementScreen.js b/src/containers/SessionManagementScreen/SessionManagementScreen.js
index b453fc482..65f080fb9 100644
--- a/src/containers/SessionManagementScreen/SessionManagementScreen.js
+++ b/src/containers/SessionManagementScreen/SessionManagementScreen.js
@@ -23,12 +23,14 @@ const fatalExportErrorAction = withErrorDialog((error) => ({
error,
}));
+const getInitialFilename = () => `networkCanvasExport-${Date.now()}`;
+
const DataExportScreen = ({ show, onClose }) => {
const [step, setStep] = useState(3);
const [selectedSessions, setSelectedSessions] = useState([]);
// Set the default filename to 'networkCanvasExport-'
- const [filename, setFilename] = useState(`networkCanvasExport-${Date.now()}`);
+ const [filename, setFilename] = useState(getInitialFilename());
const [abortHandlers, setAbortHandlers] = useState(null);
const pairedServer = useSelector((state) => state.pairedServer);
@@ -40,6 +42,7 @@ const DataExportScreen = ({ show, onClose }) => {
const openDialog = (dialog) => dispatch(dialogActions.openDialog(dialog));
const reset = () => {
+ setFilename(getInitialFilename());
setSelectedSessions([]);
setStep(1);
};
diff --git a/src/utils/network-exporters b/src/utils/network-exporters
index 8c0e9f39e..376417cf4 160000
--- a/src/utils/network-exporters
+++ b/src/utils/network-exporters
@@ -1 +1 @@
-Subproject commit 8c0e9f39ec49d85f9b7d83e270b2a46105cc782b
+Subproject commit 376417cf4aba486431d65453d415489b5f414dfe
diff --git a/src/utils/protocol/downloadProtocol.js b/src/utils/protocol/downloadProtocol.js
index c38c72617..b0ecc04b5 100644
--- a/src/utils/protocol/downloadProtocol.js
+++ b/src/utils/protocol/downloadProtocol.js
@@ -2,7 +2,7 @@
/* global FileTransfer */
import uuid from 'uuid/v4';
import environments from '../environments';
-import inEnvironment from '../Environment';
+import inEnvironment, { isIOS } from '../Environment';
import { writeFile, tempDataPath } from '../filesystem';
import friendlyErrorMessage from '../../utils/friendlyErrorMessage';
import ApiClient from '../../utils/ApiClient';
@@ -36,8 +36,8 @@ const downloadProtocol = inEnvironment((environment) => {
if (environment === environments.ELECTRON) {
const request = require('request-promise-native');
const destination = path.join(tempDataPath(), getProtocolName());
-
return (uri, pairedServer = false) => {
+
let promisedResponse;
if (pairedServer) {
promisedResponse = new ApiClient(pairedServer).downloadProtocol(uri);
@@ -56,29 +56,41 @@ const downloadProtocol = inEnvironment((environment) => {
}
if (environment === environments.CORDOVA) {
- const destination = `${tempDataPath()}${getProtocolName()}`
return (uri, pairedServer) => {
let promisedResponse;
+
if (pairedServer) {
+ // on iOS, the cordova-plugin-network-canvas-client wants the destination
+ // to be a folder, not a file. It assigns a temp filename itself.
+ //
+ // however, on android it needs to be a file.
+ const destination = isIOS() ? tempDataPath() : `${tempDataPath()}${getProtocolName()}`;
+
promisedResponse = new ApiClient(pairedServer)
// .addTrustedCert() is not required, assuming we've just fetched the protocol list
.downloadProtocol(uri, destination)
- .then(() => destination);
+ .then((result) => {
+ // Result is a FileEntry object
+ return result.nativeURL;
+ })
} else {
promisedResponse = getURL(uri)
.then(url => url.href)
.catch(urlError)
.then(href => new Promise((resolve, reject) => {
+ // The filetransfer plugin requires a folder to write to
+ const destinationWithFolder = `${tempDataPath()}${getProtocolName()}`;
+
const fileTransfer = new FileTransfer();
- console.log('fileTransfer', destination);
fileTransfer.download(
href,
- destination,
- () => resolve(destination),
+ destinationWithFolder,
+ () => resolve(destinationWithFolder),
error => reject(error),
);
}));
}
+
return promisedResponse
.catch((error) => {
const getErrorMessage = ({ code }) => {