mirror of
				https://github.com/karl0ss/homepage.git
				synced 2025-11-04 08:20:58 +00:00 
			
		
		
		
	refactor i18n to be server side
This commit is contained in:
		
							parent
							
								
									3ae4113043
								
							
						
					
					
						commit
						8bc240b934
					
				
							
								
								
									
										143
									
								
								next-i18next.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								next-i18next.config.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,143 @@
 | 
				
			|||||||
 | 
					// prettyBytes taken from https://github.com/sindresorhus/pretty-bytes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* eslint-disable no-param-reassign */
 | 
				
			||||||
 | 
					const BYTE_UNITS = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const BIBYTE_UNITS = ["B", "kiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const BIT_UNITS = ["b", "kbit", "Mbit", "Gbit", "Tbit", "Pbit", "Ebit", "Zbit", "Ybit"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const BIBIT_UNITS = ["b", "kibit", "Mibit", "Gibit", "Tibit", "Pibit", "Eibit", "Zibit", "Yibit"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					Formats the given number using `Number#toLocaleString`.
 | 
				
			||||||
 | 
					- If locale is a string, the value is expected to be a locale-key (for example: `de`).
 | 
				
			||||||
 | 
					- If locale is true, the system default locale is used for translation.
 | 
				
			||||||
 | 
					- If no value for locale is specified, the number is returned unmodified.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					const toLocaleString = (number, locale, options) => {
 | 
				
			||||||
 | 
					  let result = number;
 | 
				
			||||||
 | 
					  if (typeof locale === "string" || Array.isArray(locale)) {
 | 
				
			||||||
 | 
					    result = number.toLocaleString(locale, options);
 | 
				
			||||||
 | 
					  } else if (locale === true || options !== undefined) {
 | 
				
			||||||
 | 
					    result = number.toLocaleString(undefined, options);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function prettyBytes(number, options) {
 | 
				
			||||||
 | 
					  if (!Number.isFinite(number)) {
 | 
				
			||||||
 | 
					    throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  options = {
 | 
				
			||||||
 | 
					    bits: false,
 | 
				
			||||||
 | 
					    binary: false,
 | 
				
			||||||
 | 
					    ...options,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // eslint-disable-next-line no-nested-ternary
 | 
				
			||||||
 | 
					  const UNITS = options.bits ? (options.binary ? BIBIT_UNITS : BIT_UNITS) : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (options.signed && number === 0) {
 | 
				
			||||||
 | 
					    return ` 0 ${UNITS[0]}`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const isNegative = number < 0;
 | 
				
			||||||
 | 
					  // eslint-disable-next-line no-nested-ternary
 | 
				
			||||||
 | 
					  const prefix = isNegative ? "-" : options.signed ? "+" : "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (isNegative) {
 | 
				
			||||||
 | 
					    number = -number;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let localeOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (options.minimumFractionDigits !== undefined) {
 | 
				
			||||||
 | 
					    localeOptions = { minimumFractionDigits: options.minimumFractionDigits };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (options.maximumFractionDigits !== undefined) {
 | 
				
			||||||
 | 
					    localeOptions = { maximumFractionDigits: options.maximumFractionDigits, ...localeOptions };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (number < 1) {
 | 
				
			||||||
 | 
					    const numberString = toLocaleString(number, options.locale, localeOptions);
 | 
				
			||||||
 | 
					    return `${prefix + numberString} ${UNITS[0]}`;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const exponent = Math.min(
 | 
				
			||||||
 | 
					    Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3),
 | 
				
			||||||
 | 
					    UNITS.length - 1
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  number /= (options.binary ? 1024 : 1000) ** exponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!localeOptions) {
 | 
				
			||||||
 | 
					    number = number.toPrecision(3);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const numberString = toLocaleString(Number(number), options.locale, localeOptions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const unit = UNITS[exponent];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return `${prefix + numberString} ${unit}`;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
					  i18n: {
 | 
				
			||||||
 | 
					    defaultLocale: "en",
 | 
				
			||||||
 | 
					    locales: [
 | 
				
			||||||
 | 
					      "en",
 | 
				
			||||||
 | 
					      "ca",
 | 
				
			||||||
 | 
					      "de",
 | 
				
			||||||
 | 
					      "es",
 | 
				
			||||||
 | 
					      "fr",
 | 
				
			||||||
 | 
					      "he",
 | 
				
			||||||
 | 
					      "hr",
 | 
				
			||||||
 | 
					      "hu",
 | 
				
			||||||
 | 
					      "it",
 | 
				
			||||||
 | 
					      "nb-NO",
 | 
				
			||||||
 | 
					      "nl",
 | 
				
			||||||
 | 
					      "pl",
 | 
				
			||||||
 | 
					      "pt",
 | 
				
			||||||
 | 
					      "ro",
 | 
				
			||||||
 | 
					      "ru",
 | 
				
			||||||
 | 
					      "sv",
 | 
				
			||||||
 | 
					      "vi",
 | 
				
			||||||
 | 
					      "zh-CN",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  serializeConfig: false,
 | 
				
			||||||
 | 
					  use: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      init: (i18next) => {
 | 
				
			||||||
 | 
					        i18next.services.formatter.add("bytes", (value, lng, options) =>
 | 
				
			||||||
 | 
					          prettyBytes(parseFloat(value), { locale: lng, ...options })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i18next.services.formatter.add("rate", (value, lng, options) => {
 | 
				
			||||||
 | 
					          if (value === 0) return "0 Bps";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          const bits = options.bits ? value : value / 8;
 | 
				
			||||||
 | 
					          const k = 1024;
 | 
				
			||||||
 | 
					          const dm = options.decimals ? options.decimals : 0;
 | 
				
			||||||
 | 
					          const sizes = ["Bps", "Kbps", "Mbps", "Gbps", "Tbps", "Pbps", "Ebps", "Zbps", "Ybps"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          const i = Math.floor(Math.log(bits) / Math.log(k));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          const formatted = new Intl.NumberFormat(lng, { maximumFractionDigits: dm, minimumFractionDigits: dm }).format(
 | 
				
			||||||
 | 
					            parseFloat(bits / k ** i)
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          return `${formatted} ${sizes[i]}`;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        i18next.services.formatter.add("percent", (value, lng, options) =>
 | 
				
			||||||
 | 
					          new Intl.NumberFormat(lng, { style: "percent", ...options }).format(parseFloat(value) / 100.0)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      type: "3rdParty",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					const { i18n } = require("./next-i18next.config");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** @type {import('next').NextConfig} */
 | 
					/** @type {import('next').NextConfig} */
 | 
				
			||||||
const nextConfig = {
 | 
					const nextConfig = {
 | 
				
			||||||
  reactStrictMode: true,
 | 
					  reactStrictMode: true,
 | 
				
			||||||
@ -7,6 +9,7 @@ const nextConfig = {
 | 
				
			|||||||
    domains: ["cdn.jsdelivr.net"],
 | 
					    domains: ["cdn.jsdelivr.net"],
 | 
				
			||||||
    unoptimized: true,
 | 
					    unoptimized: true,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  i18n,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = nextConfig;
 | 
					module.exports = nextConfig;
 | 
				
			||||||
 | 
				
			|||||||
@ -15,20 +15,19 @@
 | 
				
			|||||||
    "compare-versions": "^5.0.1",
 | 
					    "compare-versions": "^5.0.1",
 | 
				
			||||||
    "dockerode": "^3.3.4",
 | 
					    "dockerode": "^3.3.4",
 | 
				
			||||||
    "follow-redirects": "^1.15.2",
 | 
					    "follow-redirects": "^1.15.2",
 | 
				
			||||||
    "i18next-browser-languagedetector": "^6.1.5",
 | 
					 | 
				
			||||||
    "i18next-http-backend": "^1.4.4",
 | 
					 | 
				
			||||||
    "i18next": "^21.9.2",
 | 
					    "i18next": "^21.9.2",
 | 
				
			||||||
    "js-yaml": "^4.1.0",
 | 
					    "js-yaml": "^4.1.0",
 | 
				
			||||||
    "json-rpc-2.0": "^1.4.1",
 | 
					    "json-rpc-2.0": "^1.4.1",
 | 
				
			||||||
    "memory-cache": "^0.2.0",
 | 
					    "memory-cache": "^0.2.0",
 | 
				
			||||||
    "next": "^12.3.1",
 | 
					    "next": "^12.3.1",
 | 
				
			||||||
 | 
					    "next-i18next": "^12.0.1",
 | 
				
			||||||
    "node-os-utils": "^1.3.7",
 | 
					    "node-os-utils": "^1.3.7",
 | 
				
			||||||
    "pretty-bytes": "^6.0.0",
 | 
					    "pretty-bytes": "^6.0.0",
 | 
				
			||||||
    "raw-body": "^2.5.1",
 | 
					    "raw-body": "^2.5.1",
 | 
				
			||||||
 | 
					    "react": "^18.2.0",
 | 
				
			||||||
    "react-dom": "^18.2.0",
 | 
					    "react-dom": "^18.2.0",
 | 
				
			||||||
    "react-i18next": "^11.18.6",
 | 
					    "react-i18next": "^11.18.6",
 | 
				
			||||||
    "react-icons": "^4.4.0",
 | 
					    "react-icons": "^4.4.0",
 | 
				
			||||||
    "react": "^18.2.0",
 | 
					 | 
				
			||||||
    "rutorrent-promise": "^2.0.0",
 | 
					    "rutorrent-promise": "^2.0.0",
 | 
				
			||||||
    "shvl": "^3.0.0",
 | 
					    "shvl": "^3.0.0",
 | 
				
			||||||
    "swr": "^1.3.0",
 | 
					    "swr": "^1.3.0",
 | 
				
			||||||
@ -38,15 +37,15 @@
 | 
				
			|||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@tailwindcss/forms": "^0.5.3",
 | 
					    "@tailwindcss/forms": "^0.5.3",
 | 
				
			||||||
    "autoprefixer": "^10.4.12",
 | 
					    "autoprefixer": "^10.4.12",
 | 
				
			||||||
 | 
					    "eslint": "^8.24.0",
 | 
				
			||||||
    "eslint-config-airbnb": "^19.0.4",
 | 
					    "eslint-config-airbnb": "^19.0.4",
 | 
				
			||||||
    "eslint-config-next": "^12.3.1",
 | 
					    "eslint-config-next": "^12.3.1",
 | 
				
			||||||
    "eslint-config-prettier": "^8.5.0",
 | 
					    "eslint-config-prettier": "^8.5.0",
 | 
				
			||||||
    "eslint-plugin-import": "^2.26.0",
 | 
					    "eslint-plugin-import": "^2.26.0",
 | 
				
			||||||
    "eslint-plugin-jsx-a11y": "^6.6.1",
 | 
					    "eslint-plugin-jsx-a11y": "^6.6.1",
 | 
				
			||||||
    "eslint-plugin-prettier": "^4.2.1",
 | 
					    "eslint-plugin-prettier": "^4.2.1",
 | 
				
			||||||
    "eslint-plugin-react-hooks": "^4.6.0",
 | 
					 | 
				
			||||||
    "eslint-plugin-react": "^7.31.8",
 | 
					    "eslint-plugin-react": "^7.31.8",
 | 
				
			||||||
    "eslint": "^8.24.0",
 | 
					    "eslint-plugin-react-hooks": "^4.6.0",
 | 
				
			||||||
    "postcss": "^8.4.16",
 | 
					    "postcss": "^8.4.16",
 | 
				
			||||||
    "prettier": "^2.7.1",
 | 
					    "prettier": "^2.7.1",
 | 
				
			||||||
    "tailwind-scrollbar": "^2.0.1",
 | 
					    "tailwind-scrollbar": "^2.0.1",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										88
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										88
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@ -18,12 +18,11 @@ specifiers:
 | 
				
			|||||||
  eslint-plugin-react-hooks: ^4.6.0
 | 
					  eslint-plugin-react-hooks: ^4.6.0
 | 
				
			||||||
  follow-redirects: ^1.15.2
 | 
					  follow-redirects: ^1.15.2
 | 
				
			||||||
  i18next: ^21.9.2
 | 
					  i18next: ^21.9.2
 | 
				
			||||||
  i18next-browser-languagedetector: ^6.1.5
 | 
					 | 
				
			||||||
  i18next-http-backend: ^1.4.4
 | 
					 | 
				
			||||||
  js-yaml: ^4.1.0
 | 
					  js-yaml: ^4.1.0
 | 
				
			||||||
  json-rpc-2.0: ^1.4.1
 | 
					  json-rpc-2.0: ^1.4.1
 | 
				
			||||||
  memory-cache: ^0.2.0
 | 
					  memory-cache: ^0.2.0
 | 
				
			||||||
  next: ^12.3.1
 | 
					  next: ^12.3.1
 | 
				
			||||||
 | 
					  next-i18next: ^12.0.1
 | 
				
			||||||
  node-os-utils: ^1.3.7
 | 
					  node-os-utils: ^1.3.7
 | 
				
			||||||
  postcss: ^8.4.16
 | 
					  postcss: ^8.4.16
 | 
				
			||||||
  prettier: ^2.7.1
 | 
					  prettier: ^2.7.1
 | 
				
			||||||
@ -49,12 +48,11 @@ dependencies:
 | 
				
			|||||||
  dockerode: 3.3.4
 | 
					  dockerode: 3.3.4
 | 
				
			||||||
  follow-redirects: 1.15.2
 | 
					  follow-redirects: 1.15.2
 | 
				
			||||||
  i18next: 21.9.2
 | 
					  i18next: 21.9.2
 | 
				
			||||||
  i18next-browser-languagedetector: 6.1.5
 | 
					 | 
				
			||||||
  i18next-http-backend: 1.4.4
 | 
					 | 
				
			||||||
  js-yaml: 4.1.0
 | 
					  js-yaml: 4.1.0
 | 
				
			||||||
  json-rpc-2.0: 1.4.1
 | 
					  json-rpc-2.0: 1.4.1
 | 
				
			||||||
  memory-cache: 0.2.0
 | 
					  memory-cache: 0.2.0
 | 
				
			||||||
  next: 12.3.1_biqbaboplfbrettd7655fr4n2y
 | 
					  next: 12.3.1_biqbaboplfbrettd7655fr4n2y
 | 
				
			||||||
 | 
					  next-i18next: 12.0.1_azq6kxkn3od7qdylwkyksrwopy
 | 
				
			||||||
  node-os-utils: 1.3.7
 | 
					  node-os-utils: 1.3.7
 | 
				
			||||||
  pretty-bytes: 6.0.0
 | 
					  pretty-bytes: 6.0.0
 | 
				
			||||||
  raw-body: 2.5.1
 | 
					  raw-body: 2.5.1
 | 
				
			||||||
@ -338,10 +336,33 @@ packages:
 | 
				
			|||||||
      tailwindcss: 3.1.8_postcss@8.4.16
 | 
					      tailwindcss: 3.1.8_postcss@8.4.16
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /@types/hoist-non-react-statics/3.3.1:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      '@types/react': 18.0.21
 | 
				
			||||||
 | 
					      hoist-non-react-statics: 3.3.2
 | 
				
			||||||
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /@types/json5/0.0.29:
 | 
					  /@types/json5/0.0.29:
 | 
				
			||||||
    resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
 | 
					    resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /@types/prop-types/15.7.5:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
 | 
				
			||||||
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /@types/react/18.0.21:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA==}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      '@types/prop-types': 15.7.5
 | 
				
			||||||
 | 
					      '@types/scheduler': 0.16.2
 | 
				
			||||||
 | 
					      csstype: 3.1.1
 | 
				
			||||||
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /@types/scheduler/0.16.2:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
 | 
				
			||||||
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /@typescript-eslint/parser/5.38.0_7ilbxdl5iguzcjriqqcg2m5cku:
 | 
					  /@typescript-eslint/parser/5.38.0_7ilbxdl5iguzcjriqqcg2m5cku:
 | 
				
			||||||
    resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==}
 | 
					    resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==}
 | 
				
			||||||
    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 | 
					    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 | 
				
			||||||
@ -746,6 +767,11 @@ packages:
 | 
				
			|||||||
    requiresBuild: true
 | 
					    requiresBuild: true
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /core-js/3.25.2:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-YB4IAT1bjEfxTJ1XYy11hJAKskO+qmhuDBM8/guIfMz4JvdsAQAqvyb97zXX7JgSrfPLG5mRGFWJwJD39ruq2A==}
 | 
				
			||||||
 | 
					    requiresBuild: true
 | 
				
			||||||
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /cpu-features/0.0.4:
 | 
					  /cpu-features/0.0.4:
 | 
				
			||||||
    resolution: {integrity: sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==}
 | 
					    resolution: {integrity: sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A==}
 | 
				
			||||||
    engines: {node: '>=10.0.0'}
 | 
					    engines: {node: '>=10.0.0'}
 | 
				
			||||||
@ -756,14 +782,6 @@ packages:
 | 
				
			|||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
    optional: true
 | 
					    optional: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /cross-fetch/3.1.5:
 | 
					 | 
				
			||||||
    resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
 | 
					 | 
				
			||||||
    dependencies:
 | 
					 | 
				
			||||||
      node-fetch: 2.6.7
 | 
					 | 
				
			||||||
    transitivePeerDependencies:
 | 
					 | 
				
			||||||
      - encoding
 | 
					 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /cross-spawn/7.0.3:
 | 
					  /cross-spawn/7.0.3:
 | 
				
			||||||
    resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
 | 
					    resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
 | 
				
			||||||
    engines: {node: '>= 8'}
 | 
					    engines: {node: '>= 8'}
 | 
				
			||||||
@ -779,6 +797,10 @@ packages:
 | 
				
			|||||||
    hasBin: true
 | 
					    hasBin: true
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /csstype/3.1.1:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
 | 
				
			||||||
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /damerau-levenshtein/1.0.8:
 | 
					  /damerau-levenshtein/1.0.8:
 | 
				
			||||||
    resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
 | 
					    resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
@ -1613,6 +1635,12 @@ packages:
 | 
				
			|||||||
      function-bind: 1.1.1
 | 
					      function-bind: 1.1.1
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /hoist-non-react-statics/3.3.2:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      react-is: 16.13.1
 | 
				
			||||||
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /html-parse-stringify/3.0.1:
 | 
					  /html-parse-stringify/3.0.1:
 | 
				
			||||||
    resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
 | 
					    resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==}
 | 
				
			||||||
    dependencies:
 | 
					    dependencies:
 | 
				
			||||||
@ -1630,18 +1658,8 @@ packages:
 | 
				
			|||||||
      toidentifier: 1.0.1
 | 
					      toidentifier: 1.0.1
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /i18next-browser-languagedetector/6.1.5:
 | 
					  /i18next-fs-backend/1.1.5:
 | 
				
			||||||
    resolution: {integrity: sha512-11t7b39oKeZe4uyMxLSPnfw28BCPNLZgUk7zyufex0zKXZ+Bv+JnmJgoB+IfQLZwDt1d71PM8vwBX1NCgliY3g==}
 | 
					    resolution: {integrity: sha512-raTel3EfshiUXxR0gvmIoqp75jhkj8+7R1LjB006VZKPTFBbXyx6TlUVhb8Z9+7ahgpFbcQg1QWVOdf/iNzI5A==}
 | 
				
			||||||
    dependencies:
 | 
					 | 
				
			||||||
      '@babel/runtime': 7.19.0
 | 
					 | 
				
			||||||
    dev: false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /i18next-http-backend/1.4.4:
 | 
					 | 
				
			||||||
    resolution: {integrity: sha512-M4gLPe6JKZ2p1UmE6t4rzWV/sAxgrLThW7ztXAsTpFwFqXoyzhTzX8eYxVv9KjpCQh4K9nwxnEjEi+74C4Thbg==}
 | 
					 | 
				
			||||||
    dependencies:
 | 
					 | 
				
			||||||
      cross-fetch: 3.1.5
 | 
					 | 
				
			||||||
    transitivePeerDependencies:
 | 
					 | 
				
			||||||
      - encoding
 | 
					 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /i18next/21.9.2:
 | 
					  /i18next/21.9.2:
 | 
				
			||||||
@ -1986,6 +2004,27 @@ packages:
 | 
				
			|||||||
    resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
 | 
					    resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
 | 
				
			||||||
    dev: true
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /next-i18next/12.0.1_azq6kxkn3od7qdylwkyksrwopy:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-i1yLpOvokldjqnnkP4KfZtnbp2+DILlUvavzJ9rvCSu1Yk5w45IRAYrJfu20/0WDeWxea/ktYDmXw+z/2roo3g==}
 | 
				
			||||||
 | 
					    engines: {node: '>=12'}
 | 
				
			||||||
 | 
					    peerDependencies:
 | 
				
			||||||
 | 
					      next: '>= 10.0.0'
 | 
				
			||||||
 | 
					      react: '>= 16.8.0'
 | 
				
			||||||
 | 
					    dependencies:
 | 
				
			||||||
 | 
					      '@babel/runtime': 7.19.0
 | 
				
			||||||
 | 
					      '@types/hoist-non-react-statics': 3.3.1
 | 
				
			||||||
 | 
					      core-js: 3.25.2
 | 
				
			||||||
 | 
					      hoist-non-react-statics: 3.3.2
 | 
				
			||||||
 | 
					      i18next: 21.9.2
 | 
				
			||||||
 | 
					      i18next-fs-backend: 1.1.5
 | 
				
			||||||
 | 
					      next: 12.3.1_biqbaboplfbrettd7655fr4n2y
 | 
				
			||||||
 | 
					      react: 18.2.0
 | 
				
			||||||
 | 
					      react-i18next: 11.18.6_ulhmqqxshznzmtuvahdi5nasbq
 | 
				
			||||||
 | 
					    transitivePeerDependencies:
 | 
				
			||||||
 | 
					      - react-dom
 | 
				
			||||||
 | 
					      - react-native
 | 
				
			||||||
 | 
					    dev: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /next/12.3.1_biqbaboplfbrettd7655fr4n2y:
 | 
					  /next/12.3.1_biqbaboplfbrettd7655fr4n2y:
 | 
				
			||||||
    resolution: {integrity: sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==}
 | 
					    resolution: {integrity: sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==}
 | 
				
			||||||
    engines: {node: '>=12.22.0'}
 | 
					    engines: {node: '>=12.22.0'}
 | 
				
			||||||
@ -2393,7 +2432,6 @@ packages:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /react-is/16.13.1:
 | 
					  /react-is/16.13.1:
 | 
				
			||||||
    resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
 | 
					    resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
 | 
				
			||||||
    dev: true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /react/18.2.0:
 | 
					  /react/18.2.0:
 | 
				
			||||||
    resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
 | 
					    resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { useTranslation } from "react-i18next";
 | 
					 | 
				
			||||||
import dynamic from "next/dynamic";
 | 
					import dynamic from "next/dynamic";
 | 
				
			||||||
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Sonarr = dynamic(() => import("./widgets/service/sonarr"));
 | 
					const Sonarr = dynamic(() => import("./widgets/service/sonarr"));
 | 
				
			||||||
const Radarr = dynamic(() => import("./widgets/service/radarr"));
 | 
					const Radarr = dynamic(() => import("./widgets/service/radarr"));
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useState } from "react";
 | 
					import { useState } from "react";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
import classNames from "classnames";
 | 
					import classNames from "classnames";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
import { BsVolumeMuteFill, BsFillPlayFill, BsPauseFill, BsCpu, BsFillCpuFill } from "react-icons/bs";
 | 
					import { BsVolumeMuteFill, BsFillPlayFill, BsPauseFill, BsCpu, BsFillCpuFill } from "react-icons/bs";
 | 
				
			||||||
import { MdOutlineSmartDisplay } from "react-icons/md";
 | 
					import { MdOutlineSmartDisplay } from "react-icons/md";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,9 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { formatApiUrl } from "utils/api-helpers";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Radarr({ service }) {
 | 
					export default function Radarr({ service }) {
 | 
				
			||||||
  const { t } = useTranslation();
 | 
					  const { t } = useTranslation();
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
/* eslint-disable camelcase */
 | 
					/* eslint-disable camelcase */
 | 
				
			||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
import { BsFillPlayFill, BsPauseFill, BsCpu, BsFillCpuFill } from "react-icons/bs";
 | 
					import { BsFillPlayFill, BsPauseFill, BsCpu, BsFillCpuFill } from "react-icons/bs";
 | 
				
			||||||
import { MdOutlineSmartDisplay, MdSmartDisplay } from "react-icons/md";
 | 
					import { MdOutlineSmartDisplay, MdSmartDisplay } from "react-icons/md";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Widget from "../widget";
 | 
					import Widget from "../widget";
 | 
				
			||||||
import Block from "../block";
 | 
					import Block from "../block";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { compareVersions } from "compare-versions";
 | 
					import { compareVersions } from "compare-versions";
 | 
				
			||||||
import { MdNewReleases } from "react-icons/md";
 | 
					import { MdNewReleases } from "react-icons/md";
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { useState, useEffect } from "react";
 | 
					import { useState, useEffect } from "react";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const textSizes = {
 | 
					const textSizes = {
 | 
				
			||||||
  "4xl": "text-4xl",
 | 
					  "4xl": "text-4xl",
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ import { useState } from "react";
 | 
				
			|||||||
import { BiError } from "react-icons/bi";
 | 
					import { BiError } from "react-icons/bi";
 | 
				
			||||||
import { WiCloudDown } from "react-icons/wi";
 | 
					import { WiCloudDown } from "react-icons/wi";
 | 
				
			||||||
import { MdLocationDisabled, MdLocationSearching } from "react-icons/md";
 | 
					import { MdLocationDisabled, MdLocationSearching } from "react-icons/md";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Icon from "./icon";
 | 
					import Icon from "./icon";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { FiCpu } from "react-icons/fi";
 | 
					import { FiCpu } from "react-icons/fi";
 | 
				
			||||||
import { BiError } from "react-icons/bi";
 | 
					import { BiError } from "react-icons/bi";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import UsageBar from "./usage-bar";
 | 
					import UsageBar from "./usage-bar";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { FiHardDrive } from "react-icons/fi";
 | 
					import { FiHardDrive } from "react-icons/fi";
 | 
				
			||||||
import { BiError } from "react-icons/bi";
 | 
					import { BiError } from "react-icons/bi";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import UsageBar from "./usage-bar";
 | 
					import UsageBar from "./usage-bar";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import { FaMemory } from "react-icons/fa";
 | 
					import { FaMemory } from "react-icons/fa";
 | 
				
			||||||
import { BiError } from "react-icons/bi";
 | 
					import { BiError } from "react-icons/bi";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import UsageBar from "./usage-bar";
 | 
					import UsageBar from "./usage-bar";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import { useState } from "react";
 | 
					import { useState } from "react";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
import { FiSearch } from "react-icons/fi";
 | 
					import { FiSearch } from "react-icons/fi";
 | 
				
			||||||
import { SiDuckduckgo, SiMicrosoftbing, SiGoogle } from "react-icons/si";
 | 
					import { SiDuckduckgo, SiMicrosoftbing, SiGoogle } from "react-icons/si";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,7 @@ import { useState } from "react";
 | 
				
			|||||||
import { BiError } from "react-icons/bi";
 | 
					import { BiError } from "react-icons/bi";
 | 
				
			||||||
import { WiCloudDown } from "react-icons/wi";
 | 
					import { WiCloudDown } from "react-icons/wi";
 | 
				
			||||||
import { MdLocationDisabled, MdLocationSearching } from "react-icons/md";
 | 
					import { MdLocationDisabled, MdLocationSearching } from "react-icons/md";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Icon from "./icon";
 | 
					import Icon from "./icon";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,12 @@
 | 
				
			|||||||
/* eslint-disable react/jsx-props-no-spreading */
 | 
					/* eslint-disable react/jsx-props-no-spreading */
 | 
				
			||||||
import { SWRConfig } from "swr";
 | 
					import { SWRConfig } from "swr";
 | 
				
			||||||
 | 
					import { appWithTranslation } from "next-i18next";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "styles/globals.css";
 | 
					import "styles/globals.css";
 | 
				
			||||||
import "styles/theme.css";
 | 
					import "styles/theme.css";
 | 
				
			||||||
import "styles/manrope.css";
 | 
					import "styles/manrope.css";
 | 
				
			||||||
 | 
					import nextI18nextConfig from "../../next-i18next.config";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "utils/i18n";
 | 
					 | 
				
			||||||
import { ColorProvider } from "utils/color-context";
 | 
					import { ColorProvider } from "utils/color-context";
 | 
				
			||||||
import { ThemeProvider } from "utils/theme-context";
 | 
					import { ThemeProvider } from "utils/theme-context";
 | 
				
			||||||
import { SettingsProvider } from "utils/settings-context";
 | 
					import { SettingsProvider } from "utils/settings-context";
 | 
				
			||||||
@ -28,4 +29,4 @@ function MyApp({ Component, pageProps }) {
 | 
				
			|||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default MyApp;
 | 
					export default appWithTranslation(MyApp, nextI18nextConfig);
 | 
				
			||||||
 | 
				
			|||||||
@ -2,9 +2,10 @@
 | 
				
			|||||||
import useSWR from "swr";
 | 
					import useSWR from "swr";
 | 
				
			||||||
import Head from "next/head";
 | 
					import Head from "next/head";
 | 
				
			||||||
import dynamic from "next/dynamic";
 | 
					import dynamic from "next/dynamic";
 | 
				
			||||||
import { useTranslation } from "react-i18next";
 | 
					import { useTranslation } from "next-i18next";
 | 
				
			||||||
import { useEffect, useContext } from "react";
 | 
					import { useEffect, useContext } from "react";
 | 
				
			||||||
import { BiError } from "react-icons/bi";
 | 
					import { BiError } from "react-icons/bi";
 | 
				
			||||||
 | 
					import { serverSideTranslations } from "next-i18next/serverSideTranslations";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ServicesGroup from "components/services/group";
 | 
					import ServicesGroup from "components/services/group";
 | 
				
			||||||
import BookmarksGroup from "components/bookmarks/group";
 | 
					import BookmarksGroup from "components/bookmarks/group";
 | 
				
			||||||
@ -30,7 +31,7 @@ const Version = dynamic(() => import("components/version"), {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const rightAlignedWidgets = ["weatherapi", "openweathermap", "weather", "search", "datetime"];
 | 
					const rightAlignedWidgets = ["weatherapi", "openweathermap", "weather", "search", "datetime"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function getStaticProps() {
 | 
					export async function getStaticProps() {
 | 
				
			||||||
  let logger;
 | 
					  let logger;
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    logger = createLogger("index");
 | 
					    logger = createLogger("index");
 | 
				
			||||||
@ -39,6 +40,7 @@ export function getStaticProps() {
 | 
				
			|||||||
    return {
 | 
					    return {
 | 
				
			||||||
      props: {
 | 
					      props: {
 | 
				
			||||||
        initialSettings: settings,
 | 
					        initialSettings: settings,
 | 
				
			||||||
 | 
					        ...(await serverSideTranslations(settings.language ?? "en")),
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  } catch (e) {
 | 
					  } catch (e) {
 | 
				
			||||||
@ -48,6 +50,7 @@ export function getStaticProps() {
 | 
				
			|||||||
    return {
 | 
					    return {
 | 
				
			||||||
      props: {
 | 
					      props: {
 | 
				
			||||||
        initialSettings: {},
 | 
					        initialSettings: {},
 | 
				
			||||||
 | 
					        ...(await serverSideTranslations("en")),
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,50 +0,0 @@
 | 
				
			|||||||
import i18n from "i18next";
 | 
					 | 
				
			||||||
import { initReactI18next } from "react-i18next";
 | 
					 | 
				
			||||||
import Backend from "i18next-http-backend";
 | 
					 | 
				
			||||||
import LanguageDetector from "i18next-browser-languagedetector";
 | 
					 | 
				
			||||||
import prettyBytes from "pretty-bytes";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
i18n
 | 
					 | 
				
			||||||
  .use(Backend)
 | 
					 | 
				
			||||||
  .use(LanguageDetector)
 | 
					 | 
				
			||||||
  .use(initReactI18next)
 | 
					 | 
				
			||||||
  .init({
 | 
					 | 
				
			||||||
    fallbackLng: "en",
 | 
					 | 
				
			||||||
    ns: ["common"],
 | 
					 | 
				
			||||||
    // debug: process.env.NODE_ENV === "development",
 | 
					 | 
				
			||||||
    defaultNS: "common",
 | 
					 | 
				
			||||||
    nonExplicitSupportedLngs: true,
 | 
					 | 
				
			||||||
    interpolation: {
 | 
					 | 
				
			||||||
      escapeValue: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    backend: {
 | 
					 | 
				
			||||||
      loadPath: "/locales/{{lng}}/{{ns}}.json",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
i18n.services.formatter.add("bytes", (value, lng, options) =>
 | 
					 | 
				
			||||||
  prettyBytes(parseFloat(value), { locale: lng, ...options })
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
i18n.services.formatter.add("rate", (value, lng, options) => {
 | 
					 | 
				
			||||||
  if (value === 0) return "0 Bps";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const bits = options.bits ? value : value / 8;
 | 
					 | 
				
			||||||
  const k = 1024;
 | 
					 | 
				
			||||||
  const dm = options.decimals ? options.decimals : 0;
 | 
					 | 
				
			||||||
  const sizes = ["Bps", "Kbps", "Mbps", "Gbps", "Tbps", "Pbps", "Ebps", "Zbps", "Ybps"];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const i = Math.floor(Math.log(bits) / Math.log(k));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const formatted = new Intl.NumberFormat(lng, { maximumFractionDigits: dm, minimumFractionDigits: dm }).format(
 | 
					 | 
				
			||||||
    parseFloat(bits / k ** i)
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return `${formatted} ${sizes[i]}`;
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
i18n.services.formatter.add("percent", (value, lng, options) =>
 | 
					 | 
				
			||||||
  new Intl.NumberFormat(lng, { style: "percent", ...options }).format(parseFloat(value) / 100.0)
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default i18n;
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user