Removed checks for QR code features that were not supported on versions older than 2.6

This commit is contained in:
Alejandro Celaya 2022-05-01 10:44:12 +02:00
parent 9518ad9bb4
commit a949ec9e8e
4 changed files with 32 additions and 74 deletions

View file

@ -7,11 +7,7 @@ import { ShortUrlModalProps } from '../data';
import { SelectedServer } from '../../servers/data'; import { SelectedServer } from '../../servers/data';
import { CopyToClipboardIcon } from '../../utils/CopyToClipboardIcon'; import { CopyToClipboardIcon } from '../../utils/CopyToClipboardIcon';
import { buildQrCodeUrl, QrCodeCapabilities, QrCodeFormat, QrErrorCorrection } from '../../utils/helpers/qrCodes'; import { buildQrCodeUrl, QrCodeCapabilities, QrCodeFormat, QrErrorCorrection } from '../../utils/helpers/qrCodes';
import { import { supportsQrErrorCorrection } from '../../utils/helpers/features';
supportsQrCodeSizeInQuery,
supportsQrCodeMargin,
supportsQrErrorCorrection,
} from '../../utils/helpers/features';
import { ImageDownloader } from '../../common/services/ImageDownloader'; import { ImageDownloader } from '../../common/services/ImageDownloader';
import { ForServerVersionProps } from '../../servers/helpers/ForServerVersion'; import { ForServerVersionProps } from '../../servers/helpers/ForServerVersion';
import { QrFormatDropdown } from './qr-codes/QrFormatDropdown'; import { QrFormatDropdown } from './qr-codes/QrFormatDropdown';
@ -30,11 +26,9 @@ const QrCodeModal = (imageDownloader: ImageDownloader, ForServerVersion: FC<ForS
const [format, setFormat] = useState<QrCodeFormat>('png'); const [format, setFormat] = useState<QrCodeFormat>('png');
const [errorCorrection, setErrorCorrection] = useState<QrErrorCorrection>('L'); const [errorCorrection, setErrorCorrection] = useState<QrErrorCorrection>('L');
const capabilities: QrCodeCapabilities = useMemo(() => ({ const capabilities: QrCodeCapabilities = useMemo(() => ({
useSizeInPath: !supportsQrCodeSizeInQuery(selectedServer),
marginIsSupported: supportsQrCodeMargin(selectedServer),
errorCorrectionIsSupported: supportsQrErrorCorrection(selectedServer), errorCorrectionIsSupported: supportsQrErrorCorrection(selectedServer),
}), [selectedServer]); }), [selectedServer]);
const willRenderThreeControls = capabilities.marginIsSupported !== capabilities.errorCorrectionIsSupported; const willRenderThreeControls = !capabilities.errorCorrectionIsSupported;
const qrCodeUrl = useMemo( const qrCodeUrl = useMemo(
() => buildQrCodeUrl(shortUrl, { size, format, margin, errorCorrection }, capabilities), () => buildQrCodeUrl(shortUrl, { size, format, margin, errorCorrection }, capabilities),
[shortUrl, size, format, margin, errorCorrection, capabilities], [shortUrl, size, format, margin, errorCorrection, capabilities],
@ -67,21 +61,19 @@ const QrCodeModal = (imageDownloader: ImageDownloader, ForServerVersion: FC<ForS
onChange={(e) => setSize(Number(e.target.value))} onChange={(e) => setSize(Number(e.target.value))}
/> />
</FormGroup> </FormGroup>
{capabilities.marginIsSupported && ( <FormGroup className={`d-grid ${willRenderThreeControls ? 'col-md-4' : 'col-md-6'}`}>
<FormGroup className={`d-grid ${willRenderThreeControls ? 'col-md-4' : 'col-md-6'}`}> <label htmlFor="marginControl">Margin: {margin}px</label>
<label htmlFor="marginControl">Margin: {margin}px</label> <input
<input id="marginControl"
id="marginControl" type="range"
type="range" className="form-control-range"
className="form-control-range" value={margin}
value={margin} step={1}
step={1} min={0}
min={0} max={100}
max={100} onChange={(e) => setMargin(Number(e.target.value))}
onChange={(e) => setMargin(Number(e.target.value))} />
/> </FormGroup>
</FormGroup>
)}
<FormGroup className={willRenderThreeControls ? 'col-md-4' : 'col-md-6'}> <FormGroup className={willRenderThreeControls ? 'col-md-4' : 'col-md-6'}>
<QrFormatDropdown format={format} setFormat={setFormat} /> <QrFormatDropdown format={format} setFormat={setFormat} />
</FormGroup> </FormGroup>

View file

@ -4,10 +4,8 @@ import { versionMatch, Versions } from './version';
const serverMatchesVersions = (versions: Versions) => (selectedServer: SelectedServer): boolean => const serverMatchesVersions = (versions: Versions) => (selectedServer: SelectedServer): boolean =>
isReachableServer(selectedServer) && versionMatch(selectedServer.version, versions); isReachableServer(selectedServer) && versionMatch(selectedServer.version, versions);
export const supportsQrCodeSizeInQuery = serverMatchesVersions({ minVersion: '2.5.0' });
export const supportsShortUrlTitle = serverMatchesVersions({ minVersion: '2.6.0' }); export const supportsShortUrlTitle = serverMatchesVersions({ minVersion: '2.6.0' });
export const supportsOrphanVisits = supportsShortUrlTitle; export const supportsOrphanVisits = supportsShortUrlTitle;
export const supportsQrCodeMargin = supportsShortUrlTitle;
export const supportsBotVisits = serverMatchesVersions({ minVersion: '2.7.0' }); export const supportsBotVisits = serverMatchesVersions({ minVersion: '2.7.0' });
export const supportsCrawlableVisits = supportsBotVisits; export const supportsCrawlableVisits = supportsBotVisits;
export const supportsQrErrorCorrection = serverMatchesVersions({ minVersion: '2.8.0' }); export const supportsQrErrorCorrection = serverMatchesVersions({ minVersion: '2.8.0' });

View file

@ -2,8 +2,6 @@ import { isEmpty } from 'ramda';
import { stringifyQuery } from './query'; import { stringifyQuery } from './query';
export interface QrCodeCapabilities { export interface QrCodeCapabilities {
useSizeInPath: boolean;
marginIsSupported: boolean;
errorCorrectionIsSupported: boolean; errorCorrectionIsSupported: boolean;
} }
@ -21,13 +19,13 @@ export interface QrCodeOptions {
export const buildQrCodeUrl = ( export const buildQrCodeUrl = (
shortUrl: string, shortUrl: string,
{ size, format, margin, errorCorrection }: QrCodeOptions, { size, format, margin, errorCorrection }: QrCodeOptions,
{ useSizeInPath, marginIsSupported, errorCorrectionIsSupported }: QrCodeCapabilities, { errorCorrectionIsSupported }: QrCodeCapabilities,
): string => { ): string => {
const baseUrl = `${shortUrl}/qr-code${useSizeInPath ? `/${size}` : ''}`; const baseUrl = `${shortUrl}/qr-code`;
const query = stringifyQuery({ const query = stringifyQuery({
size: useSizeInPath ? undefined : size, size,
format, format,
margin: marginIsSupported && margin > 0 ? margin : undefined, margin: margin > 0 ? margin : undefined,
errorCorrection: errorCorrectionIsSupported ? errorCorrection : undefined, errorCorrection: errorCorrectionIsSupported ? errorCorrection : undefined,
}); });

View file

@ -3,71 +3,41 @@ import { buildQrCodeUrl, QrCodeFormat, QrErrorCorrection } from '../../../src/ut
describe('qrCodes', () => { describe('qrCodes', () => {
describe('buildQrCodeUrl', () => { describe('buildQrCodeUrl', () => {
it.each([ it.each([
[
'foo.com',
{ size: 530, format: 'svg' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: true, marginIsSupported: false, errorCorrectionIsSupported: false },
'foo.com/qr-code/530?format=svg',
],
[
'foo.com',
{ size: 530, format: 'png' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: true, marginIsSupported: false, errorCorrectionIsSupported: false },
'foo.com/qr-code/530?format=png',
],
[ [
'bar.io', 'bar.io',
{ size: 870, format: 'svg' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection }, { size: 870, format: 'svg' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: false, marginIsSupported: false, errorCorrectionIsSupported: false }, { errorCorrectionIsSupported: false },
'bar.io/qr-code?size=870&format=svg', 'bar.io/qr-code?size=870&format=svg',
], ],
[ [
'bar.io', 'bar.io',
{ size: 200, format: 'png' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection }, { size: 200, format: 'png' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: false, marginIsSupported: false, errorCorrectionIsSupported: false }, { errorCorrectionIsSupported: false },
'bar.io/qr-code?size=200&format=png', 'bar.io/qr-code?size=200&format=png',
], ],
[ [
'bar.io', 'bar.io',
{ size: 200, format: 'svg' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection }, { size: 200, format: 'svg' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: false, marginIsSupported: false, errorCorrectionIsSupported: false }, { errorCorrectionIsSupported: false },
'bar.io/qr-code?size=200&format=svg', 'bar.io/qr-code?size=200&format=svg',
], ],
[
'foo.net',
{ size: 480, format: 'png' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: true, marginIsSupported: false, errorCorrectionIsSupported: false },
'foo.net/qr-code/480?format=png',
],
[
'foo.net',
{ size: 480, format: 'svg' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: true, marginIsSupported: false, errorCorrectionIsSupported: false },
'foo.net/qr-code/480?format=svg',
],
[
'shlink.io',
{ size: 123, format: 'svg' as QrCodeFormat, margin: 10, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: true, marginIsSupported: false, errorCorrectionIsSupported: false },
'shlink.io/qr-code/123?format=svg',
],
[ [
'shlink.io', 'shlink.io',
{ size: 456, format: 'png' as QrCodeFormat, margin: 10, errorCorrection: 'L' as QrErrorCorrection }, { size: 456, format: 'png' as QrCodeFormat, margin: 10, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: true, marginIsSupported: true, errorCorrectionIsSupported: false }, { errorCorrectionIsSupported: false },
'shlink.io/qr-code/456?format=png&margin=10', 'shlink.io/qr-code?size=456&format=png&margin=10',
],
[
'shlink.io',
{ size: 456, format: 'png' as QrCodeFormat, margin: 0, errorCorrection: 'L' as QrErrorCorrection },
{ useSizeInPath: true, marginIsSupported: true, errorCorrectionIsSupported: false },
'shlink.io/qr-code/456?format=png',
], ],
[ [
'shlink.io', 'shlink.io',
{ size: 456, format: 'png' as QrCodeFormat, margin: 0, errorCorrection: 'H' as QrErrorCorrection }, { size: 456, format: 'png' as QrCodeFormat, margin: 0, errorCorrection: 'H' as QrErrorCorrection },
{ useSizeInPath: true, marginIsSupported: true, errorCorrectionIsSupported: true }, { errorCorrectionIsSupported: true },
'shlink.io/qr-code/456?format=png&errorCorrection=H', 'shlink.io/qr-code?size=456&format=png&errorCorrection=H',
],
[
'shlink.io',
{ size: 999, format: 'png' as QrCodeFormat, margin: 20, errorCorrection: 'Q' as QrErrorCorrection },
{ errorCorrectionIsSupported: true },
'shlink.io/qr-code?size=999&format=png&margin=20&errorCorrection=Q',
], ],
])('builds expected URL based in params', (shortUrl, options, capabilities, expectedUrl) => { ])('builds expected URL based in params', (shortUrl, options, capabilities, expectedUrl) => {
expect(buildQrCodeUrl(shortUrl, options, capabilities)).toEqual(expectedUrl); expect(buildQrCodeUrl(shortUrl, options, capabilities)).toEqual(expectedUrl);