Added google recaptcha
This commit is contained in:
parent
0b02da06ef
commit
246a777878
4 changed files with 346 additions and 302 deletions
21
package-lock.json
generated
21
package-lock.json
generated
|
@ -22,6 +22,7 @@
|
|||
"react-dom": "^16.14.0",
|
||||
"react-dropzone": "^11.3.2",
|
||||
"react-ga": "^3.3.0",
|
||||
"react-google-recaptcha-v3": "^1.10.0",
|
||||
"react-notifications-component": "^3.1.0",
|
||||
"react-scripts": "^4.0.3",
|
||||
"reactstrap": "^8.9.0",
|
||||
|
@ -18676,6 +18677,18 @@
|
|||
"react": "^15.6.2 || ^16.0 || ^17"
|
||||
}
|
||||
},
|
||||
"node_modules/react-google-recaptcha-v3": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.10.0.tgz",
|
||||
"integrity": "sha512-JBoqU107X8klQmS8tQSbQh1IMsT1fH3kVoArIqnia0rtn0rPNG9Ld+9rD/dHJMculIczSZpGvIJTXXwtsolMcg==",
|
||||
"dependencies": {
|
||||
"hoist-non-react-statics": "^3.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^17.0 || ^18.0",
|
||||
"react-dom": "^17.0 || ^18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
|
@ -38638,6 +38651,14 @@
|
|||
"resolved": "https://registry.npmjs.org/react-ga/-/react-ga-3.3.0.tgz",
|
||||
"integrity": "sha512-o8RScHj6Lb8cwy3GMrVH6NJvL+y0zpJvKtc0+wmH7Bt23rszJmnqEQxRbyrqUzk9DTJIHoP42bfO5rswC9SWBQ=="
|
||||
},
|
||||
"react-google-recaptcha-v3": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-google-recaptcha-v3/-/react-google-recaptcha-v3-1.10.0.tgz",
|
||||
"integrity": "sha512-JBoqU107X8klQmS8tQSbQh1IMsT1fH3kVoArIqnia0rtn0rPNG9Ld+9rD/dHJMculIczSZpGvIJTXXwtsolMcg==",
|
||||
"requires": {
|
||||
"hoist-non-react-statics": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
"react-dom": "^16.14.0",
|
||||
"react-dropzone": "^11.3.2",
|
||||
"react-ga": "^3.3.0",
|
||||
"react-google-recaptcha-v3": "^1.10.0",
|
||||
"react-notifications-component": "^3.1.0",
|
||||
"react-scripts": "^4.0.3",
|
||||
"reactstrap": "^8.9.0",
|
||||
|
|
|
@ -1,313 +1,325 @@
|
|||
import React, { useState } from 'react';
|
||||
import { withStyles } from "@material-ui/core/styles";
|
||||
import Avatar from '@material-ui/core/Avatar';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import React, { useState } from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Avatar from '@material-ui/core/Avatar'
|
||||
import Button from '@material-ui/core/Button'
|
||||
import CssBaseline from '@material-ui/core/CssBaseline'
|
||||
import TextField from '@material-ui/core/TextField'
|
||||
|
||||
import Link from '@material-ui/core/Link';
|
||||
import Box from '@material-ui/core/Box';
|
||||
import LockOutlinedIcon from '@material-ui/icons/LockOutlined';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Container from '@material-ui/core/Container';
|
||||
import Link from '@material-ui/core/Link'
|
||||
import Box from '@material-ui/core/Box'
|
||||
import LockOutlinedIcon from '@material-ui/icons/LockOutlined'
|
||||
import Typography from '@material-ui/core/Typography'
|
||||
import Container from '@material-ui/core/Container'
|
||||
|
||||
import Dropzone from 'react-dropzone'
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
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 IconButton from '@material-ui/core/IconButton'
|
||||
import FileCopyOutlined from '@material-ui/icons/FileCopyOutlined'
|
||||
import PublishOutlined from '@material-ui/icons/PublishOutlined'
|
||||
|
||||
import { FilePicker } from '../src/Components'
|
||||
|
||||
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard'
|
||||
|
||||
import ControlledAccordions from './ControlledAccordions'
|
||||
import OnlineConverter from "./OnlineConverter";
|
||||
import OnlineConverter from './OnlineConverter'
|
||||
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'
|
||||
import { store } from 'react-notifications-component'
|
||||
|
||||
import AaxHashAlgorithm from './Utils/AaxHashAlgorithm'
|
||||
|
||||
import {
|
||||
GoogleReCaptchaProvider,
|
||||
withGoogleReCaptcha,
|
||||
} from 'react-google-recaptcha-v3'
|
||||
|
||||
const useStyles = theme => ({
|
||||
paper: {
|
||||
marginTop: theme.spacing(8),
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
},
|
||||
avatar: {
|
||||
margin: theme.spacing(1),
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
},
|
||||
form: {
|
||||
width: '100%', // Fix IE 11 issue.
|
||||
marginTop: theme.spacing(1),
|
||||
},
|
||||
const useStyles = (theme) => ({
|
||||
paper: {
|
||||
marginTop: theme.spacing(8),
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
},
|
||||
avatar: {
|
||||
margin: theme.spacing(1),
|
||||
backgroundColor: theme.palette.secondary.main,
|
||||
},
|
||||
form: {
|
||||
width: '100%', // Fix IE 11 issue.
|
||||
marginTop: theme.spacing(1),
|
||||
},
|
||||
|
||||
//Accordeon
|
||||
heading: {
|
||||
fontSize: theme.typography.pxToRem(15),
|
||||
flexBasis: '33.33%',
|
||||
flexShrink: 0,
|
||||
},
|
||||
secondaryHeading: {
|
||||
fontSize: theme.typography.pxToRem(15),
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
});
|
||||
//Accordeon
|
||||
heading: {
|
||||
fontSize: theme.typography.pxToRem(15),
|
||||
flexBasis: '33.33%',
|
||||
flexShrink: 0,
|
||||
},
|
||||
secondaryHeading: {
|
||||
fontSize: theme.typography.pxToRem(15),
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
})
|
||||
|
||||
class ChecksumResolver extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
checksum: "",
|
||||
fileName: "input.aax"
|
||||
}
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
checksum: '',
|
||||
fileName: 'input.aax',
|
||||
}
|
||||
}
|
||||
|
||||
DarkerDisabledTextField = withStyles({
|
||||
root: {
|
||||
marginRight: 8,
|
||||
"& .MuiInputBase-root.Mui-disabled": {
|
||||
color: "rgba(0, 0, 0, 0.6)"
|
||||
}
|
||||
}
|
||||
})(TextField);
|
||||
DarkerDisabledTextField = withStyles({
|
||||
root: {
|
||||
marginRight: 8,
|
||||
'& .MuiInputBase-root.Mui-disabled': {
|
||||
color: 'rgba(0, 0, 0, 0.6)',
|
||||
},
|
||||
},
|
||||
})(TextField)
|
||||
|
||||
Copyright = (function () {
|
||||
return (
|
||||
<Typography variant="body2" color="textSecondary" align="center">
|
||||
{'Copyright © '}
|
||||
<Link color="inherit" href="https://audible-tools.github.io/">
|
||||
audible-tools
|
||||
</Link>{' '}
|
||||
{new Date().getFullYear()}
|
||||
{'. V 0.3'}
|
||||
</Typography>
|
||||
);
|
||||
Copyright = function () {
|
||||
return (
|
||||
<Typography variant="body2" color="textSecondary" align="center">
|
||||
{'Copyright © '}
|
||||
<Link color="inherit" href="https://audible-tools.github.io/">
|
||||
audible-tools
|
||||
</Link>{' '}
|
||||
{new Date().getFullYear()}
|
||||
{'. V 0.3'}
|
||||
</Typography>
|
||||
)
|
||||
}
|
||||
|
||||
setChecksum = (value) => {
|
||||
if (value.length > 40) {
|
||||
return
|
||||
}
|
||||
this.setState({ checksum: value })
|
||||
}
|
||||
|
||||
isChecksumValid = () => {
|
||||
const { checksum } = this.state
|
||||
const regex = RegExp('[a-f0-9]{40}')
|
||||
const testResults = regex.test(checksum)
|
||||
|
||||
return testResults
|
||||
}
|
||||
|
||||
isInputInvalid = () => {
|
||||
const { checksum } = this.state
|
||||
if (!checksum || checksum === '') {
|
||||
return false
|
||||
}
|
||||
return !this.isChecksumValid()
|
||||
}
|
||||
|
||||
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,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
setChecksum = (value) => {
|
||||
if (value.length > 40) {
|
||||
return;
|
||||
requestActivationBytes = async () => {
|
||||
const { checksum } = this.state
|
||||
|
||||
const { executeRecaptcha } = (this.props)
|
||||
.googleReCaptchaProps;
|
||||
|
||||
if (!executeRecaptcha) {
|
||||
console.log('Recaptcha has not been loaded');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const token = await executeRecaptcha('homepage');
|
||||
console.log(`XToken: ${token}`);
|
||||
try {
|
||||
let request = await fetch(
|
||||
'https://api.audible-converter.ml/api/v2/activation/' + checksum,
|
||||
)
|
||||
let result = await request.json()
|
||||
const { success, activationBytes } = result
|
||||
|
||||
if (success !== true) {
|
||||
this.setState({ activationBytes: 'UNKNOWN' })
|
||||
this.addNotification(
|
||||
'An error occured while resolving the activation bytes, please check your inputs',
|
||||
false,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if (success === true) {
|
||||
const calculatedChecksum = await AaxHashAlgorithm.CalculateChecksum(
|
||||
activationBytes,
|
||||
)
|
||||
if (calculatedChecksum == checksum) {
|
||||
this.setState({ activationBytes: activationBytes })
|
||||
this.addNotification('Successfully resolved the activation bytes')
|
||||
return
|
||||
}
|
||||
this.setState({ checksum: value })
|
||||
|
||||
this.setState({ activationBytes: 'API ERROR' })
|
||||
this.addNotification(
|
||||
'An unexpected error occured while resolving the activation bytes, please try again',
|
||||
false,
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
this.setState({ activationBytes: error })
|
||||
this.addNotification(
|
||||
'An error occured while resolving the activation bytes, please check your inputs',
|
||||
false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
isChecksumValid = () => {
|
||||
const { checksum } = this.state;
|
||||
const regex = RegExp('[a-f0-9]{40}');
|
||||
const testResults = regex.test(checksum);
|
||||
buf2hex(buffer) {
|
||||
// buffer is an ArrayBuffer
|
||||
return Array.prototype.map
|
||||
.call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2))
|
||||
.join('')
|
||||
}
|
||||
|
||||
return testResults;
|
||||
}
|
||||
acceptFiles = async (files) => {
|
||||
const file = files[0]
|
||||
await this.acceptFile(file)
|
||||
}
|
||||
|
||||
isInputInvalid = () => {
|
||||
const { checksum } = this.state;
|
||||
if (!checksum || checksum === '') {
|
||||
return false;
|
||||
}
|
||||
return !this.isChecksumValid();
|
||||
};
|
||||
acceptFile = async (file) => {
|
||||
// if (!file.name.toLowerCase().endsWith(".aax")) {
|
||||
// alert('FileType not supported!');
|
||||
// return;
|
||||
// }
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
}
|
||||
this.setState({ fileName: file.name, file: file })
|
||||
const slic = file.slice(653, 653 + 20)
|
||||
const results = this.buf2hex(await slic.arrayBuffer())
|
||||
this.setChecksum(results)
|
||||
this.requestActivationBytes()
|
||||
}
|
||||
|
||||
requestActivationBytes = async () => {
|
||||
const { checksum } = this.state;
|
||||
try {
|
||||
let request = await fetch("https://api.audible-converter.ml/api/v2/activation/" + checksum);
|
||||
let result = await request.json();
|
||||
const { success, activationBytes } = result;
|
||||
render() {
|
||||
const { classes } = this.props
|
||||
const { checksum, activationBytes, fileName, file } = this.state
|
||||
|
||||
if (success !== true) {
|
||||
this.setState({ activationBytes: 'UNKNOWN' });
|
||||
this.addNotification("An error occured while resolving the activation bytes, please check your inputs", false);
|
||||
return;
|
||||
}
|
||||
return (
|
||||
<Container component="main" maxWidth="md">
|
||||
<CssBaseline />
|
||||
<div className={classes.paper}>
|
||||
<Avatar className={classes.avatar}>
|
||||
<LockOutlinedIcon />
|
||||
</Avatar>
|
||||
<Typography component="h1" variant="h5">
|
||||
AAX Checksum Resolver
|
||||
</Typography>
|
||||
|
||||
if (success === true) {
|
||||
const calculatedChecksum = await AaxHashAlgorithm.CalculateChecksum(activationBytes);
|
||||
if (calculatedChecksum == checksum) {
|
||||
this.setState({ activationBytes: activationBytes });
|
||||
this.addNotification("Successfully resolved the activation bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({ activationBytes: "API ERROR" });
|
||||
this.addNotification("An unexpected error occured while resolving the activation bytes, please try again", false);
|
||||
<form className={classes.form} noValidate>
|
||||
<Dropzone
|
||||
noClick
|
||||
onDrop={(acceptedFiles) => {
|
||||
console.log(acceptedFiles)
|
||||
this.acceptFiles(acceptedFiles)
|
||||
}}
|
||||
>
|
||||
{({ getRootProps, getInputProps }) => (
|
||||
<section>
|
||||
<div {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
<TextField
|
||||
error={this.isInputInvalid()}
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
id="checksum"
|
||||
label="Checksum or Drag&Drop .aax file -"
|
||||
name="checksum"
|
||||
autoComplete="checksum"
|
||||
autoFocus
|
||||
onChange={(x) => this.setChecksum(x.target.value)}
|
||||
onError={() => {}}
|
||||
value={checksum}
|
||||
InputProps={{
|
||||
readOnly: false,
|
||||
endAdornment: (
|
||||
<FilePicker
|
||||
extensions={['aax', 'AAX']}
|
||||
maxSize={99999}
|
||||
onChange={this.acceptFile}
|
||||
onError={() => {}}
|
||||
>
|
||||
<IconButton>
|
||||
<PublishOutlined />
|
||||
</IconButton>
|
||||
</FilePicker>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</Dropzone>
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
this.setState({ activationBytes: error });
|
||||
this.addNotification("An error occured while resolving the activation bytes, please check your inputs", false);
|
||||
}
|
||||
}
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
this.requestActivationBytes()
|
||||
}}
|
||||
disabled={!this.isChecksumValid()}
|
||||
>
|
||||
Request Activation Bytes
|
||||
</Button>
|
||||
|
||||
buf2hex(buffer) { // buffer is an ArrayBuffer
|
||||
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
|
||||
}
|
||||
|
||||
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;
|
||||
// }
|
||||
|
||||
this.setState({ fileName: file.name, file:file });
|
||||
const slic = file.slice(653, 653 + 20);
|
||||
const results = this.buf2hex(await slic.arrayBuffer());
|
||||
this.setChecksum(results)
|
||||
this.requestActivationBytes();
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
const { checksum, activationBytes, fileName, file } = this.state;
|
||||
|
||||
// const { files, onClick, errors, HiddenFileInput } = useFilePicker({
|
||||
// maxFileSize: 1000000,
|
||||
// maxImageWidth: 1000,
|
||||
// imageQuality: 0.92,
|
||||
// resizeImage: true
|
||||
// });
|
||||
|
||||
return (
|
||||
<Container component="main" maxWidth="md">
|
||||
|
||||
<CssBaseline />
|
||||
<div className={classes.paper}>
|
||||
<Avatar className={classes.avatar}>
|
||||
<LockOutlinedIcon />
|
||||
</Avatar>
|
||||
<Typography component="h1" variant="h5">
|
||||
AAX Checksum Resolver
|
||||
</Typography>
|
||||
|
||||
<form className={classes.form} noValidate>
|
||||
<Dropzone
|
||||
noClick
|
||||
onDrop={acceptedFiles => {
|
||||
console.log(acceptedFiles);
|
||||
this.acceptFiles(acceptedFiles);
|
||||
}}>
|
||||
{({ getRootProps, getInputProps }) => (
|
||||
<section>
|
||||
<div {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
<TextField
|
||||
error={this.isInputInvalid()}
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
required
|
||||
fullWidth
|
||||
id="checksum"
|
||||
label="Checksum or Drag&Drop .aax file -"
|
||||
name="checksum"
|
||||
autoComplete="checksum"
|
||||
autoFocus
|
||||
onChange={(x) => this.setChecksum(x.target.value)}
|
||||
onError={()=>{}}
|
||||
value={checksum}
|
||||
InputProps={{
|
||||
readOnly: false,
|
||||
endAdornment: (
|
||||
<FilePicker
|
||||
extensions={['aax', 'AAX']}
|
||||
maxSize={99999}
|
||||
onChange={this.acceptFile}
|
||||
>
|
||||
<IconButton >
|
||||
<PublishOutlined />
|
||||
</IconButton>
|
||||
</FilePicker>
|
||||
)
|
||||
}}
|
||||
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</Dropzone>
|
||||
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
this.requestActivationBytes();
|
||||
}}
|
||||
disabled={!this.isChecksumValid()}
|
||||
>
|
||||
Request Activation Bytes
|
||||
</Button>
|
||||
|
||||
<this.DarkerDisabledTextField
|
||||
value={activationBytes}
|
||||
disabled
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
fullWidth
|
||||
id="activationBytes"
|
||||
label={activationBytes ? '' : "Activation Bytes"}
|
||||
name="activationBytes"
|
||||
autoComplete="activationBytes"
|
||||
aria-readonly
|
||||
|
||||
InputProps={{
|
||||
readOnly: true,
|
||||
endAdornment: (
|
||||
<CopyToClipboard text={activationBytes}>
|
||||
<IconButton >
|
||||
<FileCopyOutlined />
|
||||
</IconButton>
|
||||
</CopyToClipboard>
|
||||
)
|
||||
}}
|
||||
|
||||
/>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<ControlledAccordions
|
||||
fileName={fileName}
|
||||
activationBytes={activationBytes}
|
||||
file ={file}
|
||||
/>
|
||||
<Box mt={1}>
|
||||
<this.Copyright />
|
||||
</Box>
|
||||
|
||||
|
||||
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
<this.DarkerDisabledTextField
|
||||
value={activationBytes}
|
||||
disabled
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
fullWidth
|
||||
id="activationBytes"
|
||||
label={activationBytes ? '' : 'Activation Bytes'}
|
||||
name="activationBytes"
|
||||
autoComplete="activationBytes"
|
||||
aria-readonly
|
||||
InputProps={{
|
||||
readOnly: true,
|
||||
endAdornment: (
|
||||
<CopyToClipboard text={activationBytes}>
|
||||
<IconButton>
|
||||
<FileCopyOutlined />
|
||||
</IconButton>
|
||||
</CopyToClipboard>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
<ControlledAccordions
|
||||
fileName={fileName}
|
||||
activationBytes={activationBytes}
|
||||
file={file}
|
||||
/>
|
||||
<Box mt={1}>
|
||||
<this.Copyright />
|
||||
</Box>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(useStyles)(ChecksumResolver);
|
||||
export default withGoogleReCaptcha(withStyles(useStyles)(ChecksumResolver))
|
||||
|
|
60
src/index.js
60
src/index.js
|
@ -1,37 +1,47 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import ChecksumResolver from './ChecksumResolver';
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import './index.css'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
import ChecksumResolver from './ChecksumResolver'
|
||||
import ReactNotification from 'react-notifications-component'
|
||||
import ForkMeOnGithub from 'fork-me-on-github';
|
||||
import ForkMeOnGithub from 'fork-me-on-github'
|
||||
|
||||
import ReactGA from 'react-ga'
|
||||
import {
|
||||
GoogleReCaptchaProvider,
|
||||
GoogleReCaptcha,
|
||||
} from 'react-google-recaptcha-v3'
|
||||
|
||||
import ReactGA from 'react-ga';
|
||||
fetch('https://api.audible-converter.ml/api/v2/WakeUpNeo').then((data) =>
|
||||
console.log('Woke up, im ready to serve :D'),
|
||||
)
|
||||
|
||||
fetch("https://api.audible-converter.ml/api/v2/WakeUpNeo")
|
||||
.then(data => console.log("Woke up, im ready to serve :D"))
|
||||
|
||||
ReactGA.initialize('UA-174657678-1');
|
||||
ReactGA.pageview(window.location.pathname + window.location.search);
|
||||
ReactGA.initialize('UA-174657678-1')
|
||||
ReactGA.pageview(window.location.pathname + window.location.search)
|
||||
|
||||
ReactDOM.render(
|
||||
<div>
|
||||
<div style={{display:'flex'}}>
|
||||
<ReactNotification />
|
||||
|
||||
</div>
|
||||
<ForkMeOnGithub
|
||||
repo="https://github.com/audible-tools/audible-tools.github.io"
|
||||
colorOctocat="black"
|
||||
isPride
|
||||
/>
|
||||
<ChecksumResolver />
|
||||
<GoogleReCaptchaProvider reCaptchaKey="6LeZhMMhAAAAAH2cwtbCRYys5WawPj4KS5pw-GNd">
|
||||
{/* <GoogleReCaptcha
|
||||
onVerify={(a, b, c) => {
|
||||
console.log(`Token: ${a}`);
|
||||
}}
|
||||
/> */}
|
||||
<div style={{ display: 'flex' }}>
|
||||
<ReactNotification />
|
||||
</div>
|
||||
<ForkMeOnGithub
|
||||
repo="https://github.com/audible-tools/audible-tools.github.io"
|
||||
colorOctocat="black"
|
||||
isPride
|
||||
/>
|
||||
<ChecksumResolver />
|
||||
</GoogleReCaptchaProvider>
|
||||
</div>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
document.getElementById('root'),
|
||||
)
|
||||
|
||||
// If you want your app to work offline and load faster, you can change
|
||||
// unregister() to register() below. Note this comes with some pitfalls.
|
||||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.unregister()
|
||||
|
|
Loading…
Reference in a new issue