diff --git a/package.json b/package.json
index 0568658e9..863f046cb 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
"@redux-beacon/logger": "^1.0.0",
"@redux-beacon/offline-web": "^1.0.0",
"axios": "^0.26.1",
- "browser-image-resizer": "^1.2.0",
+ "browser-image-resizer": "^2.4.1",
"dom-to-image": "^2.6.0",
"dotenv": "^16.1.4",
"echarts": "5.4.3",
diff --git a/src/components/Board/TileEditor/TileEditor.component.js b/src/components/Board/TileEditor/TileEditor.component.js
index 03bf5de47..1678af743 100644
--- a/src/components/Board/TileEditor/TileEditor.component.js
+++ b/src/components/Board/TileEditor/TileEditor.component.js
@@ -34,7 +34,11 @@ import EditIcon from '@material-ui/icons/Edit';
import ImageEditor from '../ImageEditor';
import API from '../../../api';
-import { isAndroid, writeCvaFile } from '../../../cordova-util';
+import {
+ isAndroid,
+ requestCvaPermissions,
+ writeCvaFile
+} from '../../../cordova-util';
import { convertImageUrlToCatchable } from '../../../helpers';
import PremiumFeature from '../../PremiumFeature';
@@ -119,12 +123,9 @@ export class TileEditor extends Component {
this.setState({ editingTiles: props.editingTiles });
}
componentDidUpdate(prevProps) {
- if (
- this.props.open !== prevProps.open &&
- this.props.open &&
- this.editingTile()
- ) {
- this.setLinkedBoard();
+ if (this.props.open !== prevProps.open && this.props.open) {
+ if (this.editingTile()) this.setLinkedBoard();
+ if (isAndroid()) requestCvaPermissions();
}
}
diff --git a/src/components/UI/InputImage/InputImage.component.js b/src/components/UI/InputImage/InputImage.component.js
index 97d421216..ea8149cbc 100644
--- a/src/components/UI/InputImage/InputImage.component.js
+++ b/src/components/UI/InputImage/InputImage.component.js
@@ -1,12 +1,29 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from 'react-intl';
-import { requestCvaPermissions, isCordova } from '../../../cordova-util';
+import { isAndroid } from '../../../cordova-util';
import PhotoCameraIcon from '@material-ui/icons/PhotoCamera';
-import readAndCompressImage from 'browser-image-resizer';
+import { readAndCompressImage } from 'browser-image-resizer';
import messages from './InputImage.messages';
import './InputImage.css';
+import Button from '@material-ui/core/Button';
+const configLQ = {
+ quality: 7,
+ maxWidth: 200,
+ maxHeight: 200,
+ autoRotate: true,
+ debug: false,
+ mimeType: 'image/png'
+};
+const configHQ = {
+ quality: 1,
+ maxWidth: 800,
+ maxHeight: 800,
+ autoRotate: true,
+ debug: false,
+ mimeType: 'image/png'
+};
class InputImage extends Component {
static propTypes = {
/**
@@ -19,54 +36,90 @@ class InputImage extends Component {
onChange: PropTypes.func.isRequired
};
- async resizeImage(file, config) {
- const resizedBlob = await readAndCompressImage(file, config);
- return resizedBlob;
+ async resizeImage(file, imageName = null) {
+ //if you cancel the image uploaded, the event is dispached and the file is null
+ try {
+ const { onChange } = this.props;
+ const resizedBlob = await readAndCompressImage(file, configLQ);
+ const blobHQ = await readAndCompressImage(file, configHQ);
+ const fileName = imageName || file.name;
+ onChange(resizedBlob, fileName, blobHQ);
+ } catch (err) {
+ console.error(err);
+ }
}
+ onClick = async () => {
+ try {
+ const imageURL = await window.cordova.plugins.safMediastore.selectFile();
+ const imageName = await window.cordova.plugins.safMediastore.getFileName(
+ imageURL
+ );
+ const file = await new Promise((resolve, reject) => {
+ window.resolveLocalFileSystemURL(
+ imageURL,
+ fileEntry => {
+ fileEntry.file(
+ file => {
+ resolve(file);
+ },
+ err => {
+ console.error(err);
+ resolve(null);
+ }
+ );
+ },
+ err => {
+ console.error(err);
+ resolve(null);
+ }
+ );
+ });
+
+ if (file) {
+ await this.resizeImage(file, imageName);
+ }
+ } catch (err) {
+ console.error(err);
+ }
+ };
+
handleChange = async event => {
const file = event.target.files[0];
- const configLQ = {
- quality: 7,
- maxWidth: 200,
- maxHeight: 200,
- autoRotate: true,
- debug: false,
- mimeType: 'image/png'
- };
- const configHQ = {
- quality: 1,
- maxWidth: 800,
- maxHeight: 800,
- autoRotate: true,
- debug: false,
- mimeType: 'image/png'
- };
if (file) {
//if you cancel the image uploaded, the event is dispached and the file is null
- const { onChange } = this.props;
- const resizedBlob = await this.resizeImage(file, configLQ);
- const blobHQ = await this.resizeImage(file, configHQ);
- onChange(resizedBlob, file.name, blobHQ);
+ await this.resizeImage(file);
}
};
render() {
const { intl } = this.props;
- if (isCordova()) {
- requestCvaPermissions();
- }
return (
-
-
-
+
+ {isAndroid() ? (
+
+ }
+ className="InputImage__button"
+ >
+ {intl.formatMessage(messages.uploadImage)}
+
+
+ ) : (
+
+
+
+
+ )}
);
}
diff --git a/src/components/UI/InputImage/InputImage.css b/src/components/UI/InputImage/InputImage.css
index 1eda393b9..56e4b408f 100644
--- a/src/components/UI/InputImage/InputImage.css
+++ b/src/components/UI/InputImage/InputImage.css
@@ -27,3 +27,10 @@
text-overflow: ellipsis;
white-space: nowrap;
}
+
+.InputImage__button {
+ width: 100%;
+}
+.InputImage__buttonContainer {
+ margin-top: 6px;
+}
diff --git a/src/components/UI/InputImage/InputImage.test.js b/src/components/UI/InputImage/InputImage.test.js
index 659b6d89a..5720749cb 100644
--- a/src/components/UI/InputImage/InputImage.test.js
+++ b/src/components/UI/InputImage/InputImage.test.js
@@ -3,7 +3,6 @@ import { shallowMatchSnapshot } from '../../../common/test_utils';
import { mount, shallow } from 'enzyme';
import InputImage from './InputImage.component';
-jest.mock('browser-image-resizer');
jest.mock('../../../api/api');
jest.mock('./InputImage.messages', () => {
diff --git a/src/components/VoiceRecorder/VoiceRecorder.component.js b/src/components/VoiceRecorder/VoiceRecorder.component.js
index bbbeb4569..598a626a2 100644
--- a/src/components/VoiceRecorder/VoiceRecorder.component.js
+++ b/src/components/VoiceRecorder/VoiceRecorder.component.js
@@ -7,7 +7,6 @@ import ClearIcon from '@material-ui/icons/Clear';
import LinearProgress from '@material-ui/core/LinearProgress';
import IconButton from '../UI/IconButton';
-import { isCordova, requestCvaPermissions } from '../../cordova-util';
import messages from './VoiceRecorder.messages';
import './VoiceRecorder.css';
let mediaStream = undefined;
@@ -32,11 +31,6 @@ class VoiceRecorder extends Component {
isRecording: false,
isPlaying: false
};
- componentDidMount() {
- if (isCordova()) {
- requestCvaPermissions();
- }
- }
startRecording = () => {
navigator.mediaDevices
diff --git a/src/cordova-util.js b/src/cordova-util.js
index 7ce5965bb..b4b872742 100644
--- a/src/cordova-util.js
+++ b/src/cordova-util.js
@@ -275,72 +275,51 @@ export const requestCvaWritePermissions = () => {
}
};
-export const requestCvaPermissions = () => {
- if (isCordova()) {
+export const requestCvaPermissions = async () => {
+ if (isAndroid()) {
var permissions = window.cordova.plugins.permissions;
- permissions.checkPermission(
- permissions.READ_EXTERNAL_STORAGE,
- function(status) {
- console.log('Has READ_EXTERNAL_STORAGE:', status.hasPermission);
- if (!status.hasPermission) {
- permissions.requestPermission(
- permissions.READ_EXTERNAL_STORAGE,
- function(status) {
- console.log(
- 'success requesting READ_EXTERNAL_STORAGE permission'
- );
- },
- function(err) {
- console.warn('No permissions granted for READ_EXTERNAL_STORAGE');
- }
- );
- }
- },
- function(err) {
- console.log(err);
- }
- );
+ const androidPermissions = {
+ READ_EXTERNAL_STORAGE: 'READ_EXTERNAL_STORAGE',
+ RECORD_AUDIO: 'RECORD_AUDIO',
+ READ_MEDIA_IMAGES: 'READ_MEDIA_IMAGES',
+ READ_MEDIA_AUDIO: 'READ_MEDIA_AUDIO'
+ };
- permissions.checkPermission(
- permissions.RECORD_AUDIO,
- function(status) {
- console.log('Has RECORD_AUDIO:', status.hasPermission);
- if (!status.hasPermission) {
- permissions.requestPermission(
- permissions.RECORD_AUDIO,
+ for (let permission in androidPermissions) {
+ try {
+ const { hasPermission } = await new Promise((resolve, reject) => {
+ permissions.checkPermission(
+ permissions[permission],
function(status) {
- console.log('success requesting RECORD_AUDIO permission');
+ console.log(`Has ${permission}:`, status.hasPermission);
+ resolve(status);
},
function(err) {
- console.warn('No permissions granted for RECORD_AUDIO');
+ console.log(err);
+ resolve({ hasPermission: false });
}
);
+ });
+ if (!hasPermission) {
+ await new Promise((resolve, reject) => {
+ permissions.requestPermission(
+ permissions[permission],
+ function(status) {
+ console.log(`Success requesting ${permission} permission`);
+ if (!status.hasPermission)
+ console.log(`No permissions granted for ${permission}`);
+ resolve(status);
+ },
+ function(err) {
+ console.log(`No permissions granted for ${permission}`);
+ reject(err);
+ }
+ );
+ });
}
- },
- function(err) {
- console.log(err);
+ } catch (err) {
+ console.error(err);
}
- );
-
- // permissions.checkPermission(
- // permissions.CAMERA,
- // function(status) {
- // console.log('Has CAMERA:', status.hasPermission);
- // if (!status.hasPermission) {
- // permissions.requestPermission(
- // permissions.CAMERA,
- // function(status) {
- // console.log('success requesting CAMERA permission');
- // },
- // function(err) {
- // console.warn('No permissions granted for CAMERA');
- // }
- // );
- // }
- // },
- // function(err) {
- // console.log(err);
- // }
- // );
+ }
}
};
diff --git a/yarn.lock b/yarn.lock
index 74da2beff..2f27cf243 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3974,10 +3974,10 @@ brotli@^1.2.0:
dependencies:
base64-js "^1.1.2"
-browser-image-resizer@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/browser-image-resizer/-/browser-image-resizer-1.2.0.tgz#7cbe7e3aa4c01f83f5441585208d90df40fa1696"
- integrity sha512-xMiB6BnRsD6RWmkD6Av90qXY7uaAOXJPaS5D8cSazyao/bx6ENCm67XGl6BIhn1ETjK52yEs8A/atmMPp74M4A==
+browser-image-resizer@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/browser-image-resizer/-/browser-image-resizer-2.4.1.tgz#b3332bbd6745efb72c9c63b4578b2a29f199ace3"
+ integrity sha512-gqrmr7+NTI9FgZVVyw/GIqwJE3MhNWaBn1R5ptu75r+/M5ncyntSMQYuYhOPonm44qQNnkGN9cnghlpd9h1Hug==
browser-process-hrtime@^1.0.0:
version "1.0.0"