GramJS: Fix request errors on init (#3517)

This commit is contained in:
Alexander Zinchuk 2023-07-05 13:16:33 +02:00
parent 44b3f4d8dd
commit 50ad3fee78
5 changed files with 40 additions and 31 deletions

View File

@ -71,7 +71,8 @@ const AuthPhoneNumber: FC<StateProps> = ({
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const suggestedLanguage = getSuggestedLanguage(); const suggestedLanguage = getSuggestedLanguage();
const continueText = useLangString(suggestedLanguage, 'ContinueOnThisLanguage', true); const isConnected = connectionState === 'connectionStateReady';
const continueText = useLangString(isConnected ? suggestedLanguage : undefined, 'ContinueOnThisLanguage', true);
const [country, setCountry] = useState<ApiCountryCode | undefined>(); const [country, setCountry] = useState<ApiCountryCode | undefined>();
const [phoneNumber, setPhoneNumber] = useState<string | undefined>(); const [phoneNumber, setPhoneNumber] = useState<string | undefined>();
const [isTouched, setIsTouched] = useState(false); const [isTouched, setIsTouched] = useState(false);
@ -88,16 +89,16 @@ const AuthPhoneNumber: FC<StateProps> = ({
}, [country]); }, [country]);
useEffect(() => { useEffect(() => {
if (connectionState === 'connectionStateReady' && !authNearestCountry) { if (isConnected && !authNearestCountry) {
loadNearestCountry(); loadNearestCountry();
} }
}, [connectionState, authNearestCountry, loadNearestCountry]); }, [isConnected, authNearestCountry]);
useEffect(() => { useEffect(() => {
if (connectionState === 'connectionStateReady') { if (isConnected) {
loadCountryList({ langCode: language }); loadCountryList({ langCode: language });
} }
}, [connectionState, language, loadCountryList]); }, [isConnected, language]);
useEffect(() => { useEffect(() => {
if (authNearestCountry && phoneCodeList && !country && !isTouched) { if (authNearestCountry && phoneCodeList && !country && !isTouched) {

View File

@ -60,7 +60,9 @@ const AuthCode: FC<StateProps> = ({
const lang = useLang(); const lang = useLang();
// eslint-disable-next-line no-null/no-null // eslint-disable-next-line no-null/no-null
const qrCodeRef = useRef<HTMLDivElement>(null); const qrCodeRef = useRef<HTMLDivElement>(null);
const continueText = useLangString(suggestedLanguage, 'ContinueOnThisLanguage', true);
const isConnected = connectionState === 'connectionStateReady';
const continueText = useLangString(isConnected ? suggestedLanguage : undefined, 'ContinueOnThisLanguage', true);
const [isLoading, markIsLoading, unmarkIsLoading] = useFlag(); const [isLoading, markIsLoading, unmarkIsLoading] = useFlag();
const [isQrMounted, markQrMounted, unmarkQrMounted] = useFlag(); const [isQrMounted, markQrMounted, unmarkQrMounted] = useFlag();
@ -97,7 +99,7 @@ const AuthCode: FC<StateProps> = ({
}; };
} }
if (connectionState !== 'connectionStateReady') { if (!isConnected) {
return undefined; return undefined;
} }
@ -120,13 +122,13 @@ const AuthCode: FC<StateProps> = ({
}, QR_CODE_MUTATION_DURATION); }, QR_CODE_MUTATION_DURATION);
return undefined; return undefined;
}, [connectionState, authQrCode, isQrMounted, markQrMounted, unmarkQrMounted, qrCode]); }, [isConnected, authQrCode, isQrMounted, markQrMounted, unmarkQrMounted, qrCode]);
useEffect(() => { useEffect(() => {
if (connectionState === 'connectionStateReady') { if (isConnected) {
void setLanguage(DEFAULT_LANG_CODE); void setLanguage(DEFAULT_LANG_CODE);
} }
}, [connectionState]); }, [isConnected]);
const handleLangChange = useCallback(() => { const handleLangChange = useCallback(() => {
markIsLoading(); markIsLoading();

View File

@ -1,26 +1,21 @@
import * as langProvider from '../util/langProvider'; import * as langProvider from '../util/langProvider';
import { useState } from '../lib/teact/teact'; import useAsync from './useAsync';
const useLangString = ( const useLangString = (
langCode: string | undefined, langCode: string | undefined,
key: string, key: string,
shouldIgnoreSameValue = false, shouldIgnoreSameValue = false,
): string | undefined => { ): string | undefined => {
const [translation, setTranslation] = useState<string>(); const defaultValue = shouldIgnoreSameValue ? undefined : key;
const { result } = useAsync(() => {
if (langCode) {
return langProvider.getTranslationForLangString(langCode, key);
}
if (langCode) { return Promise.resolve();
langProvider }, [langCode, key], defaultValue);
.getTranslationForLangString(langCode, key)
.then((value) => {
// The string is not translated, maybe the language pack was not loaded due to network errors or a timeout
if (shouldIgnoreSameValue && value === key) {
return;
}
setTranslation(value);
});
}
return translation; return result || defaultValue;
}; };
export default useLangString; export default useLangString;

View File

@ -269,7 +269,7 @@ class MTProtoState {
if (this.msgIds.length > 500) { if (this.msgIds.length > 500) {
this.msgIds.shift(); this.msgIds.shift();
} }
this.msgIds.push(remoteMsgId.toString());
const remoteSequence = reader.readInt(); const remoteSequence = reader.readInt();
const containerLen = reader.readInt(); // msgLen for the inner object, padding ignored const containerLen = reader.readInt(); // msgLen for the inner object, padding ignored
const diff = body.length - containerLen; const diff = body.length - containerLen;
@ -282,10 +282,9 @@ class MTProtoState {
// We could read msg_len bytes and use those in a new reader to read // We could read msg_len bytes and use those in a new reader to read
// the next TLObject without including the padding, but since the // the next TLObject without including the padding, but since the
// reader isn't used for anything else after this, it's unnecessary. // reader isn't used for anything else after this, it's unnecessary.
const obj = reader.tgReadObject(); const obj = await reader.tgReadObject();
// We only check for objects that telegram has returned to us (Updates) not ones we send. // We only check for objects that telegram has returned to us (Updates) not ones we send.
if (obj?.constructor.name.startsWith('Update')) { if (obj?.className?.startsWith('Update')) {
const now = Math.floor(Date.now() / 1000); const now = Math.floor(Date.now() / 1000);
const msgLocalTime = this.getMsgIdTimeLocal(remoteMsgId); const msgLocalTime = this.getMsgIdTimeLocal(remoteMsgId);
@ -294,6 +293,11 @@ class MTProtoState {
throw new SecurityError('The message time is incorrect.'); throw new SecurityError('The message time is incorrect.');
} }
} }
if (obj && !('errorCode' in obj)) {
this.msgIds.push(remoteMsgId.toString());
}
return new TLMessage(remoteMsgId, remoteSequence, obj); return new TLMessage(remoteMsgId, remoteSequence, obj);
} }
} }

View File

@ -148,13 +148,16 @@ export function getTranslationFn(): LangFn {
} }
export async function getTranslationForLangString(langCode: string, key: string) { export async function getTranslationForLangString(langCode: string, key: string) {
let translateString: ApiLangString | undefined = await cacheApi.fetch( let translateString: ApiLangString | undefined;
const cachedValue = await cacheApi.fetch(
LANG_CACHE_NAME, LANG_CACHE_NAME,
`${DEFAULT_LANG_PACK}_${langCode}_${key}`, `${DEFAULT_LANG_PACK}_${langCode}_${key}`,
cacheApi.Type.Json, cacheApi.Type.Json,
); );
if (!translateString) { if (cachedValue) {
translateString = cachedValue.value;
} else {
translateString = await fetchRemoteString(DEFAULT_LANG_PACK, langCode, key); translateString = await fetchRemoteString(DEFAULT_LANG_PACK, langCode, key);
} }
@ -243,7 +246,11 @@ async function fetchRemoteString(
}); });
if (remote?.length) { if (remote?.length) {
await cacheApi.save(LANG_CACHE_NAME, `${remoteLangPack}_${langCode}_${key}`, remote[0] || ''); const wrappedString = JSON.stringify({
value: remote[0],
});
await cacheApi.save(LANG_CACHE_NAME, `${remoteLangPack}_${langCode}_${key}`, wrappedString);
return remote[0]; return remote[0];
} }