Implemented notification & switched to async/await & added file choocer
This commit is contained in:
parent
8305d58933
commit
5ee29023a2
11 changed files with 531 additions and 73 deletions
201
package-lock.json
generated
201
package-lock.json
generated
|
@ -18,33 +18,26 @@
|
|||
"integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ=="
|
||||
},
|
||||
"@babel/core": {
|
||||
"version": "7.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz",
|
||||
"integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==",
|
||||
"version": "7.13.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.13.tgz",
|
||||
"integrity": "sha512-1xEs9jZAyKIouOoCmpsgk/I26PoKyvzQ2ixdRpRzfbcp1fL+ozw7TUgdDgwonbTovqRaTfRh50IXuw4QrWO0GA==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/generator": "^7.12.1",
|
||||
"@babel/helper-module-transforms": "^7.12.1",
|
||||
"@babel/helpers": "^7.12.1",
|
||||
"@babel/parser": "^7.12.3",
|
||||
"@babel/template": "^7.10.4",
|
||||
"@babel/traverse": "^7.12.1",
|
||||
"@babel/types": "^7.12.1",
|
||||
"@babel/code-frame": "^7.12.13",
|
||||
"@babel/generator": "^7.13.9",
|
||||
"@babel/helper-compilation-targets": "^7.13.13",
|
||||
"@babel/helper-module-transforms": "^7.13.12",
|
||||
"@babel/helpers": "^7.13.10",
|
||||
"@babel/parser": "^7.13.13",
|
||||
"@babel/template": "^7.12.13",
|
||||
"@babel/traverse": "^7.13.13",
|
||||
"@babel/types": "^7.13.13",
|
||||
"convert-source-map": "^1.7.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.1",
|
||||
"gensync": "^1.0.0-beta.2",
|
||||
"json5": "^2.1.2",
|
||||
"lodash": "^4.17.19",
|
||||
"resolve": "^1.3.2",
|
||||
"semver": "^5.4.1",
|
||||
"semver": "^6.3.0",
|
||||
"source-map": "^0.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
|
@ -1211,6 +1204,15 @@
|
|||
"@hapi/hoek": "^8.3.0"
|
||||
}
|
||||
},
|
||||
"@hypnosphi/create-react-context": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz",
|
||||
"integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==",
|
||||
"requires": {
|
||||
"gud": "^1.0.0",
|
||||
"warning": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"@istanbuljs/load-nyc-config": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||
|
@ -3870,6 +3872,29 @@
|
|||
"babel-plugin-transform-react-remove-prop-types": "0.4.24"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": {
|
||||
"version": "7.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz",
|
||||
"integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/generator": "^7.12.1",
|
||||
"@babel/helper-module-transforms": "^7.12.1",
|
||||
"@babel/helpers": "^7.12.1",
|
||||
"@babel/parser": "^7.12.3",
|
||||
"@babel/template": "^7.10.4",
|
||||
"@babel/traverse": "^7.12.1",
|
||||
"@babel/types": "^7.12.1",
|
||||
"convert-source-map": "^1.7.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.1",
|
||||
"json5": "^2.1.2",
|
||||
"lodash": "^4.17.19",
|
||||
"resolve": "^1.3.2",
|
||||
"semver": "^5.4.1",
|
||||
"source-map": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-proposal-class-properties": {
|
||||
"version": "7.12.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz",
|
||||
|
@ -4606,6 +4631,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"classnames": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
||||
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
|
||||
|
@ -7849,6 +7879,11 @@
|
|||
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
|
||||
"optional": true
|
||||
},
|
||||
"gud": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
|
||||
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
|
||||
},
|
||||
"gzip-size": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
|
||||
|
@ -14469,6 +14504,10 @@
|
|||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
|
||||
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
|
||||
},
|
||||
"react-file-picker": {
|
||||
"version": "git+https://github.com/dantheuber/react-file-picker.git#61c15b0c863987a80aa80c22a9b5caf6b975dc7e",
|
||||
"from": "git+https://github.com/dantheuber/react-file-picker.git#master"
|
||||
},
|
||||
"react-ga": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-ga/-/react-ga-3.3.0.tgz",
|
||||
|
@ -14479,6 +14518,37 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||
},
|
||||
"react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||
},
|
||||
"react-notifications-component": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-notifications-component/-/react-notifications-component-3.1.0.tgz",
|
||||
"integrity": "sha512-qq+zgqVIa2zhlw+RvO2QSPk7xHLvZWTHl9VKRO56sMUef/UrcUTqOswL0DSJtRIpZYZhclquQUfDxD6H2w8aWA=="
|
||||
},
|
||||
"react-popper": {
|
||||
"version": "1.3.11",
|
||||
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz",
|
||||
"integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@hypnosphi/create-react-context": "^0.3.1",
|
||||
"deep-equal": "^1.1.1",
|
||||
"popper.js": "^1.14.4",
|
||||
"prop-types": "^15.6.1",
|
||||
"typed-styles": "^0.0.7",
|
||||
"warning": "^4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"popper.js": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
|
||||
"integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-refresh": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
|
||||
|
@ -14550,6 +14620,36 @@
|
|||
"workbox-webpack-plugin": "5.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": {
|
||||
"version": "7.12.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.3.tgz",
|
||||
"integrity": "sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/generator": "^7.12.1",
|
||||
"@babel/helper-module-transforms": "^7.12.1",
|
||||
"@babel/helpers": "^7.12.1",
|
||||
"@babel/parser": "^7.12.3",
|
||||
"@babel/template": "^7.10.4",
|
||||
"@babel/traverse": "^7.12.1",
|
||||
"@babel/types": "^7.12.1",
|
||||
"convert-source-map": "^1.7.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.1",
|
||||
"json5": "^2.1.2",
|
||||
"lodash": "^4.17.19",
|
||||
"resolve": "^1.3.2",
|
||||
"semver": "^5.4.1",
|
||||
"source-map": "^0.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
|
@ -14593,6 +14693,47 @@
|
|||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"reactstrap": {
|
||||
"version": "8.9.0",
|
||||
"resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-8.9.0.tgz",
|
||||
"integrity": "sha512-pmf33YjpNZk1IfrjqpWCUMq9hk6GzSnMWBAofTBNIRJQB1zQ0Au2kzv3lPUAFsBYgWEuI9iYa/xKXHaboSiMkQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"classnames": "^2.2.3",
|
||||
"prop-types": "^15.5.8",
|
||||
"react-popper": "^1.3.6",
|
||||
"react-transition-group": "^2.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": {
|
||||
"version": "7.13.10",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz",
|
||||
"integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"dom-helpers": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
|
||||
"integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2"
|
||||
}
|
||||
},
|
||||
"react-transition-group": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
|
||||
"integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
|
||||
"requires": {
|
||||
"dom-helpers": "^3.4.0",
|
||||
"loose-envify": "^1.4.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-lifecycles-compat": "^3.0.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"read-pkg": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
|
||||
|
@ -16822,6 +16963,11 @@
|
|||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"typed-styles": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
|
||||
"integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
|
@ -16835,6 +16981,11 @@
|
|||
"is-typedarray": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz",
|
||||
"integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw=="
|
||||
},
|
||||
"unbox-primitive": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
|
||||
|
@ -17173,6 +17324,14 @@
|
|||
"makeerror": "1.0.x"
|
||||
}
|
||||
},
|
||||
"warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.13.13",
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@material-ui/icons": "^4.11.2",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
|
@ -13,8 +14,12 @@
|
|||
"react-copy-to-clipboard": "^5.0.3",
|
||||
"react-dom": "^16.14.0",
|
||||
"react-dropzone": "^11.3.2",
|
||||
"react-file-picker": "git+https://github.com/dantheuber/react-file-picker.git#master",
|
||||
"react-ga": "^3.3.0",
|
||||
"react-scripts": "^4.0.3"
|
||||
"react-notifications-component": "^3.1.0",
|
||||
"react-scripts": "^4.0.3",
|
||||
"reactstrap": "^8.9.0",
|
||||
"typescript": "^4.2.3"
|
||||
},
|
||||
"scripts": {
|
||||
"predeploy": "npm run build",
|
||||
|
|
|
@ -17,14 +17,21 @@ import FileCopyOutlined from '@material-ui/icons/FileCopyOutlined';
|
|||
import PublishOutlined from '@material-ui/icons/PublishOutlined';
|
||||
|
||||
// import { useFilePicker } from 'react-sage'
|
||||
//import { FilePicker } from 'react-file-picker'
|
||||
// import { FilePicker } from 'react-file-picker'
|
||||
|
||||
import { FilePicker } from '../src/Components'
|
||||
|
||||
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
|
||||
import ControlledAccordions from './ControlledAccordions'
|
||||
|
||||
import 'react-notifications-component/dist/theme.css'
|
||||
|
||||
import ReactNotification from 'react-notifications-component'
|
||||
import { store } from 'react-notifications-component';
|
||||
// import 'animate.css/animate.compat.css'
|
||||
|
||||
|
||||
const useStyles = theme => ({
|
||||
paper: {
|
||||
|
@ -108,34 +115,51 @@ class ChecksumResolver extends React.Component {
|
|||
return !this.isChecksumValid();
|
||||
};
|
||||
|
||||
requestActivationBytes = () => {
|
||||
addNotification = function (text, success = true) {
|
||||
store.addNotification({
|
||||
message: text,
|
||||
type: success ? "success" : "danger",
|
||||
// type: "danger",
|
||||
insert: "bottom-left",
|
||||
container: "top-full",
|
||||
animationIn: ["animate__animated", "animate__fadeIn"],
|
||||
animationOut: ["animate__animated", "animate__fadeOut"],
|
||||
dismiss: {
|
||||
duration: 3000,
|
||||
onScreen: false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
requestActivationBytes = async () => {
|
||||
const { checksum } = this.state;
|
||||
|
||||
fetch("https://aax.api.j-kit.me/api/v2/activation/" + checksum)
|
||||
.then(res => res.json())
|
||||
.then(
|
||||
(result) => {
|
||||
const { success, activationBytes } = result;
|
||||
if (success === true) {
|
||||
this.setState({ activationBytes: result.activationBytes });
|
||||
} else {
|
||||
this.setState({ activationBytes: 'UNKNOWN' });
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
(error) => {
|
||||
this.setState({ activationBytes: 'UNKNOWN' });
|
||||
}
|
||||
)
|
||||
try {
|
||||
let request = await fetch("https://aax.api.j-kit.me/api/v2/activation/" + checksum);
|
||||
let result = await request.json();
|
||||
const { success, activationBytes } = result;
|
||||
if (success === true) {
|
||||
this.setState({ activationBytes: activationBytes });
|
||||
this.addNotification("Successfully resolved the activation bytes");
|
||||
} else {
|
||||
this.setState({ activationBytes: 'UNKNOWN' });
|
||||
this.addNotification("An error occured while resolving the activation bytes, please check your inputs", false);
|
||||
}
|
||||
} catch (error) {
|
||||
this.setState({ activationBytes: error });
|
||||
this.addNotification("An error occured while resolving the activation bytes, please check your inputs", false);
|
||||
}
|
||||
}
|
||||
|
||||
buf2hex(buffer) { // buffer is an ArrayBuffer
|
||||
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
|
||||
}
|
||||
|
||||
acceptFile = async files => {
|
||||
acceptFiles = async files => {
|
||||
const file = files[0];
|
||||
await this.acceptFile(file);
|
||||
}
|
||||
|
||||
acceptFile = async file => {
|
||||
// if (!file.name.toLowerCase().endsWith(".aax")) {
|
||||
// alert('FileType not supported!');
|
||||
// return;
|
||||
|
@ -177,7 +201,7 @@ class ChecksumResolver extends React.Component {
|
|||
noClick
|
||||
onDrop={acceptedFiles => {
|
||||
console.log(acceptedFiles);
|
||||
this.acceptFile(acceptedFiles);
|
||||
this.acceptFiles(acceptedFiles);
|
||||
}}>
|
||||
{({ getRootProps, getInputProps }) => (
|
||||
<section>
|
||||
|
@ -196,35 +220,19 @@ class ChecksumResolver extends React.Component {
|
|||
autoFocus
|
||||
onChange={(x) => this.setChecksum(x.target.value)}
|
||||
value={checksum}
|
||||
|
||||
InputProps={{
|
||||
readOnly: true,
|
||||
// endAdornment: (
|
||||
// // <IconButton onClick={() => {
|
||||
|
||||
// // alert('hi')
|
||||
// // }}>
|
||||
// // <PublishOutlined />
|
||||
// // </IconButton>
|
||||
|
||||
// // <IconButton>
|
||||
// // <HiddenFileInput accept=".jpg, .jpeg, .png" multiple={false} />
|
||||
|
||||
// // <PublishOutlined />
|
||||
// // </IconButton>
|
||||
// //accept="image/*"
|
||||
// // <FilePicker
|
||||
// // accept="image/*"
|
||||
// // extensions={['aax','AAX']}
|
||||
// // acceptFile="image/*"
|
||||
// // onChange={FileObject => { }}
|
||||
// // onError={errMsg => { }}
|
||||
// // >
|
||||
// // <IconButton >
|
||||
// // <PublishOutlined />
|
||||
// // </IconButton>
|
||||
// // </FilePicker>
|
||||
// )
|
||||
readOnly: false,
|
||||
endAdornment: (
|
||||
<FilePicker
|
||||
extensions={['aax', 'AAX']}
|
||||
maxSize={99999}
|
||||
onChange={this.acceptFile}
|
||||
>
|
||||
<IconButton >
|
||||
<PublishOutlined />
|
||||
</IconButton>
|
||||
</FilePicker>
|
||||
)
|
||||
}}
|
||||
|
||||
/>
|
||||
|
@ -280,6 +288,7 @@ class ChecksumResolver extends React.Component {
|
|||
</Box>
|
||||
|
||||
|
||||
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
|
45
src/Components/FileInput/index.js
Normal file
45
src/Components/FileInput/index.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
// external imports
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
class FileInput extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this._handleUpload = this._handleUpload.bind(this)
|
||||
}
|
||||
|
||||
_handleUpload(evt) {
|
||||
const file = evt.target.files[0]
|
||||
this.props.onChange(file)
|
||||
|
||||
// free up the fileInput again
|
||||
this.fileInput.value = null
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={this.props.style}>
|
||||
<input
|
||||
accept={this.props.accept}
|
||||
type="file"
|
||||
style={{ display: 'none' }}
|
||||
onChange={this._handleUpload}
|
||||
ref={ele => (this.fileInput = ele)}
|
||||
/>
|
||||
{React.cloneElement(this.props.children, {
|
||||
onClick: () => this.fileInput.click()
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
FileInput.propTypes = {
|
||||
style: PropTypes.object,
|
||||
accept: PropTypes.string,
|
||||
children: PropTypes.node.isRequired,
|
||||
onChange: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
export default FileInput
|
80
src/Components/FilePicker/index.js
Normal file
80
src/Components/FilePicker/index.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
// external imports
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
// local imports
|
||||
import FileInput from '../FileInput'
|
||||
|
||||
class FilePicker extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this._validate = this._validate.bind(this)
|
||||
}
|
||||
|
||||
_validate(file) {
|
||||
const { onError, onChange, maxSize, extensions } = this.props
|
||||
|
||||
// make sure a file was provided in the first place
|
||||
if (!file) {
|
||||
onError('Failed to upload a file.')
|
||||
return
|
||||
}
|
||||
|
||||
// if we care about file extensions
|
||||
if (extensions) {
|
||||
const uploadedFileExt = file.name
|
||||
.split('.')
|
||||
.pop()
|
||||
.toLowerCase()
|
||||
const isValidFileExt = extensions
|
||||
.map(ext => ext.toLowerCase())
|
||||
.includes(uploadedFileExt)
|
||||
|
||||
if (!isValidFileExt) {
|
||||
onError(`Must upload a file of type: ${extensions.join(' or ')}`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// convert maxSize from megabytes to bytes
|
||||
const maxBytes = maxSize * 1000000
|
||||
|
||||
if (file.size > maxBytes) {
|
||||
onError(`File size must be less than ${maxSize} MB.`)
|
||||
return
|
||||
}
|
||||
|
||||
// return native file object
|
||||
onChange(file)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, style } = this.props;
|
||||
const accept = this.props.extensions.map(ext => `.${ext}`).join(',')
|
||||
|
||||
return (
|
||||
<FileInput onChange={this._validate} style={style} accept={accept}>
|
||||
{children}
|
||||
</FileInput>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
FilePicker.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onError: PropTypes.func.isRequired,
|
||||
// max file size in MB
|
||||
maxSize: PropTypes.number,
|
||||
// file extension
|
||||
extensions: PropTypes.array,
|
||||
// validate file contents
|
||||
validateContent: PropTypes.func,
|
||||
style: PropTypes.object
|
||||
}
|
||||
|
||||
FilePicker.defaultProps = {
|
||||
maxSize: 2
|
||||
}
|
||||
|
||||
export default FilePicker
|
103
src/Components/FilePicker/test.js
Normal file
103
src/Components/FilePicker/test.js
Normal file
|
@ -0,0 +1,103 @@
|
|||
// external imports
|
||||
import React from 'react'
|
||||
import { mount } from 'enzyme'
|
||||
// local imports
|
||||
import FilePicker from '.'
|
||||
|
||||
describe('File Picker', () => {
|
||||
let onChange
|
||||
let onError
|
||||
|
||||
beforeEach(() => {
|
||||
onChange = jest.fn()
|
||||
onError = jest.fn()
|
||||
})
|
||||
|
||||
test('returns a valid component with required props', () => {
|
||||
const ele = (
|
||||
<FilePicker onChange={() => ({})} onError={() => ({})}>
|
||||
<button>Click to upload</button>
|
||||
</FilePicker>
|
||||
)
|
||||
|
||||
expect(React.isValidElement(ele)).toBe(true)
|
||||
})
|
||||
|
||||
test('call error handler when no file uploaded', () => {
|
||||
// mount the select with a few options
|
||||
const wrapper = mount(
|
||||
<FilePicker onChange={onChange} onError={onError}>
|
||||
<div>Click here</div>
|
||||
</FilePicker>
|
||||
)
|
||||
|
||||
// trigger the onChange callback on file input
|
||||
wrapper.find('input').simulate('change', { target: { files: [] } })
|
||||
|
||||
expect(onError.mock.calls.length).toBe(1)
|
||||
expect(onChange.mock.calls.length).toBe(0)
|
||||
})
|
||||
|
||||
test('call error handler when a file with incorrect extension is uploaded', () => {
|
||||
// mount the select with a few options
|
||||
const wrapper = mount(
|
||||
<FilePicker onChange={onChange} onError={onError} extensions={['md']}>
|
||||
<div>Click here</div>
|
||||
</FilePicker>
|
||||
)
|
||||
|
||||
const file = new Blob(['file contents'], { type: 'text/plain' })
|
||||
file.name = 'file.txt'
|
||||
|
||||
// trigger the onChange callback on file input
|
||||
wrapper.find('input').simulate('change', { target: { files: [file] } })
|
||||
|
||||
expect(onError.mock.calls.length).toBe(1)
|
||||
expect(onChange.mock.calls.length).toBe(0)
|
||||
})
|
||||
|
||||
test('call error handler when a file that is too large is uploaded', () => {
|
||||
// mount the select with a few options
|
||||
const wrapper = mount(
|
||||
<FilePicker
|
||||
onChange={onChange}
|
||||
onError={onError}
|
||||
// set unreasonably small max size so that our tiny blob is too big
|
||||
maxSize={0.0000000001}
|
||||
>
|
||||
<div>Click here</div>
|
||||
</FilePicker>
|
||||
)
|
||||
|
||||
const file = new Blob(['file contents'], { type: 'text/plain' })
|
||||
|
||||
// trigger the onChange callback on file input
|
||||
wrapper.find('input').simulate('change', { target: { files: [file] } })
|
||||
|
||||
expect(onError.mock.calls.length).toBe(1)
|
||||
expect(onChange.mock.calls.length).toBe(0)
|
||||
})
|
||||
|
||||
test('call change handler when a file with correct size and extension is uploaded', () => {
|
||||
// mount the select with a few options
|
||||
const wrapper = mount(
|
||||
<FilePicker
|
||||
onChange={onChange}
|
||||
onError={onError}
|
||||
extensions={['txt']}
|
||||
maxSize={1}
|
||||
>
|
||||
<div>Click here</div>
|
||||
</FilePicker>
|
||||
)
|
||||
|
||||
const file = new Blob(['file contents'], { type: 'text/plain' })
|
||||
file.name = 'file.txt'
|
||||
|
||||
// trigger the onChange callback on file input
|
||||
wrapper.find('input').simulate('change', { target: { files: [file] } })
|
||||
|
||||
expect(onError.mock.calls.length).toBe(0)
|
||||
expect(onChange.mock.calls.length).toBe(1)
|
||||
})
|
||||
})
|
1
src/Components/index.js
Normal file
1
src/Components/index.js
Normal file
|
@ -0,0 +1 @@
|
|||
export { default as FilePicker } from './FilePicker'
|
2
src/Components/utils/index.js
Normal file
2
src/Components/utils/index.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
export { default as loadImage } from './load-image'
|
||||
export { default as loadFile } from './load-file'
|
11
src/Components/utils/load-file.js
Normal file
11
src/Components/utils/load-file.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
export default function loadFile(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
|
||||
reader.readAsDataURL(file)
|
||||
|
||||
reader.onloadend = loadedFIle => resolve(loadedFIle.target.result)
|
||||
|
||||
reader.onerror = () => reject(new Error('There was an error uploading the file'))
|
||||
})
|
||||
}
|
35
src/Components/utils/load-image.js
Normal file
35
src/Components/utils/load-image.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
export default function loadImg(dataUrl, dims) {
|
||||
// destructure props from dims
|
||||
const { minWidth, maxWidth, minHeight, maxHeight } = dims
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// create a new html image element
|
||||
const img = new Image()
|
||||
// set the image src attribute to our dataUrl
|
||||
img.src = dataUrl
|
||||
|
||||
// listen for onload event
|
||||
img.onload = () => {
|
||||
// validate the min and max image dimensions
|
||||
if (img.width < minWidth || img.height < minHeight) {
|
||||
reject(
|
||||
new Error(
|
||||
`The uploaded image is too small. Must be at least ${minWidth}px by ${minHeight}px.`
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (img.width > maxWidth || img.height > maxHeight) {
|
||||
reject(
|
||||
new Error(
|
||||
`The uploaded image is too large. Must be no more than ${maxWidth}px by ${maxHeight}px.`
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
resolve(true)
|
||||
}
|
||||
|
||||
img.onerror = () => reject(new Error('There was an error uploading the image'))
|
||||
})
|
||||
}
|
10
src/index.js
10
src/index.js
|
@ -3,13 +3,21 @@ import ReactDOM from 'react-dom';
|
|||
import './index.css';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import ChecksumResolver from './ChecksumResolver';
|
||||
import ReactNotification from 'react-notifications-component'
|
||||
|
||||
import ReactGA from 'react-ga';
|
||||
ReactGA.initialize('UA-174657678-1');
|
||||
ReactGA.pageview(window.location.pathname + window.location.search);
|
||||
|
||||
ReactDOM.render(
|
||||
<ChecksumResolver />,
|
||||
<div>
|
||||
<div style={{display:'flex'}}>
|
||||
<ReactNotification />
|
||||
|
||||
</div>
|
||||
|
||||
<ChecksumResolver />
|
||||
</div>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue