2021-01-21 16:51:54 +01:00
|
|
|
import { useMemo, useState } from 'react';
|
|
|
|
import { DropdownItem, FormGroup, Modal, ModalBody, ModalHeader, Row } from 'reactstrap';
|
2020-01-15 18:16:12 +01:00
|
|
|
import { ExternalLink } from 'react-external-link';
|
2020-08-30 09:59:14 +02:00
|
|
|
import { ShortUrlModalProps } from '../data';
|
2021-01-21 16:51:54 +01:00
|
|
|
import { ReachableServer } from '../../servers/data';
|
|
|
|
import { versionMatch } from '../../utils/helpers/version';
|
|
|
|
import { DropdownBtn } from '../../utils/DropdownBtn';
|
2021-01-24 17:37:31 +01:00
|
|
|
import { CopyToClipboardIcon } from '../../utils/CopyToClipboardIcon';
|
|
|
|
import { buildQrCodeUrl, QrCodeCapabilities, QrCodeFormat } from '../../utils/helpers/qrCodes';
|
2018-07-27 18:05:09 +02:00
|
|
|
import './QrCodeModal.scss';
|
|
|
|
|
2021-01-21 16:51:54 +01:00
|
|
|
interface QrCodeModalConnectProps extends ShortUrlModalProps {
|
|
|
|
selectedServer: ReachableServer;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QrCodeModal = ({ shortUrl: { shortUrl }, toggle, isOpen, selectedServer }: QrCodeModalConnectProps) => {
|
|
|
|
const [ size, setSize ] = useState(300);
|
2021-02-14 09:50:26 +01:00
|
|
|
const [ margin ] = useState(0);
|
2021-01-21 16:51:54 +01:00
|
|
|
const [ format, setFormat ] = useState<QrCodeFormat>('png');
|
2021-01-24 17:37:31 +01:00
|
|
|
const capabilities: QrCodeCapabilities = useMemo(() => ({
|
|
|
|
useSizeInPath: !versionMatch(selectedServer.version, { minVersion: '2.5.0' }),
|
|
|
|
svgIsSupported: versionMatch(selectedServer.version, { minVersion: '2.4.0' }),
|
2021-02-14 09:50:26 +01:00
|
|
|
marginIsSupported: versionMatch(selectedServer.version, { minVersion: '2.6.0' }),
|
2021-01-24 17:37:31 +01:00
|
|
|
}), [ selectedServer ]);
|
2021-01-21 16:51:54 +01:00
|
|
|
const qrCodeUrl = useMemo(
|
2021-02-14 09:50:26 +01:00
|
|
|
() => buildQrCodeUrl(shortUrl, { size, format, margin }, capabilities),
|
2021-01-24 17:37:31 +01:00
|
|
|
[ shortUrl, size, format, capabilities ],
|
2021-01-21 16:51:54 +01:00
|
|
|
);
|
|
|
|
const modalSize = useMemo(() => {
|
|
|
|
if (size < 500) {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
return size < 800 ? 'lg' : 'xl';
|
|
|
|
}, [ size ]);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Modal isOpen={isOpen} toggle={toggle} centered size={modalSize}>
|
|
|
|
<ModalHeader toggle={toggle}>
|
|
|
|
QR code for <ExternalLink href={shortUrl}>{shortUrl}</ExternalLink>
|
|
|
|
</ModalHeader>
|
|
|
|
<ModalBody>
|
|
|
|
<Row className="mb-2">
|
2021-01-24 17:37:31 +01:00
|
|
|
<div className={capabilities.svgIsSupported ? 'col-md-6' : 'col-12'}>
|
2021-01-21 16:51:54 +01:00
|
|
|
<FormGroup>
|
|
|
|
<label className="mb-0">Size: {size}px</label>
|
|
|
|
<input
|
|
|
|
type="range"
|
|
|
|
className="form-control-range"
|
|
|
|
value={size}
|
|
|
|
step={10}
|
|
|
|
min={50}
|
|
|
|
max={1000}
|
|
|
|
onChange={(e) => setSize(Number(e.target.value))}
|
|
|
|
/>
|
|
|
|
</FormGroup>
|
|
|
|
</div>
|
2021-01-24 17:37:31 +01:00
|
|
|
{capabilities.svgIsSupported && (
|
|
|
|
<div className="col-md-6">
|
|
|
|
<DropdownBtn text={`Format (${format})`}>
|
|
|
|
<DropdownItem active={format === 'png'} onClick={() => setFormat('png')}>PNG</DropdownItem>
|
|
|
|
<DropdownItem active={format === 'svg'} onClick={() => setFormat('svg')}>SVG</DropdownItem>
|
|
|
|
</DropdownBtn>
|
|
|
|
</div>
|
|
|
|
)}
|
2021-01-21 16:51:54 +01:00
|
|
|
</Row>
|
|
|
|
<div className="text-center">
|
|
|
|
<div className="mb-3">
|
|
|
|
<div>QR code URL:</div>
|
|
|
|
<ExternalLink className="indivisible" href={qrCodeUrl} />
|
2021-01-24 17:37:31 +01:00
|
|
|
<CopyToClipboardIcon text={qrCodeUrl} />
|
2021-01-21 16:51:54 +01:00
|
|
|
</div>
|
|
|
|
<img src={qrCodeUrl} className="qr-code-modal__img" alt="QR code" />
|
|
|
|
<div className="mt-2">{size}x{size}</div>
|
|
|
|
</div>
|
|
|
|
</ModalBody>
|
|
|
|
</Modal>
|
|
|
|
);
|
|
|
|
};
|
2018-08-25 23:39:27 +02:00
|
|
|
|
2018-11-01 12:35:51 +01:00
|
|
|
export default QrCodeModal;
|