Shared Folder: Fix localization (#5395)

This commit is contained in:
zubiden 2025-01-05 20:18:41 +01:00 committed by Alexander Zinchuk
parent 963f3cd9a0
commit 9e6aa47013
9 changed files with 147 additions and 28 deletions

View File

@ -607,7 +607,8 @@ export function buildApiChatlistInvite(
if (invite instanceof GramJs.chatlists.ChatlistInvite) {
return {
slug,
title: invite.title.text,
title: buildApiFormattedText(invite.title),
noTitleAnimations: invite.titleNoanimate,
emoticon: invite.emoticon,
peerIds: invite.peers.map(getApiChatIdFromMtpPeer).filter(Boolean),
};

View File

@ -261,7 +261,8 @@ export interface ApiTopic {
}
export interface ApiChatlistInviteNew {
title: string;
title: ApiFormattedText;
noTitleAnimations?: true;
emoticon?: string;
peerIds: string[];
slug: string;

View File

@ -1416,6 +1416,21 @@
"FolderLinkTitleDescription" = "Anyone with this link can add {folder} folder and {chats} selected below.";
"FolderLinkTitleDescriptionChats_one" = "the chat";
"FolderLinkTitleDescriptionChats_other" = "the {count} chats";
"FolderLinkSubtitleNew" = "Do you want to add a new chat folder and join its groups and channels?"
"FolderLinkSubtitleAlready" = "You have already added this folder and its chats."
"FolderLinkSubtitleAdd" = "Do you want to add {chats} to the folder **{title}**?"
"FolderLinkSubtitleAddCount_one" = "1 chat";
"FolderLinkSubtitleAddCount_other" = "{count} chats";
"FolderLinkAddFolder" = "Add Folder";
"FolderLinkNotificationDeletedTitle" = "Folder {title} Deleted";
"FolderLinkNotificationDeletedSubtitle_one" = "You also left {count} chat";
"FolderLinkNotificationDeletedSubtitle_other" = "You also left {count} chats";
"FolderLinkNotificationAddedTitle" = "Folder {title} Added";
"FolderLinkNotificationAddedSubtitle_one" = "You also joined {count} chat";
"FolderLinkNotificationAddedSubtitle_other" = "You also joined {count} chats";
"FolderLinkNotificationUpdatedTitle" = "Folder {title} Updated";
"FolderLinkNotificationUpdatedSubtitle_one" = "You have added {count} chat";
"FolderLinkNotificationUpdatedSubtitle_other" = "You have added {count} chats";
"SearchTabChats" = "Chats";
"SearchTabChannels" = "Channels";
"SearchTabApps" = "Apps";

View File

@ -6,7 +6,9 @@ import type { ApiChatFolder, ApiChatlistInviteAlready } from '../../../api/types
import buildClassName from '../../../util/buildClassName';
import renderText from '../../common/helpers/renderText';
import { renderTextWithEntities } from '../../common/helpers/renderTextWithEntities';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import PeerPicker from '../../common/pickers/PeerPicker';
@ -23,17 +25,28 @@ type OwnProps = {
const ChatlistAlready: FC<OwnProps> = ({ invite, folder }) => {
const { closeChatlistModal, joinChatlistInvite } = getActions();
const lang = useOldLang();
const lang = useLang();
const oldLang = useOldLang();
const [selectedPeerIds, setSelectedPeerIds] = useState<string[]>(invite.missingPeerIds);
const hasChatsToAdd = Boolean(invite.missingPeerIds.length);
const isNew = invite.alreadyPeerIds.length === 0;
const newChatsCount = hasChatsToAdd ? invite.missingPeerIds.length : 0;
const badgeText = selectedPeerIds.length ? selectedPeerIds.length.toString() : undefined;
const descriptionText = hasChatsToAdd
? lang('FolderLinkSubtitleChats', [newChatsCount, folder.title], undefined, newChatsCount)
: lang('FolderLinkSubtitleAlready', folder.title);
const descriptionText = isNew ? lang('FolderLinkSubtitleNew')
: newChatsCount ? lang('FolderLinkSubtitleAdd', {
chats: lang('FolderLinkSubtitleAddCount', { count: newChatsCount }, { pluralValue: newChatsCount }),
title: renderTextWithEntities({
text: folder.title.text,
entities: folder.title.entities,
noCustomEmojiPlayback: folder.noTitleAnimations,
}),
}, {
withNodes: true,
withMarkdown: true,
}) : lang('FolderLinkSubtitleAlready');
const handleButtonClick = useCallback(() => {
closeChatlistModal();
@ -61,7 +74,7 @@ const ChatlistAlready: FC<OwnProps> = ({ invite, folder }) => {
<>
<div className={styles.pickerHeader}>
<div className={styles.pickerHeaderInfo}>
{lang('FolderLinkHeaderChatsJoin', selectedPeerIds.length, 'i')}
{oldLang('FolderLinkHeaderChatsJoin', selectedPeerIds.length, 'i')}
</div>
<div
className={styles.selectionToggle}
@ -69,7 +82,8 @@ const ChatlistAlready: FC<OwnProps> = ({ invite, folder }) => {
tabIndex={0}
onClick={handleSelectionToggle}
>
{selectedPeerIds.length === invite.missingPeerIds.length ? lang('DeselectAll') : lang('SelectAll')}
{selectedPeerIds.length === invite.missingPeerIds.length
? oldLang('DeselectAll') : oldLang('SelectAll')}
</div>
</div>
<PeerPicker
@ -84,7 +98,7 @@ const ChatlistAlready: FC<OwnProps> = ({ invite, folder }) => {
)}
<div className={styles.pickerHeader}>
<div className={styles.pickerHeaderInfo}>
{lang('FolderLinkHeaderAlready')}
{oldLang('FolderLinkHeaderAlready')}
</div>
</div>
<PeerPicker
@ -101,10 +115,10 @@ const ChatlistAlready: FC<OwnProps> = ({ invite, folder }) => {
onClick={handleButtonClick}
>
<div className={styles.buttonText}>
{!selectedPeerIds.length && lang('OK')}
{!selectedPeerIds.length && oldLang('OK')}
{Boolean(selectedPeerIds.length) && (
<>
{lang('FolderLinkButtonJoinPlural', selectedPeerIds.length, 'i')}
{oldLang('FolderLinkButtonJoinPlural', selectedPeerIds.length, 'i')}
<Badge className={styles.buttonBadge} text={badgeText} isAlternateColor />
</>
)}

View File

@ -29,7 +29,7 @@ const ChatlistDelete: FC<OwnProps> = ({
const lang = useOldLang();
const [selectedPeerIds, setSelectedPeerIds] = useState<string[]>(suggestedPeerIds);
const [selectedPeerIds, setSelectedPeerIds] = useState<string[]>([]);
const badgeText = selectedPeerIds.length ? selectedPeerIds.length.toString() : undefined;

View File

@ -63,7 +63,13 @@ const ChatlistInviteModal: FC<OwnProps & StateProps> = ({
noCustomEmojiPlayback: renderingFolder.noTitleAnimations,
});
}
if (renderingInfo?.invite && 'title' in renderingInfo.invite) return renderingInfo.invite.title;
if (renderingInfo?.invite && 'title' in renderingInfo.invite) {
return renderTextWithEntities({
text: renderingInfo.invite.title.text,
entities: renderingInfo.invite.title.entities,
noCustomEmojiPlayback: renderingInfo.invite.noTitleAnimations,
});
}
return undefined;
}, [renderingFolder, renderingInfo]);

View File

@ -7,8 +7,8 @@ import { getActions, getGlobal } from '../../../global';
import type { ApiChatlistInviteNew } from '../../../api/types';
import buildClassName from '../../../util/buildClassName';
import renderText from '../../common/helpers/renderText';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import PeerPicker from '../../common/pickers/PeerPicker';
@ -24,7 +24,8 @@ type OwnProps = {
const ChatlistNew: FC<OwnProps> = ({ invite }) => {
const { closeChatlistModal, joinChatlistInvite } = getActions();
const lang = useOldLang();
const lang = useLang();
const oldLang = useOldLang();
const [selectedPeerIds, setSelectedPeerIds] = useState<string[]>(invite.peerIds);
const joinedIds = useMemo(() => {
@ -53,12 +54,12 @@ const ChatlistNew: FC<OwnProps> = ({ invite }) => {
return (
<div className={styles.content}>
<div className={styles.description}>
{renderText(lang('FolderLinkSubtitle', invite.title), ['simple_markdown', 'emoji'])}
{lang('FolderLinkSubtitleNew')}
</div>
<div className={buildClassName(styles.pickerWrapper, 'custom-scroll')}>
<div className={styles.pickerHeader}>
<div className={styles.pickerHeaderInfo}>
{lang('FolderLinkHeaderChatsJoin', selectedCount, 'i')}
{oldLang('FolderLinkHeaderChatsJoin', selectedCount, 'i')}
</div>
<div
className={styles.selectionToggle}
@ -66,7 +67,7 @@ const ChatlistNew: FC<OwnProps> = ({ invite }) => {
tabIndex={0}
onClick={handleSelectionToggle}
>
{selectedPeerIds.length === invite.peerIds.length ? lang('DeselectAll') : lang('SelectAll')}
{selectedPeerIds.length === invite.peerIds.length ? oldLang('DeselectAll') : oldLang('SelectAll')}
</div>
</div>
<PeerPicker
@ -85,7 +86,7 @@ const ChatlistNew: FC<OwnProps> = ({ invite }) => {
disabled={!selectedPeerIds.length}
>
<div className={styles.buttonText}>
{lang('FolderLinkButtonAdd', invite.title)}
{lang('FolderLinkAddFolder')}
<Badge className={styles.buttonBadge} text={badgeText} isAlternateColor />
</div>
</Button>

View File

@ -36,7 +36,9 @@ import { formatShareText, processDeepLink } from '../../../util/deeplink';
import { isDeepLink } from '../../../util/deepLinkParser';
import { getCurrentTabId } from '../../../util/establishMultitabRole';
import { getOrderedIds } from '../../../util/folderManager';
import { buildCollectionByKey, omit, pick } from '../../../util/iteratees';
import {
buildCollectionByKey, omit, pick, unique,
} from '../../../util/iteratees';
import { isLocalMessageId } from '../../../util/keys/messageKey';
import * as langProvider from '../../../util/oldLangProvider';
import { debounce, pause, throttle } from '../../../util/schedulers';
@ -2329,18 +2331,54 @@ addActionHandler('joinChatlistInvite', async (global, actions, payload): Promise
const { invite, peerIds, tabId = getCurrentTabId() } = payload;
const peers = peerIds.map((peerId) => selectChat(global, peerId)).filter(Boolean);
const notJoinedCount = peers.filter((peer) => peer.isNotJoined).length;
const currentNotJoinedCount = peers.filter((peer) => peer.isNotJoined).length;
const folder = 'folderId' in invite ? selectChatFolder(global, invite.folderId) : undefined;
const folderTitle = 'title' in invite ? invite.title : folder?.title;
const existingFolder = 'folderId' in invite ? selectChatFolder(global, invite.folderId) : undefined;
const folderTitle = ('title' in invite ? invite.title : existingFolder?.title)!;
try {
const result = await callApi('joinChatlistInvite', { slug: invite.slug, peers });
if (!result) return;
if (existingFolder) {
actions.showNotification({
title: {
key: 'FolderLinkNotificationUpdatedTitle',
variables: {
title: folderTitle.text,
},
},
message: {
key: 'FolderLinkNotificationUpdatedSubtitle',
variables: {
count: currentNotJoinedCount,
},
options: {
pluralValue: currentNotJoinedCount,
},
},
tabId,
});
return;
}
actions.showNotification({
title: langProvider.oldTranslate(folder ? 'FolderLinkUpdatedTitle' : 'FolderLinkAddedTitle', folderTitle),
message: langProvider.oldTranslate('FolderLinkAddedSubtitle', notJoinedCount, 'i'),
title: {
key: 'FolderLinkNotificationAddedTitle',
variables: {
title: folderTitle.text,
},
},
message: {
key: 'FolderLinkNotificationAddedSubtitle',
variables: {
count: currentNotJoinedCount,
},
options: {
pluralValue: currentNotJoinedCount,
},
},
tabId,
});
} catch (error) {
@ -2362,10 +2400,24 @@ addActionHandler('leaveChatlist', async (global, actions, payload): Promise<void
const result = await callApi('leaveChatlist', { folderId, peers });
if (!result) return;
if (!folder) return;
actions.showNotification({
title: langProvider.oldTranslate('FolderLinkDeletedTitle', folder.title),
message: langProvider.oldTranslate('FolderLinkDeletedSubtitle', peers.length, 'i'),
title: {
key: 'FolderLinkNotificationDeletedTitle',
variables: {
title: folder.title.text,
},
},
message: {
key: 'FolderLinkNotificationDeletedSubtitle',
variables: {
count: peers.length,
},
options: {
pluralValue: peers.length,
},
},
tabId,
});
});
@ -2549,13 +2601,14 @@ addActionHandler('openDeleteChatFolderModal', async (global, actions, payload):
if (!folder) return;
if (folder.isChatList && (!folder.hasMyInvites || isConfirmedForChatlist)) {
const currentIds = getOrderedIds(folderId);
const suggestions = await callApi('fetchLeaveChatlistSuggestions', { folderId });
global = getGlobal();
global = updateTabState(global, {
chatlistModal: {
removal: {
folderId,
suggestedPeerIds: suggestions,
suggestedPeerIds: unique([...(suggestions || []), ...(currentIds || [])]),
},
},
}, tabId);

View File

@ -1174,6 +1174,9 @@ export interface LangPair {
'PrivateChatsSearchContext': undefined;
'GroupChatsSearchContext': undefined;
'ChannelsSearchContext': undefined;
'FolderLinkSubtitleNew': undefined;
'FolderLinkSubtitleAlready': undefined;
'FolderLinkAddFolder': undefined;
'SearchTabChats': undefined;
'SearchTabChannels': undefined;
'SearchTabApps': undefined;
@ -1613,6 +1616,19 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
'folder': V;
'chats': V;
};
'FolderLinkSubtitleAdd': {
'chats': V;
'title': V;
};
'FolderLinkNotificationDeletedTitle': {
'title': V;
};
'FolderLinkNotificationAddedTitle': {
'title': V;
};
'FolderLinkNotificationUpdatedTitle': {
'title': V;
};
}
export interface LangPairPlural {
@ -1797,6 +1813,18 @@ export interface LangPairPluralWithVariables<V extends unknown = LangVariable> {
'FolderLinkTitleDescriptionChats': {
'count': V;
};
'FolderLinkSubtitleAddCount': {
'count': V;
};
'FolderLinkNotificationDeletedSubtitle': {
'count': V;
};
'FolderLinkNotificationAddedSubtitle': {
'count': V;
};
'FolderLinkNotificationUpdatedSubtitle': {
'count': V;
};
}
export type RegularLangKey = keyof LangPair;
export type RegularLangKeyWithVariables = keyof LangPairWithVariables;