[Refactoring] Implement own localization provider (#4631)

This commit is contained in:
zubiden 2024-06-18 16:30:25 +02:00 committed by Alexander Zinchuk
parent 9caa5d3198
commit 9d2a928968
424 changed files with 5331 additions and 945 deletions

View File

@ -0,0 +1,19 @@
import { writeFileSync } from 'fs';
import initialKeys from '../src/assets/localization/initialKeys';
import readFallbackStrings from '../src/util/data/readFallbackStrings';
import { pick } from '../src/util/iteratees';
const HEADER = `/* eslint-disable */
// This file is generated by dev/generateInitialLangFallback.ts. Do not edit it manually.\n`;
async function main() {
const data = await readFallbackStrings(true);
const selectedKeys = pick(data.langPack.strings, initialKeys);
const json = JSON.stringify(selectedKeys, undefined, 2);
const text = `${HEADER}\nexport default ${json} as Record<string, string>;\n`;
writeFileSync('./src/assets/localization/initialStrings.ts', text, 'utf8');
}
main();

47
dev/generateLangTypes.ts Normal file
View File

@ -0,0 +1,47 @@
import { readFileSync, writeFileSync } from 'fs';
import readStrings from '../src/util/data/readStrings';
const TOP_COMMENT = '// This file is generated by dev/generateLangTypes.ts. Do not edit it manually.\n';
const LANG_KEY_TYPE = 'export type LangKey = keyof LangPair;';
const data = readFileSync('./src/assets/localization/fallback.strings', 'utf8');
const parsed = readStrings(data);
const keysWithVars = Object.entries(parsed).reduce((acc, [keyWithSuffix, value]) => {
const key = keyWithSuffix.split('_')[0];
const variables = extractVariables(value);
const previousVariables = acc[key] || [];
if (!previousVariables.length) {
acc[key] = variables;
} else {
acc[key] = Array.from(new Set([...previousVariables, ...variables]));
}
return acc;
}, {} as Record<string, string[]>);
let entries = '';
Object.entries(keysWithVars).forEach(([key, variables]) => {
const varString = variables.length
? `{\n ${variables.map((v) => `${wrapInQuotes(v)}: string | number;`).join('\n ')}\n };\n`
: 'undefined;\n';
entries += ` ${wrapInQuotes(key)}: ${varString}`;
});
const langPair = `export interface LangPair {\n${entries}\n}\n`;
const text = `${TOP_COMMENT}\n${langPair}\n${LANG_KEY_TYPE}\n`;
writeFileSync('./src/types/language.d.ts', text, 'utf8');
// eslint-disable-next-line no-console
console.log(`Language types generated: ${Object.keys(keysWithVars).length} keys`);
function extractVariables(value: string) {
const matches = value.match(/(?<!\\){[^{}]+}/g);
if (!matches) return [];
return matches.map((match) => match.slice(1, -1));
}
function wrapInQuotes(value: string) {
return `'${value}'`;
}

447
package-lock.json generated
View File

@ -104,6 +104,7 @@
"stylelint-high-performance-animation": "^1.10.0",
"stylelint-selector-tag-no-without-class": "^3.0.1",
"telegraph-node": "^1.0.4",
"tsx": "^4.11.0",
"typescript": "^5.4.5",
"webpack": "^5.91.0",
"webpack-dev-server": "^5.0.4"
@ -2714,6 +2715,374 @@
"node": "*"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
"integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
"integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
"integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
"integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
"integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
"integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
"integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
"integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
"integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
"integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
"integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
"integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
"integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
"integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
"integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
"integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
"integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
"integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
"integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
"integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
"integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
"integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
"integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@ -10200,6 +10569,44 @@
"dev": true,
"optional": true
},
"node_modules/esbuild": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
"integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.20.2",
"@esbuild/android-arm": "0.20.2",
"@esbuild/android-arm64": "0.20.2",
"@esbuild/android-x64": "0.20.2",
"@esbuild/darwin-arm64": "0.20.2",
"@esbuild/darwin-x64": "0.20.2",
"@esbuild/freebsd-arm64": "0.20.2",
"@esbuild/freebsd-x64": "0.20.2",
"@esbuild/linux-arm": "0.20.2",
"@esbuild/linux-arm64": "0.20.2",
"@esbuild/linux-ia32": "0.20.2",
"@esbuild/linux-loong64": "0.20.2",
"@esbuild/linux-mips64el": "0.20.2",
"@esbuild/linux-ppc64": "0.20.2",
"@esbuild/linux-riscv64": "0.20.2",
"@esbuild/linux-s390x": "0.20.2",
"@esbuild/linux-x64": "0.20.2",
"@esbuild/netbsd-x64": "0.20.2",
"@esbuild/openbsd-x64": "0.20.2",
"@esbuild/sunos-x64": "0.20.2",
"@esbuild/win32-arm64": "0.20.2",
"@esbuild/win32-ia32": "0.20.2",
"@esbuild/win32-x64": "0.20.2"
}
},
"node_modules/escalade": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
@ -12440,6 +12847,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-tsconfig": {
"version": "4.7.5",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz",
"integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==",
"dev": true,
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
"funding": {
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
}
},
"node_modules/git-revision-webpack-plugin": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/git-revision-webpack-plugin/-/git-revision-webpack-plugin-5.0.0.tgz",
@ -19994,6 +20413,15 @@
"node": ">=4"
}
},
"node_modules/resolve-pkg-maps": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
"dev": true,
"funding": {
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
}
},
"node_modules/resolve.exports": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
@ -22438,6 +22866,25 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
"node_modules/tsx": {
"version": "4.11.0",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.11.0.tgz",
"integrity": "sha512-vzGGELOgAupsNVssAmZjbUDfdm/pWP4R+Kg8TVdsonxbXk0bEpE1qh0yV6/QxUVXaVlNemgcPajGdJJ82n3stg==",
"dev": true,
"dependencies": {
"esbuild": "~0.20.2",
"get-tsconfig": "^4.7.5"
},
"bin": {
"tsx": "dist/cli.mjs"
},
"engines": {
"node": ">=18.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
}
},
"node_modules/ttf2eot": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-3.1.0.tgz",

View File

@ -24,6 +24,8 @@
"gramjs:tl": "node ./src/lib/gramjs/tl/generateModules.js",
"gramjs:lint": "eslint src/lib/gramjs --ext .ts,.tsx,.js",
"gramjs:lint:fix": "npm run gramjs:lint -- --fix",
"lang:ts": "tsx ./dev/generateLangTypes.js",
"lang:initial": "tsx ./dev/generateInitialLangFallback.js",
"icons:build": "fantasticon",
"test": "cross-env APP_ENV=test jest --verbose --silent --forceExit",
"test:playwright": "playwright test",
@ -124,6 +126,7 @@
"stylelint-high-performance-animation": "^1.10.0",
"stylelint-selector-tag-no-without-class": "^3.0.1",
"telegraph-node": "^1.0.4",
"tsx": "^4.11.0",
"typescript": "^5.4.5",
"webpack": "^5.91.0",
"webpack-dev-server": "^5.0.4"

View File

@ -7,9 +7,12 @@ function compatTest() {
var hasCssSupports = window.CSS && typeof window.CSS.supports === 'function';
var hasIntl = typeof window.Intl !== 'undefined';
var hasDisplayNames = hasIntl && typeof Intl.DisplayNames !== 'undefined';
var hasPluralRules = hasIntl && typeof Intl.PluralRules !== 'undefined';
var hasListFormat = hasIntl && typeof Intl.ListFormat !== 'undefined';
var hasNumberFormat = hasIntl && typeof Intl.NumberFormat !== 'undefined';
var isCompatible = hasPromise && hasWebSockets && hasWebCrypto && hasObjectFromEntries && hasResizeObserver
&& hasCssSupports && hasDisplayNames;
&& hasCssSupports && hasDisplayNames && hasPluralRules && hasListFormat && hasNumberFormat;
if (isCompatible || (window.localStorage && window.localStorage.getItem('tt-ignore-compat'))) {
window.isCompatTestPassed = true;
@ -25,6 +28,9 @@ function compatTest() {
console.warn('ResizeObserver', hasResizeObserver);
console.warn('CSS.supports', hasCssSupports);
console.warn('Intl.DisplayNames', hasDisplayNames);
console.warn('Intl.PluralRules', hasPluralRules);
console.warn('Intl.ListFormat', hasListFormat);
console.warn('Intl.NumberFormat', hasNumberFormat);
}
// Hardcoded page because server forbids iframe embedding

View File

@ -64,6 +64,7 @@ declare module '*.png';
declare module '*.svg';
declare module '*.tgs';
declare module '*.wasm';
declare module '*.strings';
declare module '*.txt' {
const content: string;

View File

@ -4,12 +4,15 @@ import type { ApiPrivacyKey } from '../../../types';
import type {
ApiChatLink,
ApiCollectionInfo,
ApiConfig, ApiCountry, ApiLangString,
ApiConfig, ApiCountry, ApiLanguage, ApiOldLangString,
ApiPeerColors,
ApiSession, ApiTimezone, ApiUrlAuthResult, ApiWallpaper, ApiWebSession,
LangPackStringValue,
} from '../../types';
import { buildCollectionByCallback, omit, pick } from '../../../util/iteratees';
import {
buildCollectionByCallback, omit, omitUndefined, pick,
} from '../../../util/iteratees';
import { getServerTime } from '../../../util/serverTime';
import { addUserToLocalDb } from '../helpers';
import { omitVirtualClassFields } from './helpers';
@ -225,14 +228,14 @@ export function buildApiConfig(config: GramJs.Config): ApiConfig {
};
}
export function buildLangPack(mtpLangPack: GramJs.LangPackDifference) {
return mtpLangPack.strings.reduce<Record<string, ApiLangString | undefined>>((acc, mtpString) => {
acc[mtpString.key] = buildLangPackString(mtpString);
export function oldBuildLangPack(mtpLangPack: GramJs.LangPackDifference) {
return mtpLangPack.strings.reduce<Record<string, ApiOldLangString | undefined>>((acc, mtpString) => {
acc[mtpString.key] = oldBuildLangPackString(mtpString);
return acc;
}, {});
}
export function buildLangPackString(mtpString: GramJs.TypeLangPackString) {
export function oldBuildLangPackString(mtpString: GramJs.TypeLangPackString) {
return mtpString instanceof GramJs.LangPackString
? mtpString.value
: mtpString instanceof GramJs.LangPackStringPluralized
@ -240,6 +243,55 @@ export function buildLangPackString(mtpString: GramJs.TypeLangPackString) {
: undefined;
}
export function buildLangStrings(strings: GramJs.TypeLangPackString[]) {
const keysToRemove: string[] = [];
const apiStrings = strings.reduce<Record<string, LangPackStringValue>>((acc, mtpString) => {
if (mtpString instanceof GramJs.LangPackStringDeleted) {
keysToRemove.push(mtpString.key);
}
if (mtpString instanceof GramJs.LangPackString) {
acc[mtpString.key] = mtpString.value;
}
if (mtpString instanceof GramJs.LangPackStringPluralized) {
acc[mtpString.key] = omitUndefined({
zero: mtpString.zeroValue,
one: mtpString.oneValue,
two: mtpString.twoValue,
few: mtpString.fewValue,
many: mtpString.manyValue,
other: mtpString.otherValue,
});
}
return acc;
}, {});
return {
keysToRemove,
strings: apiStrings,
};
}
export function buildApiLanguage(lang: GramJs.TypeLangPackLanguage): ApiLanguage {
const {
name, nativeName, langCode, pluralCode, rtl, stringsCount, translatedCount, translationsUrl, beta, official,
} = lang;
return {
name,
nativeName,
langCode,
pluralCode,
isRtl: rtl,
isBeta: beta,
isOfficial: official,
stringsCount,
translatedCount,
translationsUrl,
};
}
function buildApiPeerColorSet(colorSet: GramJs.help.TypePeerColorSet) {
if (colorSet instanceof GramJs.help.PeerColorSet) {
return colorSet.colors.map((color) => `#${color.toString(16).padStart(6, '0')}`);

View File

@ -19,16 +19,19 @@ import { getServerTime } from '../../../util/serverTime';
import { buildAppConfig } from '../apiBuilders/appConfig';
import { buildApiChatFromPreview } from '../apiBuilders/chats';
import { buildApiPhoto, buildPrivacyRules } from '../apiBuilders/common';
import { omitVirtualClassFields } from '../apiBuilders/helpers';
import {
buildApiConfig,
buildApiCountryList,
buildApiLanguage,
buildApiNotifyException,
buildApiPeerColors,
buildApiSession,
buildApiTimezone,
buildApiWallpaper,
buildApiWebSession, buildLangPack, buildLangPackString,
buildApiWebSession,
buildLangStrings,
oldBuildLangPack,
oldBuildLangPackString,
} from '../apiBuilders/misc';
import { getApiChatIdFromMtpPeer } from '../apiBuilders/peers';
import { buildApiUser } from '../apiBuilders/users';
@ -429,6 +432,57 @@ export function updateNotificationSettings(peerType: 'contact' | 'group' | 'broa
}));
}
export async function fetchLangPack({
langPack,
langCode,
}: {
langPack: string;
langCode: string;
}) {
const result = await invokeRequest(new GramJs.langpack.GetLangPack({
langPack,
langCode,
}));
if (!result) {
return undefined;
}
const { strings, keysToRemove } = buildLangStrings(result.strings);
return {
version: result.version,
strings,
keysToRemove,
};
}
export async function fetchLangDifference({
langPack,
langCode,
fromVersion,
}: {
langPack: string;
langCode: string;
fromVersion: number;
}) {
const result = await invokeRequest(new GramJs.langpack.GetDifference({
langPack,
langCode,
fromVersion,
}));
if (!result) {
return undefined;
}
const { strings, keysToRemove } = buildLangStrings(result.strings);
return {
version: result.version,
strings,
keysToRemove,
};
}
export async function fetchLanguages(): Promise<ApiLanguage[] | undefined> {
const result = await invokeRequest(new GramJs.langpack.GetLanguages({
langPack: DEFAULT_LANG_PACK,
@ -437,10 +491,28 @@ export async function fetchLanguages(): Promise<ApiLanguage[] | undefined> {
return undefined;
}
return result.map(omitVirtualClassFields);
return result.map(buildApiLanguage);
}
export async function fetchLangPack({ sourceLangPacks, langCode }: {
export async function fetchLanguage({
langPack,
langCode,
}: {
langPack: string;
langCode: string;
}): Promise<ApiLanguage | undefined> {
const result = await invokeRequest(new GramJs.langpack.GetLanguage({
langPack,
langCode,
}));
if (!result) {
return undefined;
}
return buildApiLanguage(result);
}
export async function oldFetchLangPack({ sourceLangPacks, langCode }: {
sourceLangPacks: typeof LANG_PACKS;
langCode: string;
}) {
@ -451,7 +523,7 @@ export async function fetchLangPack({ sourceLangPacks, langCode }: {
}));
}));
const collections = results.filter(Boolean).map(buildLangPack);
const collections = results.filter(Boolean).map(oldBuildLangPack);
if (!collections.length) {
return undefined;
}
@ -459,7 +531,7 @@ export async function fetchLangPack({ sourceLangPacks, langCode }: {
return { langPack: Object.assign({}, ...collections.reverse()) as typeof collections[0] };
}
export async function fetchLangStrings({ langPack, langCode, keys }: {
export async function oldFetchLangStrings({ langPack, langCode, keys }: {
langPack: string; langCode: string; keys: string[];
}) {
const result = await invokeRequest(new GramJs.langpack.GetStrings({
@ -472,7 +544,7 @@ export async function fetchLangStrings({ langPack, langCode, keys }: {
return undefined;
}
return result.map(buildLangPackString);
return result.map(oldBuildLangPackString);
}
export async function fetchPrivacySettings(privacyKey: ApiPrivacyKey) {

View File

@ -1,7 +1,7 @@
export interface ApiLanguage {
official?: true;
rtl?: true;
beta?: true;
isOfficial?: true;
isRtl?: true;
isBeta?: true;
name: string;
nativeName: string;
langCode: string;
@ -12,7 +12,7 @@ export interface ApiLanguage {
translationsUrl: string;
}
export type ApiLangString = string | {
export type ApiOldLangString = string | {
zeroValue?: string;
oneValue?: string;
twoValue?: string;
@ -21,4 +21,30 @@ export type ApiLangString = string | {
otherValue?: string;
};
export type ApiLangPack = Record<string, ApiLangString | undefined>;
export type ApiOldLangPack = Record<string, ApiOldLangString | undefined>;
export type LangPack = {
langCode: string;
version: number;
strings: Record<string, LangPackStringValue>;
};
export type CachedLangData = {
langPack: LangPack;
language: ApiLanguage;
};
export type LangPackStringValueRegular = string;
export type LangPackStringValueDeleted = {
isDeleted: true;
};
export type LangPackStringValuePlural = {
zero?: string;
one?: string;
two?: string;
few?: string;
many?: string;
other: string;
};
export type LangPackStringValue = LangPackStringValueRegular | LangPackStringValueDeleted | LangPackStringValuePlural;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
const INITIAL_KEYS = [
'WrongNumber',
'SentAppCode',
'LoginJustSentSms',
'LoginHeaderPassword',
'LoginEnterPasswordDescription',
'StartText',
'LoginPhonePlaceholder',
'LoginNext',
'LoginQRLogin',
'LoginQRTitle',
'LoginQRHelp1',
'LoginQRHelp2',
'LoginQR2Help2',
'LoginQRHelp3',
'LoginQRCancel',
'YourName',
'LoginRegisterDesc',
'LoginRegisterFirstNamePlaceholder',
'LoginRegisterLastNamePlaceholder',
'LoginSelectCountryTitle',
'CountryNone',
'PleaseEnterPassword',
];
export default INITIAL_KEYS;

View File

@ -0,0 +1,26 @@
/* eslint-disable */
// This file is generated by dev/generateInitialLangFallback.ts. Do not edit it manually.
export default {
"WrongNumber": "Wrong number?",
"SentAppCode": "We've sent the code to the **Telegram** app on your other device.",
"LoginJustSentSms": "We've sent you a code via SMS. Please enter it above.",
"LoginHeaderPassword": "Enter Password",
"LoginEnterPasswordDescription": "You have Two-Step Verification enabled, so your account is protected with an additional password.",
"StartText": "Please confirm your country codenand enter your phone number.",
"LoginPhonePlaceholder": "Your phone number",
"LoginNext": "Next",
"LoginQRLogin": "Log in by QR Code",
"LoginQRTitle": "Log in to Telegram by QR Code",
"LoginQRHelp1": "Open Telegram on your phone",
"LoginQR2Help2": "Go to **Settings** > **Devices** > **Link Desktop Device**",
"LoginQRHelp3": "Point your phone at this screen to confirm login",
"LoginQRCancel": "Log in by phone Number",
"YourName": "Your Name",
"LoginRegisterDesc": "Enter your name and add a profile photo.",
"LoginRegisterFirstNamePlaceholder": "First Name",
"LoginRegisterLastNamePlaceholder": "Last Name",
"LoginSelectCountryTitle": "Country",
"CountryNone": "Country not found",
"PleaseEnterPassword": "Enter your new password"
} as Record<string, string>;

View File

@ -22,7 +22,7 @@ import useAppLayout from '../hooks/useAppLayout';
import useFlag from '../hooks/useFlag';
import usePrevious from '../hooks/usePrevious';
// import Test from './test/TestSvg';
// import Test from './test/TestLocale';
import Auth from './auth/Auth';
import UiLoader from './common/UiLoader';
import AppInactive from './main/AppInactive';

View File

@ -12,7 +12,7 @@ import { IS_TOUCH_ENV } from '../../util/windowEnvironment';
import renderText from '../common/helpers/renderText';
import useHistoryBack from '../../hooks/useHistoryBack';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import TrackingMonkey from '../common/TrackingMonkey';
import InputText from '../ui/InputText';
@ -34,7 +34,7 @@ const AuthCode: FC<StateProps> = ({
clearAuthError,
} = getActions();
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);

View File

@ -6,7 +6,7 @@ import type { GlobalState } from '../../global/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import PasswordForm from '../common/PasswordForm';
import MonkeyPassword from '../common/PasswordMonkey';
@ -18,7 +18,7 @@ const AuthPassword: FC<StateProps> = ({
}) => {
const { setAuthPassword, clearAuthError } = getActions();
const lang = useLang();
const lang = useOldLang();
const [showPassword, setShowPassword] = useState(false);
const handleChangePasswordVisibility = useCallback((isVisible) => {

View File

@ -13,14 +13,14 @@ import { requestMeasure } from '../../lib/fasterdom/fasterdom';
import { preloadImage } from '../../util/files';
import preloadFonts from '../../util/fonts';
import { pick } from '../../util/iteratees';
import { setLanguage } from '../../util/langProvider';
import { oldSetLanguage } from '../../util/oldLangProvider';
import { formatPhoneNumber, getCountryCodesByIso, getCountryFromPhoneNumber } from '../../util/phoneNumber';
import { IS_SAFARI, IS_TOUCH_ENV } from '../../util/windowEnvironment';
import { getSuggestedLanguage } from './helpers/getSuggestedLanguage';
import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang';
import useLangString from '../../hooks/useLangString';
import useOldLang from '../../hooks/useOldLang';
import useOldLangString from '../../hooks/useOldLangString';
import Button from '../ui/Button';
import Checkbox from '../ui/Checkbox';
@ -66,13 +66,13 @@ const AuthPhoneNumber: FC<StateProps> = ({
setSettingOption,
} = getActions();
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);
const suggestedLanguage = getSuggestedLanguage();
const isConnected = connectionState === 'connectionStateReady';
const continueText = useLangString(isConnected ? suggestedLanguage : undefined, 'ContinueOnThisLanguage', true);
const continueText = useOldLangString(isConnected ? suggestedLanguage : undefined, 'ContinueOnThisLanguage', true);
const [country, setCountry] = useState<ApiCountryCode | undefined>();
const [phoneNumber, setPhoneNumber] = useState<string | undefined>();
const [isTouched, setIsTouched] = useState(false);
@ -129,7 +129,7 @@ const AuthPhoneNumber: FC<StateProps> = ({
const handleLangChange = useCallback(() => {
markIsLoading();
void setLanguage(suggestedLanguage, () => {
void oldSetLanguage(suggestedLanguage, () => {
unmarkIsLoading();
setSettingOption({ language: suggestedLanguage });

View File

@ -10,16 +10,16 @@ import type { LangCode } from '../../types';
import { DEFAULT_LANG_CODE, STRICTERDOM_ENABLED } from '../../config';
import { disableStrict, enableStrict } from '../../lib/fasterdom/stricterdom';
import buildClassName from '../../util/buildClassName';
import { setLanguage } from '../../util/langProvider';
import { oldSetLanguage } from '../../util/oldLangProvider';
import { LOCAL_TGS_URLS } from '../common/helpers/animatedAssets';
import renderText from '../common/helpers/renderText';
import { getSuggestedLanguage } from './helpers/getSuggestedLanguage';
import useAsync from '../../hooks/useAsync';
import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang';
import useLangString from '../../hooks/useLangString';
import useMediaTransition from '../../hooks/useMediaTransition';
import useOldLang from '../../hooks/useOldLang';
import useOldLangString from '../../hooks/useOldLangString';
import AnimatedIcon from '../common/AnimatedIcon';
import Button from '../ui/Button';
@ -57,12 +57,12 @@ const AuthCode: FC<StateProps> = ({
} = getActions();
const suggestedLanguage = getSuggestedLanguage();
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const qrCodeRef = useRef<HTMLDivElement>(null);
const isConnected = connectionState === 'connectionStateReady';
const continueText = useLangString(isConnected ? suggestedLanguage : undefined, 'ContinueOnThisLanguage', true);
const continueText = useOldLangString(isConnected ? suggestedLanguage : undefined, 'ContinueOnThisLanguage', true);
const [isLoading, markIsLoading, unmarkIsLoading] = useFlag();
const [isQrMounted, markQrMounted, unmarkQrMounted] = useFlag();
@ -130,14 +130,14 @@ const AuthCode: FC<StateProps> = ({
useEffect(() => {
if (isConnected) {
void setLanguage(DEFAULT_LANG_CODE);
void oldSetLanguage(DEFAULT_LANG_CODE);
}
}, [isConnected]);
const handleLangChange = useCallback(() => {
markIsLoading();
void setLanguage(suggestedLanguage, () => {
void oldSetLanguage(suggestedLanguage, () => {
unmarkIsLoading();
setSettingOption({ language: suggestedLanguage });

View File

@ -7,7 +7,7 @@ import type { GlobalState } from '../../global/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import AvatarEditable from '../ui/AvatarEditable';
import Button from '../ui/Button';
@ -20,7 +20,7 @@ const AuthRegister: FC<StateProps> = ({
}) => {
const { signUp, clearAuthError, uploadProfilePhoto } = getActions();
const lang = useLang();
const lang = useOldLang();
const [isButtonShown, setIsButtonShown] = useState(false);
const [croppedFile, setCroppedFile] = useState<File | undefined>();
const [firstName, setFirstName] = useState('');

View File

@ -12,7 +12,7 @@ import { isoToEmoji } from '../../util/emoji/emoji';
import { prepareSearchWordsForNeedle } from '../../util/searchWords';
import renderText from '../common/helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import useSyncEffect from '../../hooks/useSyncEffect';
import DropdownMenu from '../ui/DropdownMenu';
@ -42,7 +42,7 @@ const CountryCodeInput: FC<OwnProps & StateProps> = ({
onChange,
phoneCodeList,
}) => {
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);

View File

@ -8,7 +8,7 @@ import { selectTabState } from '../../global/selectors';
import { selectActiveGroupCall, selectPhoneCallUser } from '../../global/selectors/calls';
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import './ActiveCallHeader.scss';
@ -25,7 +25,7 @@ const ActiveCallHeader: FC<StateProps> = ({
}) => {
const { toggleGroupCallPanel } = getActions();
const lang = useLang();
const lang = useOldLang();
useEffect(() => {
document.body.classList.toggle('has-call-header', Boolean(isCallPanelVisible));

View File

@ -25,8 +25,8 @@ import { compact } from '../../../util/iteratees';
import useAppLayout from '../../../hooks/useAppLayout';
import useFlag from '../../../hooks/useFlag';
import { useIntersectionObserver, useIsIntersecting } from '../../../hooks/useIntersectionObserver';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import { useFullscreenStatus } from '../../../hooks/window/useFullscreen';
import useGroupCallVideoLayout from './hooks/useGroupCallVideoLayout';
@ -78,7 +78,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
createGroupCallInviteLink,
} = getActions();
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);

View File

@ -15,8 +15,8 @@ import renderText from '../../common/helpers/renderText';
import formatGroupCallVolume from './helpers/formatGroupCallVolume';
import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers';
import useLang from '../../../hooks/useLang';
import useMenuPosition from '../../../hooks/useMenuPosition';
import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle';
@ -42,7 +42,7 @@ const GroupCallParticipant: FC<OwnProps & StateProps> = ({
const ref = useRef<HTMLDivElement>(null);
// eslint-disable-next-line no-null/no-null
const menuRef = useRef<HTMLDivElement>(null);
const lang = useLang();
const lang = useOldLang();
const {
isSelf, isMutedByMe, isMuted, hasVideoStream, hasPresentationStream,

View File

@ -12,8 +12,8 @@ import buildClassName from '../../../util/buildClassName';
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
import useFlag from '../../../hooks/useFlag';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import useRunThrottled from '../../../hooks/useRunThrottled';
import AnimatedIcon from '../../common/AnimatedIcon';
@ -73,7 +73,7 @@ const GroupCallParticipantMenu: FC<OwnProps & StateProps> = ({
requestToSpeak,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const [isDeleteUserModalOpen, openDeleteUserModal, closeDeleteUserModal] = useFlag();
const id = participant?.id;

View File

@ -21,9 +21,9 @@ import formatGroupCallVolume from './helpers/formatGroupCallVolume';
import useInterval from '../../../hooks/schedulers/useInterval';
import useContextMenuHandlers from '../../../hooks/useContextMenuHandlers';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useMenuPosition from '../../../hooks/useMenuPosition';
import useOldLang from '../../../hooks/useOldLang';
import FullNameTitle from '../../common/FullNameTitle';
import Button from '../../ui/Button';
@ -61,7 +61,7 @@ const GroupCallParticipantVideo: FC<OwnProps & StateProps> = ({
user,
chat,
}) => {
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const thumbnailRef = useRef<HTMLCanvasElement>(null);

View File

@ -11,7 +11,7 @@ import { selectChatGroupCall } from '../../../global/selectors/calls';
import buildClassName from '../../../util/buildClassName';
import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import useShowTransition from '../../../hooks/useShowTransition';
import AvatarList from '../../common/AvatarList';
@ -44,7 +44,7 @@ const GroupCallTopPane: FC<OwnProps & StateProps> = ({
subscribeToGroupCallUpdates,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const handleJoinGroupCall = useCallback(() => {
requestMasterAndJoinGroupCall({

View File

@ -11,7 +11,7 @@ import buildClassName from '../../../util/buildClassName';
import { vibrateShort } from '../../../util/vibrate';
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import usePrevious from '../../../hooks/usePrevious';
import AnimatedIcon from '../../common/AnimatedIcon';
@ -51,7 +51,7 @@ const MicrophoneButton: FC<OwnProps & StateProps> = ({
playGroupCallSound,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const muteMouseDownState = useRef('up');
const [isRequestingToSpeak, setIsRequestingToSpeak] = useState(false);

View File

@ -14,7 +14,7 @@ import {
import { selectTabState } from '../../../global/selectors';
import { selectPhoneCallUser } from '../../../global/selectors/calls';
import buildClassName from '../../../util/buildClassName';
import { formatMediaDuration } from '../../../util/date/dateFormat';
import { formatMediaDuration } from '../../../util/dates/dateFormat';
import {
IS_ANDROID,
IS_IOS,
@ -27,7 +27,7 @@ import useInterval from '../../../hooks/schedulers/useInterval';
import useAppLayout from '../../../hooks/useAppLayout';
import useFlag from '../../../hooks/useFlag';
import useForceUpdate from '../../../hooks/useForceUpdate';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import AnimatedIcon from '../../common/AnimatedIcon';
import Avatar from '../../common/Avatar';
@ -50,7 +50,7 @@ const PhoneCall: FC<StateProps> = ({
phoneCall,
isCallPanelVisible,
}) => {
const lang = useLang();
const lang = useOldLang();
const {
hangUp, requestMasterAndAcceptCall, playGroupCallSound, toggleGroupCallPanel, connectToActivePhoneCall,
} = getActions();

View File

@ -6,7 +6,7 @@ import { getActions } from '../../../global';
import buildClassName from '../../../util/buildClassName';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import Button from '../../ui/Button';
import InputText from '../../ui/InputText';
@ -26,7 +26,7 @@ const RatePhoneCallModal: FC<OwnProps> = ({
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);
const lang = useLang();
const lang = useOldLang();
const [rating, setRating] = useState<number | undefined>();
const handleSend = useCallback(() => {

View File

@ -5,7 +5,7 @@ import buildClassName from '../../util/buildClassName';
import renderText from './helpers/renderText';
import useDerivedState from '../../hooks/useDerivedState';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import useSelectorSignal from '../../hooks/useSelectorSignal';
import Button from '../ui/Button';
@ -28,7 +28,7 @@ const AboutAdsModal: FC<OwnProps> = ({
isRevenueSharing,
onClose,
}) => {
const lang = useLang();
const lang = useOldLang();
const minLevelSignal = useSelectorSignal((global) => global.appConfig?.channelRestrictAdsLevelMin);
const minLevelToRestrictAds = useDerivedState(minLevelSignal);

View File

@ -8,7 +8,7 @@ import { selectCanAnimateInterface } from '../../global/selectors';
import buildClassName from '../../util/buildClassName';
import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import styles from './AnimatedCounter.module.scss';
@ -21,7 +21,7 @@ const AnimatedCounter: FC<OwnProps> = ({
text,
className,
}) => {
const lang = useLang();
const lang = useOldLang();
const prevTextRef = useRef<string>();
const [isAnimating, markAnimating, unmarkAnimating] = useFlag(false);

View File

@ -6,7 +6,7 @@ import { getActions } from '../../global';
import type { ApiAudio, ApiMessage, ApiVoice } from '../../api/types';
import type { BufferedRange } from '../../hooks/useBuffering';
import type { LangFn } from '../../hooks/useLang';
import type { LangFn } from '../../hooks/useOldLang';
import type { ISettings } from '../../types';
import { ApiMediaFormat } from '../../api/types';
import { AudioOrigin } from '../../types';
@ -24,7 +24,7 @@ import {
import { makeTrackId } from '../../util/audioPlayer';
import buildClassName from '../../util/buildClassName';
import { captureEvents } from '../../util/captureEvents';
import { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/date/dateFormat';
import { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/dates/dateFormat';
import { decodeWaveform, interpolateArray } from '../../util/waveform';
import { LOCAL_TGS_URLS } from './helpers/animatedAssets';
import { getFileSizeString } from './helpers/documentInfo';
@ -34,10 +34,10 @@ import { MAX_EMPTY_WAVEFORM_POINTS, renderWaveform } from './helpers/waveform';
import useAppLayout from '../../hooks/useAppLayout';
import useAudioPlayer from '../../hooks/useAudioPlayer';
import useBuffering from '../../hooks/useBuffering';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useMedia from '../../hooks/useMedia';
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
import useOldLang from '../../hooks/useOldLang';
import useShowTransition from '../../hooks/useShowTransition';
import Button from '../ui/Button';
@ -121,7 +121,7 @@ const Audio: FC<OwnProps> = ({
const isSeeking = useRef<boolean>(false);
// eslint-disable-next-line no-null/no-null
const seekerRef = useRef<HTMLDivElement>(null);
const lang = useLang();
const lang = useOldLang();
const { isRtl } = lang;
const { isMobile } = useAppLayout();

View File

@ -29,10 +29,10 @@ import { getPeerColorClass } from './helpers/peerColor';
import renderText from './helpers/renderText';
import { useFastClick } from '../../hooks/useFastClick';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useMedia from '../../hooks/useMedia';
import useMediaTransition from '../../hooks/useMediaTransition';
import useOldLang from '../../hooks/useOldLang';
import OptimizedVideo from '../ui/OptimizedVideo';
import AvatarStoryCircle from './AvatarStoryCircle';
@ -171,7 +171,7 @@ const Avatar: FC<OwnProps> = ({
}
});
const lang = useLang();
const lang = useOldLang();
let content: TeactNode | undefined;
const author = user ? getUserFullName(user) : (chat ? getChatTitle(lang, chat) : text);

View File

@ -6,7 +6,7 @@ import type { AvatarSize } from './Avatar';
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Avatar from './Avatar';
@ -29,7 +29,7 @@ const AvatarList: FC<OwnProps> = ({
limit = DEFAULT_LIMIT,
badgeText,
}) => {
const lang = useLang();
const lang = useOldLang();
const renderingBadgeText = useMemo(() => {
if (badgeText) return badgeText;
if (!peers?.length || peers.length <= limit) return undefined;

View File

@ -3,14 +3,14 @@ import React, {
memo, useCallback, useEffect, useMemo, useState,
} from '../../lib/teact/teact';
import type { LangFn } from '../../hooks/useLang';
import type { LangFn } from '../../hooks/useOldLang';
import { MAX_INT_32 } from '../../config';
import buildClassName from '../../util/buildClassName';
import { formatDateToString, formatTime, getDayStart } from '../../util/date/dateFormat';
import { formatDateToString, formatTime, getDayStart } from '../../util/dates/dateFormat';
import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import usePrevious from '../../hooks/usePrevious';
import Button from '../ui/Button';
@ -60,7 +60,7 @@ const CalendarModal: FC<OwnProps> = ({
onSubmit,
onSecondButtonClick,
}) => {
const lang = useLang();
const lang = useOldLang();
const now = new Date();
const minDate = useMemo(() => {

View File

@ -18,7 +18,7 @@ import renderText from './helpers/renderText';
import { getIsMobile } from '../../hooks/useAppLayout';
import { useFastClick } from '../../hooks/useFastClick';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import TopicIcon from './TopicIcon';
@ -45,7 +45,7 @@ const ChatForumLastMessage: FC<OwnProps> = ({
// eslint-disable-next-line no-null/no-null
const mainColumnRef = useRef<HTMLDivElement>(null);
const lang = useLang();
const lang = useOldLang();
const [lastActiveTopic, ...otherTopics] = useMemo(() => {
if (!chat.topics) {

View File

@ -16,8 +16,8 @@ import renderText from './helpers/renderText';
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
import useInputFocusOnOpen from '../../hooks/useInputFocusOnOpen';
import useKeyboardListNavigation from '../../hooks/useKeyboardListNavigation';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import InfiniteScroll from '../ui/InfiniteScroll';
@ -65,7 +65,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
}) => {
const { loadTopics } = getActions();
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
// eslint-disable-next-line no-null/no-null

View File

@ -87,7 +87,7 @@ import {
} from '../../global/selectors';
import { selectCurrentLimit } from '../../global/selectors/limits';
import buildClassName from '../../util/buildClassName';
import { formatMediaDuration, formatVoiceRecordDuration } from '../../util/date/dateFormat';
import { formatMediaDuration, formatVoiceRecordDuration } from '../../util/dates/dateFormat';
import deleteLastCharacterOutsideSelection from '../../util/deleteLastCharacterOutsideSelection';
import { processMessageInputForCustomEmoji } from '../../util/emoji/customEmojiManager';
import focusEditableElement from '../../util/focusEditableElement';
@ -112,8 +112,8 @@ import useDerivedState from '../../hooks/useDerivedState';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
import useFlag from '../../hooks/useFlag';
import useGetSelectionRange from '../../hooks/useGetSelectionRange';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import usePrevious from '../../hooks/usePrevious';
import useSchedule from '../../hooks/useSchedule';
import useSendMessageAction from '../../hooks/useSendMessageAction';
@ -380,7 +380,7 @@ const Composer: FC<OwnProps & StateProps> = ({
editMessage,
} = getActions();
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLDivElement>(null);

View File

@ -8,8 +8,8 @@ import type { ApiCountry } from '../../api/types';
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import usePrevious from '../../hooks/usePrevious';
import Button from '../ui/Button';
@ -36,7 +36,7 @@ const CountryPickerModal: FC<OwnProps> = ({
}) => {
const { showNotification } = getActions();
const lang = useLang();
const lang = useOldLang();
const [selectedCountryIds, setSelectedCountryIds] = useState<string[]>([]);
const prevSelectedCountryIds = usePrevious(selectedCountryIds);

View File

@ -34,8 +34,8 @@ import { REM } from './helpers/mediaDimensions';
import useAppLayout from '../../hooks/useAppLayout';
import useHorizontalScroll from '../../hooks/useHorizontalScroll';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import useScrolledState from '../../hooks/useScrolledState';
import useAsyncRendering from '../right/hooks/useAsyncRendering';
import { useStickerPickerObservers } from './hooks/useStickerPickerObservers';
@ -164,7 +164,7 @@ const CustomEmojiPicker: FC<OwnProps & StateProps> = ({
selectStickerSet,
} = useStickerPickerObservers(containerRef, headerRef, prefix, isHidden);
const lang = useLang();
const lang = useOldLang();
const areAddedLoaded = Boolean(addedCustomEmojiIds);

View File

@ -10,7 +10,7 @@ import { selectCanPlayAnimatedEmojis } from '../../global/selectors';
import buildClassName from '../../util/buildClassName';
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import usePrevious from '../../hooks/usePrevious';
import Modal from '../ui/Modal';
@ -34,7 +34,7 @@ const CustomEmojiSetsModal: FC<OwnProps & StateProps> = ({
onClose,
}) => {
const { openStickerSet } = getActions();
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const customEmojiModalRef = useRef<HTMLDivElement>(null);

View File

@ -17,7 +17,7 @@ import {
import { selectIsChatWithSelf, selectUser } from '../../global/selectors';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
@ -70,7 +70,7 @@ const DeleteChatModal: FC<OwnProps & StateProps> = ({
blockUser,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const chatTitle = getChatTitle(lang, chat);
const handleDeleteForAll = useCallback(() => {

View File

@ -21,7 +21,7 @@ import {
} from '../../global/selectors';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
@ -84,7 +84,7 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
onClose();
}, [onConfirm, album, message.id, isSchedule, onClose, deleteScheduledMessages, deleteMessages]);
const lang = useLang();
const lang = useOldLang();
return (
<Modal

View File

@ -6,7 +6,7 @@ import type { ApiPhoto } from '../../api/types';
import { isUserId } from '../../global/helpers';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
@ -44,7 +44,7 @@ const DeleteProfilePhotoModal: FC<OwnProps> = ({
onClose();
}, [onConfirm, profileId, onClose, deleteProfilePhoto, photo, deleteChatPhoto]);
const lang = useLang();
const lang = useOldLang();
return (
<Modal

View File

@ -20,10 +20,10 @@ import { getDocumentExtension, getDocumentHasPreview } from './helpers/documentI
import useFlag from '../../hooks/useFlag';
import { useIsIntersecting } from '../../hooks/useIntersectionObserver';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useMedia from '../../hooks/useMedia';
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
import useOldLang from '../../hooks/useOldLang';
import Checkbox from '../ui/Checkbox';
import ConfirmDialog from '../ui/ConfirmDialog';
@ -76,7 +76,7 @@ const Document: FC<OwnProps> = ({
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
const lang = useLang();
const lang = useOldLang();
const [isSvgDialogOpen, openSvgDialog, closeSvgDialog] = useFlag();
const [shouldNotWarnAboutSvg, setShouldNotWarnAboutSvg] = useState(false);

View File

@ -4,7 +4,7 @@ import React from '../../lib/teact/teact';
import buildClassName from '../../util/buildClassName';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import './DotAnimation.scss';
@ -14,7 +14,7 @@ type OwnProps = {
};
const DotAnimation: FC<OwnProps> = ({ content, className }) => {
const lang = useLang();
const lang = useOldLang();
return (
<span className={buildClassName('DotAnimation', className)} dir={lang.isRtl ? 'rtl' : 'auto'}>
{renderText(content)}

View File

@ -3,7 +3,7 @@ import React, { memo } from '../../lib/teact/teact';
import type { ApiFakeType } from '../../api/types';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import './FakeIcon.scss';
@ -14,7 +14,7 @@ type OwnProps = {
const FakeIcon: FC<OwnProps> = ({
fakeType,
}) => {
const lang = useLang();
const lang = useOldLang();
return (
<span className="FakeIcon">

View File

@ -6,7 +6,7 @@ import React, {
import type { IconName } from '../../types/icons';
import buildClassName from '../../util/buildClassName';
import { formatMediaDateTime, formatPastTimeShort } from '../../util/date/dateFormat';
import { formatMediaDateTime, formatPastTimeShort } from '../../util/dates/dateFormat';
import { IS_CANVAS_FILTER_SUPPORTED } from '../../util/windowEnvironment';
import { getColorFromExtension, getFileSizeString } from './helpers/documentInfo';
import { getDocumentThumbnailDimensions } from './helpers/mediaDimensions';
@ -14,8 +14,8 @@ import renderText from './helpers/renderText';
import useAppLayout from '../../hooks/useAppLayout';
import useCanvasBlur from '../../hooks/useCanvasBlur';
import useLang from '../../hooks/useLang';
import useMediaTransition from '../../hooks/useMediaTransition';
import useOldLang from '../../hooks/useOldLang';
import useShowTransition from '../../hooks/useShowTransition';
import Link from '../ui/Link';
@ -64,7 +64,7 @@ const File: FC<OwnProps> = ({
onClick,
onDateClick,
}) => {
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
let elementRef = useRef<HTMLDivElement>(null);
if (ref) {

View File

@ -17,8 +17,8 @@ import { copyTextToClipboard } from '../../util/clipboard';
import stopEvent from '../../util/stopEvent';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import CustomEmoji from './CustomEmoji';
import FakeIcon from './FakeIcon';
@ -58,7 +58,7 @@ const FullNameTitle: FC<OwnProps> = ({
observeIntersection,
iconElement,
}) => {
const lang = useLang();
const lang = useOldLang();
const { showNotification } = getActions();
const realPeer = 'id' in peer ? peer : undefined;
const customPeer = 'isCustomPeer' in peer ? peer : undefined;

View File

@ -15,10 +15,10 @@ import useBuffering from '../../hooks/useBuffering';
import useCanvasBlur from '../../hooks/useCanvasBlur';
import useContextMenuHandlers from '../../hooks/useContextMenuHandlers';
import { useIsIntersecting } from '../../hooks/useIntersectionObserver';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useMedia from '../../hooks/useMedia';
import useMenuPosition from '../../hooks/useMenuPosition';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Menu from '../ui/Menu';
@ -50,7 +50,7 @@ const GifButton: FC<OwnProps> = ({
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
const lang = useLang();
const lang = useOldLang();
const localMediaHash = `gif${gif.id}`;
const isIntersecting = useIsIntersecting(ref, observeIntersection);

View File

@ -5,7 +5,7 @@ import { getActions, withGlobal } from '../../global';
import type {
ApiChat, ApiThreadInfo, ApiTopic, ApiTypingStatus, ApiUser,
} from '../../api/types';
import type { LangFn } from '../../hooks/useLang';
import type { LangFn } from '../../hooks/useOldLang';
import type { IconName } from '../../types/icons';
import { MediaViewerOrigin, type StoryViewerOrigin, type ThreadId } from '../../types';
@ -26,8 +26,8 @@ import buildClassName from '../../util/buildClassName';
import { REM } from './helpers/mediaDimensions';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Transition from '../ui/Transition';
import Avatar from './Avatar';
@ -112,7 +112,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
loadProfilePhotos,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const isSuperGroup = chat && isChatSuperGroup(chat);
const isTopic = Boolean(chat?.isForum && threadInfo && topic);

View File

@ -3,9 +3,9 @@ import React, { memo } from '../../lib/teact/teact';
import type { ApiMessage, ApiMessageOutgoingStatus } from '../../api/types';
import { formatPastTimeShort } from '../../util/date/dateFormat';
import { formatPastTimeShort } from '../../util/dates/dateFormat';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import MessageOutgoingStatus from './MessageOutgoingStatus';
@ -18,7 +18,7 @@ type OwnProps = {
};
const LastMessageMeta: FC<OwnProps> = ({ message, outgoingStatus, draftDate }) => {
const lang = useLang();
const lang = useOldLang();
const shouldUseDraft = draftDate && draftDate > message.date;
return (

View File

@ -6,8 +6,8 @@ import buildClassName from '../../util/buildClassName';
import { copyTextToClipboard } from '../../util/clipboard';
import useAppLayout from '../../hooks/useAppLayout';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import DropdownMenu from '../ui/DropdownMenu';
@ -33,7 +33,7 @@ const InviteLink: FC<OwnProps> = ({
withShare,
onRevoke,
}) => {
const lang = useLang();
const lang = useOldLang();
const { showNotification, openChatWithDraft } = getActions();
const { isMobile } = useAppLayout();

View File

@ -10,7 +10,7 @@ import buildClassName from '../../util/buildClassName';
import { copyTextToClipboard } from '../../util/clipboard';
import { isBetween } from '../../util/math';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import usePrevious from '../../hooks/usePrevious';
import ConfirmDialog from '../ui/ConfirmDialog';
@ -45,7 +45,7 @@ const ManageUsernames: FC<OwnProps> = ({
sortUsernames,
sortChatUsernames,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const [usernameForConfirm, setUsernameForConfirm] = useState<ApiUsername | undefined>();
const usernameList = useMemo(() => usernames.map(({ username }) => username), [usernames]);

View File

@ -12,7 +12,7 @@ import {
getMessageVideo,
} from '../../global/helpers';
import buildClassName from '../../util/buildClassName';
import { formatMediaDuration } from '../../util/date/dateFormat';
import { formatMediaDuration } from '../../util/dates/dateFormat';
import stopEvent from '../../util/stopEvent';
import useFlag from '../../hooks/useFlag';

View File

@ -2,7 +2,7 @@ import React, { memo } from '../../lib/teact/teact';
import type { ApiFormattedText, ApiMessage } from '../../api/types';
import type { ObserveFn } from '../../hooks/useIntersectionObserver';
import type { LangFn } from '../../hooks/useLang';
import type { LangFn } from '../../hooks/useOldLang';
import { ApiMessageEntityTypes } from '../../api/types';
import {

View File

@ -4,7 +4,7 @@ import React, { memo } from '../../lib/teact/teact';
import buildClassName from '../../util/buildClassName';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import useShowTransition from '../../hooks/useShowTransition';
import './NothingFound.scss';
@ -17,7 +17,7 @@ interface OwnProps {
const DEFAULT_TEXT = 'Nothing found.';
const NothingFound: FC<OwnProps> = ({ text = DEFAULT_TEXT, description }) => {
const lang = useLang();
const lang = useOldLang();
const { transitionClassNames } = useShowTransition(true);
return (

View File

@ -12,7 +12,7 @@ import { IS_TOUCH_ENV } from '../../util/windowEnvironment';
import useTimeout from '../../hooks/schedulers/useTimeout';
import useAppLayout from '../../hooks/useAppLayout';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
@ -53,7 +53,7 @@ const PasswordForm: FC<OwnProps> = ({
}) => {
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);
const lang = useLang();
const lang = useOldLang();
const { isMobile } = useAppLayout();
const [password, setPassword] = useState('');

View File

@ -12,8 +12,8 @@ import buildClassName from '../../util/buildClassName';
import { buildCollectionByKey } from '../../util/iteratees';
import useInfiniteScroll from '../../hooks/useInfiniteScroll';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Checkbox from '../ui/Checkbox';
import InfiniteScroll from '../ui/InfiniteScroll';
@ -173,7 +173,7 @@ const Picker: FC<OwnProps> = ({
const [viewportIds, getMore] = useInfiniteScroll(onLoadMore, sortedItemIds, Boolean(filterValue));
const lang = useLang();
const lang = useOldLang();
const countriesByIso = useMemo(() => {
if (!countryList) return undefined;

View File

@ -12,7 +12,7 @@ import buildClassName from '../../util/buildClassName';
import { getPeerColorClass } from './helpers/peerColor';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Avatar from './Avatar';
import Icon from './icons/Icon';
@ -55,7 +55,7 @@ const PickerSelectedItem: FC<OwnProps & StateProps> = ({
withPeerColors,
onClick,
}) => {
const lang = useLang();
const lang = useOldLang();
let iconElement: TeactNode | undefined;
let titleText: any;

View File

@ -13,7 +13,7 @@ import {
import { selectChat, selectIsChatWithSelf, selectUser } from '../../global/selectors';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
@ -61,7 +61,7 @@ const PinMessageModal: FC<OwnProps & StateProps> = ({
onClose();
}, [messageId, onClose, pinMessage]);
const lang = useLang();
const lang = useOldLang();
function renderMessage() {
if (isChannel) {

View File

@ -8,7 +8,7 @@ import type { IconName } from '../../types/icons';
import buildClassName from '../../util/buildClassName';
import buildStyle from '../../util/buildStyle';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import useResizeObserver from '../../hooks/useResizeObserver';
import Icon from './icons/Icon';
@ -32,7 +32,7 @@ const LimitPreview: FC<OwnProps> = ({
progress,
className,
}) => {
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const floatingBadgeRef = useRef<HTMLDivElement>(null);
// eslint-disable-next-line no-null/no-null

View File

@ -9,8 +9,8 @@ import { selectTabState, selectUser } from '../../global/selectors';
import { LOCAL_TGS_URLS } from './helpers/animatedAssets';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Modal, { ANIMATION_DURATION } from '../ui/Modal';
@ -32,7 +32,7 @@ type StateProps = {
const CLOSE_ANIMATION_DURATION = ANIMATION_DURATION + ANIMATION_END_DELAY;
const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & StateProps) => {
const lang = useLang();
const lang = useOldLang();
const {
updateGlobalPrivacySettings,
openPremiumModal,

View File

@ -16,8 +16,8 @@ import { selectChatMessages, selectUser, selectUserStatus } from '../../global/s
import buildClassName from '../../util/buildClassName';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import RippleEffect from '../ui/RippleEffect';
import Avatar from './Avatar';
@ -105,7 +105,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
loadProfilePhotos,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const { id: userId } = user || {};

View File

@ -27,8 +27,8 @@ import { MEMO_EMPTY_ARRAY } from '../../util/memo';
import { IS_TOUCH_ENV } from '../../util/windowEnvironment';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import usePrevious from '../../hooks/usePrevious';
import { useStateRef } from '../../hooks/useStateRef';
import usePhotosPreload from './hooks/usePhotosPreload';
@ -93,7 +93,7 @@ const ProfileInfo: FC<OwnProps & StateProps> = ({
openPrivacySettingsNoticeModal,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const { id: userId } = user || {};
const { id: chatId } = chat || {};

View File

@ -24,9 +24,9 @@ import renderText from './helpers/renderText';
import useAppLayout from '../../hooks/useAppLayout';
import useCanvasBlur from '../../hooks/useCanvasBlur';
import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang';
import useMedia from '../../hooks/useMedia';
import useMediaTransition from '../../hooks/useMediaTransition';
import useOldLang from '../../hooks/useOldLang';
import OptimizedVideo from '../ui/OptimizedVideo';
import Spinner from '../ui/Spinner';
@ -56,7 +56,7 @@ const ProfilePhoto: FC<OwnProps> = ({
// eslint-disable-next-line no-null/no-null
const videoRef = useRef<HTMLVideoElement>(null);
const lang = useLang();
const lang = useOldLang();
const { isMobile } = useAppLayout();
const isDeleted = user && isDeletedUser(user);

View File

@ -18,7 +18,7 @@ import { unique } from '../../util/iteratees';
import sortChatIds from './helpers/sortChatIds';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import ChatOrUserPicker from './ChatOrUserPicker';
@ -56,7 +56,7 @@ const RecipientPicker: FC<OwnProps & StateProps> = ({
onClose,
onCloseAnimationEnd,
}) => {
const lang = useLang();
const lang = useOldLang();
const [search, setSearch] = useState('');
const ids = useMemo(() => {
if (!isOpen) return undefined;

View File

@ -7,8 +7,8 @@ import type { ApiPhoto, ApiReportReason } from '../../api/types';
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import InputText from '../ui/InputText';
@ -77,7 +77,7 @@ const ReportModal: FC<OwnProps> = ({
setDescription(e.target.value);
});
const lang = useLang();
const lang = useOldLang();
const REPORT_OPTIONS: { value: ApiReportReason; label: string }[] = useMemo(() => [
{ value: 'spam', label: lang('lng_report_reason_spam') },

View File

@ -3,11 +3,11 @@ import { getActions, withGlobal } from '../../global';
import { selectChatMessage, selectTabState } from '../../global/selectors';
import buildClassName from '../../util/buildClassName';
import { formatDateAtTime } from '../../util/date/dateFormat';
import { formatDateAtTime } from '../../util/dates/dateFormat';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import ListItem from '../ui/ListItem';
@ -35,7 +35,7 @@ function SeenByModal({
closeSeenByModal,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const renderingSeenByDates = useCurrentOrPrev(seenByDates, true);
const memberIds = useMemo(() => {

View File

@ -15,9 +15,9 @@ import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMe
import useDynamicColorListener from '../../hooks/stickers/useDynamicColorListener';
import useContextMenuHandlers from '../../hooks/useContextMenuHandlers';
import { useIsIntersecting } from '../../hooks/useIntersectionObserver';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useMenuPosition from '../../hooks/useMenuPosition';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Menu from '../ui/Menu';
@ -96,7 +96,7 @@ const StickerButton = <T extends number | ApiSticker | ApiBotInlineMediaResult |
const ref = useRef<HTMLDivElement>(null);
// eslint-disable-next-line no-null/no-null
const menuRef = useRef<HTMLDivElement>(null);
const lang = useLang();
const lang = useOldLang();
const hasCustomColor = sticker.shouldUseTextColor;
const customColor = useDynamicColorListener(ref, !hasCustomColor);

View File

@ -24,9 +24,9 @@ import buildClassName from '../../util/buildClassName';
import useAppLayout from '../../hooks/useAppLayout';
import useFlag from '../../hooks/useFlag';
import { useIsIntersecting } from '../../hooks/useIntersectionObserver';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useMediaTransition from '../../hooks/useMediaTransition';
import useOldLang from '../../hooks/useOldLang';
import useResizeObserver from '../../hooks/useResizeObserver';
import useWindowSize from '../../hooks/window/useWindowSize';
@ -127,7 +127,7 @@ const StickerSet: FC<OwnProps> = ({
// eslint-disable-next-line no-null/no-null
const sharedCanvasHqRef = useRef<HTMLCanvasElement>(null);
const lang = useLang();
const lang = useOldLang();
const { width: windowWidth } = useWindowSize();
const [isConfirmModalOpen, openConfirmModal, closeConfirmModal] = useFlag();
const { isMobile } = useAppLayout();

View File

@ -7,7 +7,7 @@ import type { ObserveFn } from '../../hooks/useIntersectionObserver';
import { CHAT_HEIGHT_PX, STICKER_SIZE_GENERAL_SETTINGS } from '../../config';
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import StickerSetCover from '../middle/composer/StickerSetCover';
import Button from '../ui/Button';
@ -31,7 +31,7 @@ const StickerSetCard: FC<OwnProps> = ({
observeIntersection,
onClick,
}) => {
const lang = useLang();
const lang = useOldLang();
const firstSticker = stickerSet?.stickers?.[0];

View File

@ -26,7 +26,7 @@ import renderText from './helpers/renderText';
import useAppLayout from '../../hooks/useAppLayout';
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import usePrevious from '../../hooks/usePrevious';
import useSchedule from '../../hooks/useSchedule';
import useScrolledState from '../../hooks/useScrolledState';
@ -86,7 +86,7 @@ const StickerSetModal: FC<OwnProps & StateProps> = ({
// eslint-disable-next-line no-null/no-null
const sharedCanvasRef = useRef<HTMLCanvasElement>(null);
const lang = useLang();
const lang = useOldLang();
const { isMobile } = useAppLayout();

View File

@ -8,7 +8,7 @@ import { getTopicColorCssVariable } from '../../util/forumColors';
import { REM } from './helpers/mediaDimensions';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import TopicIcon from './TopicIcon';
@ -29,7 +29,7 @@ const TopicChip: FC<OwnProps> = ({
className,
onClick,
}) => {
const lang = useLang();
const lang = useOldLang();
return (
<div
className={buildClassName(styles.root, className)}

View File

@ -8,7 +8,7 @@ import { getUserFirstOrLastName } from '../../global/helpers';
import { selectUser } from '../../global/selectors';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import DotAnimation from './DotAnimation';
@ -23,7 +23,7 @@ type StateProps = {
};
const TypingStatus: FC<OwnProps & StateProps> = ({ typingStatus, typingUser }) => {
const lang = useLang();
const lang = useOldLang();
const typingUserName = typingUser && !typingUser.isSelf && getUserFirstOrLastName(typingUser);
const content = lang(typingStatus.action)
// Fix for translation "{user} is typing"

View File

@ -10,6 +10,7 @@ import { selectIsRightColumnShown, selectTabState } from '../../global/selectors
import buildClassName from '../../util/buildClassName';
import { preloadImage } from '../../util/files';
import preloadFonts from '../../util/fonts';
import { localizationReadyPromise } from '../../util/localization';
import * as mediaLoader from '../../util/mediaLoader';
import { Bundles, loadModule } from '../../util/moduleLoader';
import { pause } from '../../util/schedulers';
@ -80,6 +81,7 @@ const preloadTasks = {
.then(preloadFonts),
preloadAvatars(),
preloadImage(spoilerMaskPath),
localizationReadyPromise,
]),
authPhoneNumber: () => Promise.all([
preloadFonts(),

View File

@ -1,7 +1,7 @@
import type { FC } from '../../lib/teact/teact';
import React, { memo } from '../../lib/teact/teact';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
@ -20,7 +20,7 @@ const UnpinAllMessagesModal: FC<OwnProps> = ({
onClose,
onUnpin,
}) => {
const lang = useLang();
const lang = useOldLang();
return (
<Modal

View File

@ -10,7 +10,7 @@ import {
isUsernameValid, MAX_USERNAME_LENGTH, MIN_UPDATE_USERNAME_LENGTH, USERNAME_REGEX,
} from '../../util/username';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import usePrevious from '../../hooks/usePrevious';
import InputText from '../ui/InputText';
@ -39,7 +39,7 @@ const UsernameInput: FC<OwnProps> = ({
const { checkUsername, checkPublicLink } = getActions();
const [username, setUsername] = useState(currentUsername || '');
const lang = useLang();
const lang = useOldLang();
const langPrefix = asLink ? 'SetUrl' : 'Username';
const label = asLink ? lang('SetUrlPlaceholder') : lang('Username');

View File

@ -10,13 +10,13 @@ import {
getMessageWebPage,
} from '../../global/helpers';
import buildClassName from '../../util/buildClassName';
import { formatPastTimeShort } from '../../util/date/dateFormat';
import { formatPastTimeShort } from '../../util/dates/dateFormat';
import trimText from '../../util/trimText';
import { renderMessageSummary } from './helpers/renderMessageText';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Link from '../ui/Link';
import Media from './Media';
@ -41,7 +41,7 @@ type ApiWebPageWithFormatted =
const WebLink: FC<OwnProps> = ({
message, senderTitle, isProtected, observeIntersection, onMessageClick,
}) => {
const lang = useLang();
const lang = useOldLang();
let linkData: ApiWebPageWithFormatted | undefined = getMessageWebPage(message);

View File

@ -8,7 +8,7 @@ import buildClassName from '../../../util/buildClassName';
import { copyTextToClipboard } from '../../../util/clipboard';
import { areLinesWrapping } from '../helpers/renderText';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import useWindowSize from '../../../hooks/window/useWindowSize';
import styles from './CodeOverlay.module.scss';
@ -27,7 +27,7 @@ const CodeOverlay: FC<OwnProps> = ({
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
const windowSize = useWindowSize();
const lang = useLang();
const lang = useOldLang();
const [isWordWrap, setIsWordWrap] = useState(true);
const [withWordWrapButton, setWithWordWrapButton] = useState(false);

View File

@ -31,8 +31,8 @@ import { renderTextWithEntities } from '../helpers/renderTextWithEntities';
import { useFastClick } from '../../../hooks/useFastClick';
import { useIsIntersecting } from '../../../hooks/useIntersectionObserver';
import useLang from '../../../hooks/useLang';
import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import useThumbnail from '../../../hooks/useThumbnail';
import useMessageTranslation from '../../middle/message/hooks/useMessageTranslation';
@ -109,7 +109,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
chatTranslations, message?.chatId, shouldTranslate ? message?.id : undefined, requestedChatTranslationLanguage,
);
const lang = useLang();
const lang = useOldLang();
const senderTitle = sender ? getSenderTitle(lang, sender)
: (replyForwardInfo?.hiddenUserName || message?.forwardInfo?.hiddenUserName);

View File

@ -16,9 +16,9 @@ import renderText from '../helpers/renderText';
import { useFastClick } from '../../../hooks/useFastClick';
import { useIsIntersecting } from '../../../hooks/useIntersectionObserver';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../icons/Icon';
@ -45,7 +45,7 @@ const EmbeddedStory: FC<OwnProps> = ({
}) => {
const { showNotification } = getActions();
const lang = useLang();
const lang = useOldLang();
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);

View File

@ -20,8 +20,8 @@ import renderText from '../helpers/renderText';
import { renderTextWithEntities } from '../helpers/renderTextWithEntities';
import { useFastClick } from '../../../hooks/useFastClick';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../icons/Icon';
import EmojiIconBackground from './EmojiIconBackground';
@ -48,7 +48,7 @@ const EmbeddedStoryForward: FC<OwnProps & StateProps> = ({
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
const lang = useLang();
const lang = useOldLang();
useEffect(() => {
if (!story && forwardInfo.fromPeerId && forwardInfo.storyId) {

View File

@ -10,9 +10,9 @@ import { REM } from '../helpers/mediaDimensions';
import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorListener';
import { useThrottleForHeavyAnimation } from '../../../hooks/useHeavyAnimationCheck';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import useResizeObserver from '../../../hooks/useResizeObserver';
import useDevicePixelRatio from '../../../hooks/window/useDevicePixelRatio';
import useCustomEmoji from '../hooks/useCustomEmoji';
@ -75,7 +75,7 @@ const EmojiIconBackground = ({
const dpr = useDevicePixelRatio();
const lang = useLang();
const lang = useOldLang();
const { customEmoji } = useCustomEmoji(emojiDocumentId);
const previewMediaHash = customEmoji ? getStickerPreviewHash(customEmoji.id) : undefined;

View File

@ -4,7 +4,7 @@ import type {
ApiChat, ApiGroupCall, ApiMessage, ApiTopic, ApiUser,
} from '../../../api/types';
import type { ObserveFn } from '../../../hooks/useIntersectionObserver';
import type { LangFn } from '../../../hooks/useLang';
import type { LangFn } from '../../../hooks/useOldLang';
import type { TextPart } from '../../../types';
import {

View File

@ -1,5 +1,5 @@
import type { ApiMessage } from '../../../api/types';
import type { LangFn } from '../../../hooks/useLang';
import type { LangFn } from '../../../hooks/useOldLang';
import type { TextPart } from '../../../types';
import { ApiMessageEntityTypes } from '../../../api/types';

View File

@ -31,7 +31,7 @@ const SIMPLE_MARKDOWN_REGEX = /(\*\*|__).+?\1/g;
export default function renderText(
part: TextPart,
filters: Array<TextFilter> = ['emoji'],
params?: { highlight?: string; quote?: string },
params?: { highlight?: string; quote?: string; markdownPostProcessor?: (part: string) => TeactNode },
): TeactNode[] {
if (typeof part !== 'string') {
return [part];
@ -73,7 +73,7 @@ export default function renderText(
return addLinks(text, true);
case 'simple_markdown':
return replaceSimpleMarkdown(text, 'jsx');
return replaceSimpleMarkdown(text, 'jsx', params?.markdownPostProcessor);
case 'simple_markdown_html':
return replaceSimpleMarkdown(text, 'html');
@ -266,7 +266,12 @@ function addLinks(textParts: TextPart[], allowOnlyTgLinks?: boolean): TextPart[]
}, []);
}
function replaceSimpleMarkdown(textParts: TextPart[], type: 'jsx' | 'html'): TextPart[] {
function replaceSimpleMarkdown(
textParts: TextPart[], type: 'jsx' | 'html', postProcessor?: (part: string) => TeactNode,
): TextPart[] {
// Currently supported only for JSX. If needed, add typings to support HTML as well.
const postProcess = postProcessor || ((part: string) => part);
return textParts.reduce<TextPart[]>((result, part) => {
if (typeof part !== 'string') {
result.push(part);
@ -275,14 +280,14 @@ function replaceSimpleMarkdown(textParts: TextPart[], type: 'jsx' | 'html'): Tex
const parts = part.split(SIMPLE_MARKDOWN_REGEX);
const entities: string[] = part.match(SIMPLE_MARKDOWN_REGEX) || [];
result.push(parts[0]);
result.push(postProcess(parts[0]));
return entities.reduce((entityResult: TextPart[], entity, i) => {
if (type === 'jsx') {
entityResult.push(
entity.startsWith('**')
? <b>{entity.replace(/\*\*/g, '')}</b>
: <i>{entity.replace(/__/g, '')}</i>,
? <b>{postProcess(entity.replace(/\*\*/g, ''))}</b>
: <i>{postProcess(entity.replace(/__/g, ''))}</i>,
);
} else {
entityResult.push(
@ -294,7 +299,7 @@ function replaceSimpleMarkdown(textParts: TextPart[], type: 'jsx' | 'html'): Tex
const index = i * 2 + 2;
if (parts[index]) {
entityResult.push(parts[index]);
entityResult.push(postProcess(parts[index]));
}
return entityResult;

View File

@ -9,7 +9,7 @@ import { ApiMessageEntityTypes } from '../../../api/types';
import buildClassName from '../../../util/buildClassName';
import { copyTextToClipboard } from '../../../util/clipboard';
import { translate } from '../../../util/langProvider';
import { oldTranslate } from '../../../util/oldLangProvider';
import { buildCustomEmojiHtmlFromEntity } from '../../middle/composer/helpers/customEmoji';
import renderText from './renderText';
@ -663,6 +663,6 @@ function handleHashtagClick(e: React.MouseEvent<HTMLAnchorElement>) {
function handleCodeClick(e: React.MouseEvent<HTMLElement>) {
copyTextToClipboard(e.currentTarget.innerText);
getActions().showNotification({
message: translate('TextCopied'),
message: oldTranslate('TextCopied'),
});
}

View File

@ -6,18 +6,18 @@ import type { ApiBusinessWorkHours } from '../../../api/types';
import { requestMeasure, requestMutation } from '../../../lib/fasterdom/fasterdom';
import buildClassName from '../../../util/buildClassName';
import { formatTime, formatWeekday } from '../../../util/date/dateFormat';
import { formatTime, formatWeekday } from '../../../util/dates/dateFormat';
import {
getUtcOffset, getWeekStart, shiftTimeRanges, splitDays,
} from '../../../util/date/workHours';
} from '../../../util/dates/workHours';
import { IS_TOUCH_ENV } from '../../../util/windowEnvironment';
import useInterval from '../../../hooks/schedulers/useInterval';
import useDerivedState from '../../../hooks/useDerivedState';
import useFlag from '../../../hooks/useFlag';
import useForceUpdate from '../../../hooks/useForceUpdate';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import useSelectorSignal from '../../../hooks/useSelectorSignal';
import ListItem from '../../ui/ListItem';
@ -39,7 +39,7 @@ const BusinessHours = ({
const transitionRef = useRef<HTMLDivElement>(null);
const [isExpanded, expand, collapse] = useFlag(false);
const [isMyTime, showInMyTime, showInLocalTime] = useFlag(false);
const lang = useLang();
const lang = useOldLang();
const forceUpdate = useForceUpdate();
useInterval(forceUpdate, 60 * 1000);

View File

@ -37,9 +37,9 @@ import formatUsername from '../helpers/formatUsername';
import renderText from '../helpers/renderText';
import useEffectWithPrevDeps from '../../../hooks/useEffectWithPrevDeps';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import useDevicePixelRatio from '../../../hooks/window/useDevicePixelRatio';
import Chat from '../../left/main/Chat';
@ -120,7 +120,7 @@ const ChatExtra: FC<OwnProps & StateProps> = ({
personalChannelMessageId,
birthday,
} = userFullInfo || {};
const lang = useLang();
const lang = useOldLang();
const [areNotificationsEnabled, setAreNotificationsEnabled] = useState(!isMuted);

View File

@ -11,7 +11,7 @@ import { requestMeasure } from '../../../lib/fasterdom/fasterdom';
import { getStickerMediaHash } from '../../../global/helpers';
import { selectIsPremiumPurchaseBlocked } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName';
import { formatDateToString } from '../../../util/date/dateFormat';
import { formatDateToString } from '../../../util/dates/dateFormat';
import { buildCollectionByKey } from '../../../util/iteratees';
import * as mediaLoader from '../../../util/mediaLoader';
import { IS_OFFSET_PATH_SUPPORTED } from '../../../util/windowEnvironment';
@ -19,8 +19,8 @@ import renderText from '../helpers/renderText';
import useTimeout from '../../../hooks/schedulers/useTimeout';
import useFlag from '../../../hooks/useFlag';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import ListItem from '../../ui/ListItem';
import StickerView from '../StickerView';
@ -59,7 +59,7 @@ const UserBirthday = ({
const animationPlayedRef = useRef(false);
const [isPlayingAnimation, playAnimation, stopAnimation] = useFlag();
const lang = useLang();
const lang = useOldLang();
const {
formattedDate,

View File

@ -12,8 +12,8 @@ import { ANIMATION_DURATION } from '../story/helpers/ribbonAnimation';
import useForumPanelRender from '../../hooks/useForumPanelRender';
import useHistoryBack from '../../hooks/useHistoryBack';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import useShowTransition from '../../hooks/useShowTransition';
import useLeftHeaderButtonRtlForumTransition from './main/hooks/useLeftHeaderButtonRtlForumTransition';
@ -51,7 +51,7 @@ const ArchivedChats: FC<OwnProps> = ({
foldersDispatch,
}) => {
const { updateArchiveSettings } = getActions();
const lang = useLang();
const lang = useOldLang();
useHistoryBack({
isActive,

View File

@ -8,7 +8,7 @@ import type { ApiChatFolder } from '../../api/types';
import { ALL_FOLDER_ID } from '../../config';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import CheckboxGroup from '../ui/CheckboxGroup';
@ -36,7 +36,7 @@ const ChatFolderModal: FC<OwnProps & StateProps> = ({
}) => {
const { editChatFolders } = getActions();
const lang = useLang();
const lang = useOldLang();
const initialSelectedFolderIds = useMemo(() => {
if (!foldersById) {

View File

@ -3,7 +3,7 @@ import React, { memo } from '../../lib/teact/teact';
import type { ConnectionStatus } from '../../hooks/useConnectionStatus';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Spinner from '../ui/Spinner';
@ -22,7 +22,7 @@ const ConnectionStatusOverlay: FC<OwnProps> = ({
connectionStatusText,
onClick,
}) => {
const lang = useLang();
const lang = useOldLang();
return (
<div id="ConnectionStatusOverlay" dir={lang.isRtl ? 'rtl' : undefined} onClick={onClick}>

View File

@ -6,7 +6,7 @@ import { getActions } from '../../global';
import { MAX_INT_32 } from '../../config';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
@ -39,7 +39,7 @@ const MuteChatModal: FC<OwnProps> = ({
const [muteUntilOption, setMuteUntilOption] = useState(MuteDuration.Forever);
const { updateChatMutedState, updateTopicMutedState } = getActions();
const lang = useLang();
const lang = useOldLang();
const muteForOptions = useMemo(() => [
{ label: lang('MuteFor.Hours', 1), value: MuteDuration.OneHour },

View File

@ -5,7 +5,7 @@ import React, {
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Menu from '../ui/Menu';
@ -34,7 +34,7 @@ const NewChatButton: FC<OwnProps> = ({
}
}, [isShown]);
const lang = useLang();
const lang = useOldLang();
const fabClassName = buildClassName(
'NewChatButton',

View File

@ -12,7 +12,7 @@ import { formatIntegerCompact } from '../../../util/textFormat';
import renderText from '../../common/helpers/renderText';
import { useFolderManagerForOrderedIds, useFolderManagerForUnreadCounters } from '../../../hooks/useFolderManager';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import Badge from '../../ui/Badge';
import ListItem, { type MenuItemContextAction } from '../../ui/ListItem';
@ -33,7 +33,7 @@ const Archive: FC<OwnProps> = ({
onClick,
}) => {
const { updateArchiveSettings } = getActions();
const lang = useLang();
const lang = useOldLang();
const orderedChatIds = useFolderManagerForOrderedIds(ARCHIVED_FOLDER_ID);
const unreadCounters = useFolderManagerForUnreadCounters();

View File

@ -22,8 +22,8 @@ import { IS_TOUCH_ENV } from '../../../util/windowEnvironment';
import { useFolderManagerForUnreadCounters } from '../../../hooks/useFolderManager';
import useHistoryBack from '../../../hooks/useHistoryBack';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import useShowTransition from '../../../hooks/useShowTransition';
import StoryRibbon from '../../story/StoryRibbon';
@ -93,7 +93,7 @@ const ChatFolders: FC<OwnProps & StateProps> = ({
// eslint-disable-next-line no-null/no-null
const transitionRef = useRef<HTMLDivElement>(null);
const lang = useLang();
const lang = useOldLang();
useEffect(() => {
loadChatFolders();

View File

@ -10,7 +10,7 @@ import { filterUsersByName, sortUserIds } from '../../../global/helpers';
import useAppLayout from '../../../hooks/useAppLayout';
import useHistoryBack from '../../../hooks/useHistoryBack';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -43,7 +43,7 @@ const ContactList: FC<OwnProps & StateProps> = ({
openNewContactDialog,
} = getActions();
const lang = useLang();
const lang = useOldLang();
const { isMobile } = useAppLayout();
useHistoryBack({

View File

@ -9,7 +9,7 @@ import { SettingsScreens } from '../../../types';
import { selectAnimatedEmoji, selectChatFolder } from '../../../global/selectors';
import useAppLayout from '../../../hooks/useAppLayout';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import AnimatedIconFromSticker from '../../common/AnimatedIconFromSticker';
import Button from '../../ui/Button';
@ -33,7 +33,7 @@ const ICON_SIZE = 96;
const EmptyFolder: FC<OwnProps & StateProps> = ({
chatFolder, animatedEmoji, foldersDispatch, onSettingsScreenSelect,
}) => {
const lang = useLang();
const lang = useOldLang();
const { isMobile } = useAppLayout();
const handleEditFolder = useCallback(() => {

View File

@ -10,7 +10,7 @@ import buildClassName from '../../../util/buildClassName';
import { REM } from '../../common/helpers/mediaDimensions';
import useAppLayout from '../../../hooks/useAppLayout';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import AnimatedIconFromSticker from '../../common/AnimatedIconFromSticker';
import Button from '../../ui/Button';
@ -33,7 +33,7 @@ const EmptyForum: FC<OwnProps & StateProps> = ({
}) => {
const { openCreateTopicPanel } = getActions();
const lang = useLang();
const lang = useOldLang();
const { isMobile } = useAppLayout();
const handleCreateTopic = useCallback(() => {

Some files were not shown because too many files have changed in this diff Show More