[Dev] Localization: Reassign lang function for memo (#2341)

This commit is contained in:
Alexander Zinchuk 2023-01-28 02:15:16 +01:00
parent 6c40a8e487
commit 68f28b9405
14 changed files with 79 additions and 67 deletions

View File

@ -25,7 +25,6 @@ import buildClassName from '../../util/buildClassName';
import { formatMediaDateTime, formatMediaDuration, formatPastTimeShort } from '../../util/dateFormat';
import { decodeWaveform, interpolateArray } from '../../util/waveform';
import { makeTrackId } from '../../util/audioPlayer';
import { getTranslation } from '../../util/langProvider';
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
import useShowTransition from '../../hooks/useShowTransition';
import type { BufferedRange } from '../../hooks/useBuffering';
@ -443,7 +442,7 @@ function renderAudio(
title, performer, fileName,
} = audio;
const showSeekline = isPlaying || (playProgress > 0 && playProgress < 1);
const { isRtl } = getTranslation;
const { isRtl } = lang;
return (
<div className="content">

View File

@ -10,7 +10,7 @@ import type { TextFilter } from './renderText';
import buildClassName from '../../../util/buildClassName';
import renderText from './renderText';
import { copyTextToClipboard } from '../../../util/clipboard';
import { getTranslation } from '../../../util/langProvider';
import { translate } from '../../../util/langProvider';
import { buildCustomEmojiHtmlFromEntity } from '../../middle/composer/helpers/customEmoji';
import MentionLink from '../../middle/message/MentionLink';
@ -550,6 +550,6 @@ function handleHashtagClick(e: React.MouseEvent<HTMLAnchorElement>) {
function handleCodeClick(e: React.MouseEvent<HTMLElement>) {
copyTextToClipboard(e.currentTarget.innerText);
getActions().showNotification({
message: getTranslation('TextCopied'),
message: translate('TextCopied'),
});
}

View File

@ -1,7 +1,7 @@
import { addActionHandler, getGlobal, setGlobal } from '../../index';
import { selectChat } from '../../selectors';
import { callApi } from '../../../api/gramjs';
import { getTranslation } from '../../../util/langProvider';
import { translate } from '../../../util/langProvider';
import { addUsers } from '../../reducers';
import { buildCollectionByKey } from '../../../util/iteratees';
@ -28,7 +28,7 @@ addActionHandler('reportPeer', async (global, actions, payload) => {
actions.showNotification({
message: result
? getTranslation('ReportPeer.AlertSuccess')
? translate('ReportPeer.AlertSuccess')
: 'An error occurred while submitting your report. Please, try again later.',
});
});
@ -58,7 +58,7 @@ addActionHandler('reportProfilePhoto', async (global, actions, payload) => {
actions.showNotification({
message: result
? getTranslation('ReportPeer.AlertSuccess')
? translate('ReportPeer.AlertSuccess')
: 'An error occurred while submitting your report. Please, try again later.',
});
});

View File

@ -636,7 +636,7 @@ addActionHandler('openChatByPhoneNumber', async (global, actions, payload) => {
if (!chat) {
actions.openPreviousChat();
actions.showNotification({
message: langProvider.getTranslation('lng_username_by_phone_not_found').replace('{phone}', phoneNumber),
message: langProvider.translate('lng_username_by_phone_not_found').replace('{phone}', phoneNumber),
});
return;
}
@ -1525,7 +1525,7 @@ addActionHandler('toggleTopicPinned', (global, actions, payload) => {
if (isPinned && Object.values(chat.topics).filter((topic) => topic.isPinned).length >= topicsPinnedLimit) {
actions.showNotification({
message: langProvider.getTranslation('LimitReachedPinnedTopics', topicsPinnedLimit, 'i'),
message: langProvider.translate('LimitReachedPinnedTopics', topicsPinnedLimit, 'i'),
});
return;
}
@ -1953,7 +1953,7 @@ async function getAttachBotOrNotify(global: GlobalState, username: string) {
global = getGlobal();
if (!result) {
getActions().showNotification({ message: langProvider.getTranslation('WebApp.AddToAttachmentUnavailableError') });
getActions().showNotification({ message: langProvider.translate('WebApp.AddToAttachmentUnavailableError') });
return undefined;
}

View File

@ -84,7 +84,7 @@ import {
import {
getMessageOriginalId, getUserFullName, isDeletedUser, isServiceNotificationMessage, isUserBot,
} from '../../helpers';
import { getTranslation } from '../../../util/langProvider';
import { translate } from '../../../util/langProvider';
import { ensureProtocol } from '../../../util/ensureProtocol';
const AUTOLOGIN_TOKEN_KEY = 'autologin_token';
@ -494,7 +494,7 @@ addActionHandler('reportMessages', async (global, actions, payload) => {
actions.showNotification({
message: result
? getTranslation('ReportPeer.AlertSuccess')
? translate('ReportPeer.AlertSuccess')
: 'An error occurred while submitting your report. Please, try again later.',
});
});
@ -1336,7 +1336,7 @@ addActionHandler('setForwardChatOrTopic', async (global, actions, payload) => {
if (user?.fullInfo!.noVoiceMessages) {
actions.showDialog({
data: {
message: getTranslation('VoiceMessagesRestrictedByPrivacy', getUserFullName(user)),
message: translate('VoiceMessagesRestrictedByPrivacy', getUserFullName(user)),
},
});
return;

View File

@ -18,7 +18,7 @@ import {
} from '../../reducers';
import searchWords from '../../../util/searchWords';
import { selectIsCurrentUserPremium, selectStickerSet } from '../../selectors';
import { getTranslation } from '../../../util/langProvider';
import { translate } from '../../../util/langProvider';
import { selectCurrentLimit, selectPremiumLimit } from '../../selectors/limits';
import * as langProvider from '../../../util/langProvider';
import { buildCollectionByKey } from '../../../util/iteratees';
@ -273,9 +273,9 @@ addActionHandler('saveGif', async (global, actions, payload) => {
if (!shouldUnsave && length && length >= limit) {
actions.showNotification({
title: langProvider.getTranslation('LimitReachedFavoriteGifs', limit.toString()),
message: isPremium ? langProvider.getTranslation('LimitReachedFavoriteGifsSubtitlePremium')
: langProvider.getTranslation('LimitReachedFavoriteGifsSubtitle',
title: langProvider.translate('LimitReachedFavoriteGifs', limit.toString()),
message: isPremium ? langProvider.translate('LimitReachedFavoriteGifsSubtitlePremium')
: langProvider.translate('LimitReachedFavoriteGifsSubtitle',
premiumLimit.toString()),
...(!isPremium && { action: actions.openPremiumModal }),
className: 'bold-link',
@ -312,9 +312,9 @@ addActionHandler('faveSticker', (global, actions, payload) => {
if (current >= limit) {
actions.showNotification({
title: langProvider.getTranslation('LimitReachedFavoriteStickers', limit.toString()),
message: isPremium ? langProvider.getTranslation('LimitReachedFavoriteStickersSubtitlePremium')
: langProvider.getTranslation('LimitReachedFavoriteStickersSubtitle',
title: langProvider.translate('LimitReachedFavoriteStickers', limit.toString()),
message: isPremium ? langProvider.translate('LimitReachedFavoriteStickersSubtitlePremium')
: langProvider.translate('LimitReachedFavoriteStickersSubtitle',
premiumLimit.toString()),
...(!isPremium && { action: actions.openPremiumModal }),
className: 'bold-link',
@ -476,7 +476,7 @@ async function loadStickers(stickerSetInfo: ApiStickerSetInfo) {
if (!stickerSet) {
onTickEnd(() => {
getActions().showNotification({
message: getTranslation('StickerPack.ErrorNotFound'),
message: translate('StickerPack.ErrorNotFound'),
});
});
if ('shortName' in stickerSetInfo && global.openedStickerSetShortName === stickerSetInfo.shortName) {
@ -621,7 +621,7 @@ addActionHandler('openStickerSet', async (global, actions, payload) => {
const set = selectStickerSet(global, stickerSetInfo);
if (!set?.shortName) {
actions.showNotification({
message: getTranslation('StickerPack.ErrorNotFound'),
message: translate('StickerPack.ErrorNotFound'),
});
return;
}

View File

@ -302,7 +302,7 @@ addActionHandler('importContact', async (global, actions, payload) => {
const result = await callApi('importContact', { phone, firstName, lastName });
if (!result) {
actions.showNotification({
message: langProvider.getTranslation('Contacts.PhoneNumber.NotRegistred'),
message: langProvider.translate('Contacts.PhoneNumber.NotRegistred'),
});
return;

View File

@ -105,7 +105,7 @@ addActionHandler('apiUpdate', (global, actions, update) => {
if (!verifyPhoneCallProtocol(call.protocol)) {
const user = selectPhoneCallUser(global);
actions.hangUp();
actions.showNotification({ message: langProvider.getTranslation('VoipPeerIncompatible', user?.firstName) });
actions.showNotification({ message: langProvider.translate('VoipPeerIncompatible', user?.firstName) });
return undefined;
}
}

View File

@ -18,8 +18,8 @@ addActionHandler('apiUpdate', (global, actions, update) => {
const { amount, currency, title } = message.content.invoice;
actions.showNotification({
message: langProvider.getTranslation('PaymentInfoHint', [
formatCurrency(amount, currency, langProvider.getTranslation.code),
message: langProvider.translate('PaymentInfoHint', [
formatCurrency(amount, currency, langProvider.getTranslationFn().code),
title,
]),
});

View File

@ -196,7 +196,7 @@ addActionHandler('joinVoiceChatByLink', async (global, actions, payload) => {
const chat = await fetchChatByUsername(username);
if (!chat) {
actions.showNotification({ message: langProvider.getTranslation('NoUsernameFound') });
actions.showNotification({ message: langProvider.translate('NoUsernameFound') });
return;
}
@ -383,7 +383,7 @@ export function checkNavigatorUserMediaPermissions(isVideo?: boolean) {
.then((stream) => {
if (stream.getVideoTracks().length === 0) {
getActions().showNotification({
message: langProvider.getTranslation('Call.Camera.Error'),
message: langProvider.translate('Call.Camera.Error'),
});
} else {
checkMicrophonePermission();
@ -391,7 +391,7 @@ export function checkNavigatorUserMediaPermissions(isVideo?: boolean) {
})
.catch(() => {
getActions().showNotification({
message: langProvider.getTranslation('Call.Camera.Error'),
message: langProvider.translate('Call.Camera.Error'),
});
});
} else {
@ -404,13 +404,13 @@ function checkMicrophonePermission() {
.then((stream) => {
if (stream.getAudioTracks().length === 0) {
getActions().showNotification({
message: langProvider.getTranslation('RequestAcces.Error.HaveNotAccess.Call'),
message: langProvider.translate('RequestAcces.Error.HaveNotAccess.Call'),
});
}
})
.catch(() => {
getActions().showNotification({
message: langProvider.getTranslation('RequestAcces.Error.HaveNotAccess.Call'),
message: langProvider.translate('RequestAcces.Error.HaveNotAccess.Call'),
});
});
}

View File

@ -751,7 +751,7 @@ addActionHandler('copyMessagesByIds', (global, actions, payload: { messageIds?:
function copyTextForMessages(global: GlobalState, chatId: string, messageIds: number[]) {
const { type: messageListType, threadId } = selectCurrentMessageList(global) || {};
const lang = langProvider.getTranslation;
const lang = langProvider.translate;
const chatMessages = messageListType === 'scheduled'
? selectChatScheduledMessages(global, chatId)

View File

@ -2,7 +2,7 @@ import * as langProvider from '../util/langProvider';
import useForceUpdate from './useForceUpdate';
import useOnChange from './useOnChange';
export type LangFn = typeof langProvider.getTranslation;
export type LangFn = langProvider.LangFn;
const useLang = (): LangFn => {
const forceUpdate = useForceUpdate();
@ -11,7 +11,7 @@ const useLang = (): LangFn => {
return langProvider.addCallback(forceUpdate);
}, [forceUpdate]);
return langProvider.getTranslation;
return langProvider.getTranslationFn();
};
export default useLang;

View File

@ -11,7 +11,7 @@ import { callApi } from '../api/gramjs';
import { createCallbackManager } from './callbacks';
import { formatInteger } from './textFormat';
interface LangFn {
export interface LangFn {
(key: string, value?: any, format?: 'i', pluralValue?: number): string;
isRtl?: boolean;
@ -94,30 +94,42 @@ export { addCallback, removeCallback };
let currentLangCode: string | undefined;
let currentTimeFormat: TimeFormat | undefined;
export const getTranslation: LangFn = (key: string, value?: any, format?: 'i', pluralValue?: number) => {
if (value !== undefined) {
const cacheValue = Array.isArray(value) ? JSON.stringify(value) : value;
const cached = cache.get(`${key}_${cacheValue}_${format}${pluralValue ? `_${pluralValue}` : ''}`);
if (cached) {
return cached;
}
}
if (!langPack && !fallbackLangPack) {
return key;
}
const langString = (langPack?.[key]) || (fallbackLangPack?.[key]);
if (!langString) {
if (!fallbackLangPack) {
void importFallbackLangPack();
function createLangFn() {
return (key: string, value?: any, format?: 'i', pluralValue?: number) => {
if (value !== undefined) {
const cacheValue = Array.isArray(value) ? JSON.stringify(value) : value;
const cached = cache.get(`${key}_${cacheValue}_${format}${pluralValue ? `_${pluralValue}` : ''}`);
if (cached) {
return cached;
}
}
return key;
}
if (!langPack && !fallbackLangPack) {
return key;
}
return processTranslation(langString, key, value, format, pluralValue);
};
const langString = (langPack?.[key]) || (fallbackLangPack?.[key]);
if (!langString) {
if (!fallbackLangPack) {
void importFallbackLangPack();
}
return key;
}
return processTranslation(langString, key, value, format, pluralValue);
};
}
let translationFn: LangFn = createLangFn();
export function translate(...args: Parameters<LangFn>) {
return translationFn(...args);
}
export function getTranslationFn(): LangFn {
return translationFn;
}
export async function getTranslationForLangString(langCode: string, key: string) {
let translateString: ApiLangString | undefined = await cacheApi.fetch(
@ -162,10 +174,11 @@ export async function setLanguage(langCode: LangCode, callback?: NoneToVoidFunct
const { languages, timeFormat } = getGlobal().settings.byKey;
const langInfo = languages?.find((lang) => lang.langCode === langCode);
getTranslation.isRtl = Boolean(langInfo?.rtl);
getTranslation.code = langCode.replace('-raw', '') as LangCode;
getTranslation.langName = langInfo?.nativeName;
getTranslation.timeFormat = timeFormat;
translationFn = createLangFn();
translationFn.isRtl = Boolean(langInfo?.rtl);
translationFn.code = langCode.replace('-raw', '') as LangCode;
translationFn.langName = langInfo?.nativeName;
translationFn.timeFormat = timeFormat;
if (callback) {
callback();
@ -180,7 +193,7 @@ export function setTimeFormat(timeFormat: TimeFormat) {
}
currentTimeFormat = timeFormat;
getTranslation.timeFormat = timeFormat;
translationFn.timeFormat = timeFormat;
runCallbacks();
}

View File

@ -29,7 +29,7 @@ import {
selectUser,
} from '../global/selectors';
import { IS_SERVICE_WORKER_SUPPORTED, IS_TOUCH_ENV } from './environment';
import { getTranslation } from './langProvider';
import { translate } from './langProvider';
import * as mediaLoader from './mediaLoader';
import { debounce } from './schedulers';
@ -300,7 +300,7 @@ function getNotificationContent(chat: ApiChat, message: ApiMessage, reaction?: A
const isChat = chat && (isChatChannel(chat) || message.senderId === message.chatId);
body = renderActionMessageText(
getTranslation,
translate,
message,
!isChat ? messageSender : undefined,
isChat ? chat : undefined,
@ -312,8 +312,8 @@ function getNotificationContent(chat: ApiChat, message: ApiMessage, reaction?: A
) as string;
} else {
// TODO[forums] Support ApiChat
const senderName = getMessageSenderName(getTranslation, chat.id, messageSender);
const summary = getMessageSummaryText(getTranslation, message, false, 60, false);
const senderName = getMessageSenderName(translate, chat.id, messageSender);
const summary = getMessageSummaryText(translate, message, false, 60, false);
body = senderName ? `${senderName}: ${summary}` : summary;
}
@ -321,7 +321,7 @@ function getNotificationContent(chat: ApiChat, message: ApiMessage, reaction?: A
body = 'New message';
}
let title = isScreenLocked ? APP_NAME : getChatTitle(getTranslation, chat, privateChatUser);
let title = isScreenLocked ? APP_NAME : getChatTitle(translate, chat, privateChatUser);
if (message.isSilent) {
title += ' 🔕';
@ -364,7 +364,7 @@ export async function notifyAboutCall({
options.vibrate = [200, 100, 200];
}
const notification = new Notification(getTranslation('VoipIncoming'), options);
const notification = new Notification(translate('VoipIncoming'), options);
notification.onclick = () => {
notification.close();