diff --git a/README.md b/README.md index 44a5a8b32..e6c7da325 100644 --- a/README.md +++ b/README.md @@ -102,3 +102,34 @@ redux-devtools --open --port=8000 > Other UI options like `--open=browser` are available. Go to settings to specify port one more time. + +### Notes about countries flags + +- Do not compress the atlas with them, which is located at `public/misc/country-flags/atlas_original.png`, using tinypng; the compressed image has too low quality. +- You can generate such an atlas with a script like below: +```js +const sharp = require('sharp'); +const fsPromises = require('fs/promises'); +const path = require('path'); +(async () => { + const imagesNames = await fsPromises.readdir(path.resolve('input')); + const atlasRowSize = 7; + const atlasRows = Math.ceil(imagesNames.length / atlasRowSize); + // Each image has a size of 40x30 + const atlas = sharp({ + create: { + width: 40 * atlasRowSize, + height: 30 * atlasRows, + channels: 4, + background: { r: 0, g: 0, b: 0, alpha: 0 } + } + }).composite( + imagesNames.map((imageName, index) => ({ + input: path.resolve(`input/${imageName}`), + left: 40 * (index % atlasRowSize), + top: 30 * Math.floor(index / atlasRowSize) + })) + ); + await atlas.png().toFile(path.resolve('output/atlas.png')); +})(); +``` diff --git a/public/misc/country-flags/atlas.png b/public/misc/country-flags/atlas.png new file mode 100644 index 000000000..2b5a644c9 Binary files /dev/null and b/public/misc/country-flags/atlas.png differ diff --git a/public/misc/country-flags/cn.png b/public/misc/country-flags/cn.png deleted file mode 100644 index 0093d23d4..000000000 Binary files a/public/misc/country-flags/cn.png and /dev/null differ diff --git a/public/misc/country-flags/de.png b/public/misc/country-flags/de.png deleted file mode 100644 index 798ef00c9..000000000 Binary files a/public/misc/country-flags/de.png and /dev/null differ diff --git a/public/misc/country-flags/fr.png b/public/misc/country-flags/fr.png deleted file mode 100644 index f41e5c283..000000000 Binary files a/public/misc/country-flags/fr.png and /dev/null differ diff --git a/public/misc/country-flags/gb.png b/public/misc/country-flags/gb.png deleted file mode 100644 index 68a19e508..000000000 Binary files a/public/misc/country-flags/gb.png and /dev/null differ diff --git a/public/misc/country-flags/jp.png b/public/misc/country-flags/jp.png deleted file mode 100644 index de0bf28ae..000000000 Binary files a/public/misc/country-flags/jp.png and /dev/null differ diff --git a/public/misc/country-flags/kr.png b/public/misc/country-flags/kr.png deleted file mode 100644 index f865eaf0d..000000000 Binary files a/public/misc/country-flags/kr.png and /dev/null differ diff --git a/public/misc/country-flags/pt.png b/public/misc/country-flags/pt.png deleted file mode 100644 index 32ad7b867..000000000 Binary files a/public/misc/country-flags/pt.png and /dev/null differ diff --git a/public/misc/country-flags/tr.png b/public/misc/country-flags/tr.png deleted file mode 100644 index 2c762410b..000000000 Binary files a/public/misc/country-flags/tr.png and /dev/null differ diff --git a/public/misc/country-flags/tw.png b/public/misc/country-flags/tw.png deleted file mode 100644 index 6e99b3c8a..000000000 Binary files a/public/misc/country-flags/tw.png and /dev/null differ diff --git a/public/misc/country-flags/ua.png b/public/misc/country-flags/ua.png deleted file mode 100644 index 044d48a2f..000000000 Binary files a/public/misc/country-flags/ua.png and /dev/null differ diff --git a/public/misc/country-flags/us.png b/public/misc/country-flags/us.png deleted file mode 100644 index efc8a09e6..000000000 Binary files a/public/misc/country-flags/us.png and /dev/null differ diff --git a/src/app/atoms/Flag.tsx b/src/app/atoms/Flag.tsx index 9e30951ea..6a31863ef 100644 --- a/src/app/atoms/Flag.tsx +++ b/src/app/atoms/Flag.tsx @@ -1,25 +1,122 @@ -import React, { HTMLAttributes, memo, useCallback, useState } from 'react'; +import React, { HTMLAttributes, memo, useCallback, useMemo, useState } from 'react'; import classNames from 'clsx'; +import browser from 'webextension-polyfill'; -type FlagProps = { +const atlasCountriesCodes = [ + 'ae', + 'ar', + 'au', + 'az', + 'bg', + 'bh', + 'br', + 'ca', + 'ch', + 'cl', + 'cn', + 'co', + 'cr', + 'cz', + 'de', + 'dk', + 'do', + 'eg', + 'eu', + 'fr', + 'gb', + 'ge', + 'gt', + 'hk', + 'hn', + 'hr', + 'hu', + 'id', + 'il', + 'in', + 'jo', + 'jp', + 'kn', + 'kr', + 'kw', + 'kz', + 'lk', + 'md', + 'mx', + 'my', + 'ng', + 'no', + 'nz', + 'om', + 'pe', + 'ph', + 'pl', + 'pt', + 'py', + 'qa', + 'ro', + 'rw', + 'sa', + 'se', + 'th', + 'tr', + 'tw', + 'ua', + 'us', + 'uy', + 'vn', + 'za' +]; +const atlasRowSize = 7; +const imageWidth = 40; +const imageHeight = 30; + +export const canUseAtlasFlag = (countryCode: string) => atlasCountriesCodes.includes(countryCode); + +interface FlagProps { alt: string; + countryCode?: string; className?: string; src?: string; -}; +} -const Flag = memo(({ alt, className, src }) => { +export const Flag = memo(({ alt, className, countryCode, src }) => { const [error, setError] = useState(false); + const bgFromAtlasStyle = useMemo(() => { + if (src || !countryCode) { + return undefined; + } + + const index = atlasCountriesCodes.indexOf(countryCode); + + if (index === -1) { + return undefined; + } + + const row = Math.floor(index / atlasRowSize); + const col = index % atlasRowSize; + + return { + backgroundImage: `url(${browser.runtime.getURL('/misc/country-flags/atlas.png')})`, + backgroundPosition: `${-(col * imageWidth) / 2}px ${-(row * imageHeight) / 2}px`, + backgroundSize: `${atlasRowSize * 1.25}rem` + }; + }, [countryCode, src]); + const handleError = useCallback(() => { setError(true); }, [setError]); return (
- {src ? ( + {src || bgFromAtlasStyle ? ( <> - {alt} + {src ? ( + {alt} + ) : ( +
+ )} {error && } ) : ( @@ -29,8 +126,6 @@ const Flag = memo(({ alt, className, src }) => { ); }); -export default Flag; - const FlagStub = memo((props: HTMLAttributes) => ( >(({ option: { flagName, code } }) => ( - + ));