Invite via Link: Use new translations (#6451)
This commit is contained in:
parent
9192eb10fe
commit
833db81897
@ -2315,4 +2315,19 @@
|
|||||||
"UserNoteHint" = "only visible to you";
|
"UserNoteHint" = "only visible to you";
|
||||||
"EditUserNoteHint" = "Notes are only visible to you.";
|
"EditUserNoteHint" = "Notes are only visible to you.";
|
||||||
"AriaStoryTogglerOpen" = "Open Story List";
|
"AriaStoryTogglerOpen" = "Open Story List";
|
||||||
|
"InviteBlockedTitle" = "Invite via Link";
|
||||||
|
"InviteBlockedOneMessage" = "This user restricts adding them to groups. You can send an invite link in a private message instead.";
|
||||||
|
"InviteBlockedManyMessage" = "Some users restrict adding them to groups. You can send these people an invite link in a private message instead.";
|
||||||
|
"InviteBlockedOr" = "or";
|
||||||
|
"InviteBlockedNoLinkTitle" = "You can't create a link";
|
||||||
|
"InviteBlockedPremiumTitle" = "Upgrade to Premium";
|
||||||
|
"InviteBlockedPremiumButton" = "Subscribe to Telegram Premium";
|
||||||
|
"InviteRestrictedPremiumReason" = "available only to Premium users";
|
||||||
|
"InviteRestrictedUsers_one" = "**{count} user** can only be invited via link, but you don't have permission to share invite links to this group.";
|
||||||
|
"InviteRestrictedUsers_other" = "**{count} users** can only be invited via link, but you don't have permission to share invite links to this group.";
|
||||||
|
"InviteViaLinkButton" = "Send Invite Link";
|
||||||
|
"InviteRestrictedPremiumReasonSingle" = "**{user}** accepts invitations to groups from contacts and **Premium** users.";
|
||||||
|
"InviteRestrictedPremiumReasonMultiple" = "{list} only accept invitations to groups from contacts and **Premium** users.";
|
||||||
|
"InviteRestrictedPremiumReasonMultipleMore_one" = "{list} and **{count} more** person only accept invitations to groups from contacts and **Premium** users.";
|
||||||
|
"InviteRestrictedPremiumReasonMultipleMore_other" = "{list} and **{count} more** people only accept invitations to groups from contacts and **Premium** users.";
|
||||||
"StoryUnsupported" = "This story is not supported in Telegram Web A. Try viewing it in the Telegram app.";
|
"StoryUnsupported" = "This story is not supported in Telegram Web A. Try viewing it in the Telegram app.";
|
||||||
|
|||||||
@ -4,13 +4,6 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.closeButton {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
top: 0.5rem;
|
|
||||||
left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contentText {
|
.contentText {
|
||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
text-align: center !important;
|
text-align: center !important;
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import type { FC } from '../../../lib/teact/teact';
|
|
||||||
import {
|
import {
|
||||||
memo, useCallback,
|
memo,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo, useState,
|
useMemo, useState,
|
||||||
} from '../../../lib/teact/teact';
|
} from '../../../lib/teact/teact';
|
||||||
@ -10,16 +9,14 @@ import type { ApiChat } from '../../../api/types';
|
|||||||
import type { TabState } from '../../../global/types';
|
import type { TabState } from '../../../global/types';
|
||||||
|
|
||||||
import { getUserFullName } from '../../../global/helpers';
|
import { getUserFullName } from '../../../global/helpers';
|
||||||
import { selectChat } from '../../../global/selectors';
|
import { selectChat, selectUser } from '../../../global/selectors';
|
||||||
import { partition } from '../../../util/iteratees';
|
import { partition } from '../../../util/iteratees';
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
import renderText from '../../common/helpers/renderText';
|
|
||||||
|
|
||||||
|
import useLang from '../../../hooks/useLang';
|
||||||
import useLastCallback from '../../../hooks/useLastCallback';
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
|
||||||
|
|
||||||
import AvatarList from '../../common/AvatarList';
|
import AvatarList from '../../common/AvatarList';
|
||||||
import Icon from '../../common/icons/Icon';
|
|
||||||
import PeerPicker from '../../common/pickers/PeerPicker';
|
import PeerPicker from '../../common/pickers/PeerPicker';
|
||||||
import Button from '../../ui/Button';
|
import Button from '../../ui/Button';
|
||||||
import Modal from '../../ui/Modal';
|
import Modal from '../../ui/Modal';
|
||||||
@ -35,14 +32,14 @@ type StateProps = {
|
|||||||
chat?: ApiChat;
|
chat?: ApiChat;
|
||||||
};
|
};
|
||||||
|
|
||||||
const InviteViaLinkModal: FC<OwnProps & StateProps> = ({
|
const InviteViaLinkModal = ({
|
||||||
modal,
|
modal,
|
||||||
chat,
|
chat,
|
||||||
}) => {
|
}: OwnProps & StateProps) => {
|
||||||
const { sendInviteMessages, closeInviteViaLinkModal, openPremiumModal } = getActions();
|
const { sendInviteMessages, closeInviteViaLinkModal, openPremiumModal } = getActions();
|
||||||
const { missingUsers } = modal || {};
|
const { missingUsers } = modal || {};
|
||||||
|
|
||||||
const lang = useOldLang();
|
const lang = useLang();
|
||||||
const [selectedMemberIds, setSelectedMemberIds] = useState<string[]>([]);
|
const [selectedMemberIds, setSelectedMemberIds] = useState<string[]>([]);
|
||||||
|
|
||||||
const userIds = useMemo(() => missingUsers?.map((user) => user.id) || MEMO_EMPTY_ARRAY, [missingUsers]);
|
const userIds = useMemo(() => missingUsers?.map((user) => user.id) || MEMO_EMPTY_ARRAY, [missingUsers]);
|
||||||
@ -52,35 +49,27 @@ const InviteViaLinkModal: FC<OwnProps & StateProps> = ({
|
|||||||
return [requirePremiumIds.map((user) => user.id), regularIds.map((user) => user.id)];
|
return [requirePremiumIds.map((user) => user.id), regularIds.map((user) => user.id)];
|
||||||
}, [missingUsers]);
|
}, [missingUsers]);
|
||||||
|
|
||||||
const invitableWithPremiumIds = useMemo(() => {
|
const invitableWithPremiumPeers = useMemo(() => {
|
||||||
|
const global = getGlobal();
|
||||||
return missingUsers?.filter((user) => user.isRequiringPremiumToInvite || user.isRequiringPremiumToMessage)
|
return missingUsers?.filter((user) => user.isRequiringPremiumToInvite || user.isRequiringPremiumToMessage)
|
||||||
.map((user) => user.id);
|
.map((user) => selectUser(global, user.id))
|
||||||
|
.filter(Boolean);
|
||||||
}, [missingUsers]);
|
}, [missingUsers]);
|
||||||
|
|
||||||
const isEveryPremiumBlocksPm = useMemo(() => {
|
|
||||||
if (!missingUsers) return undefined;
|
|
||||||
return !missingUsers.some((user) => user.isRequiringPremiumToInvite && !user.isRequiringPremiumToMessage);
|
|
||||||
}, [missingUsers]);
|
|
||||||
|
|
||||||
const topListPeers = useMemo(() => {
|
|
||||||
const users = getGlobal().users.byId;
|
|
||||||
return invitableWithPremiumIds?.map((id) => users[id]);
|
|
||||||
}, [invitableWithPremiumIds]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSelectedMemberIds(selectableIds);
|
setSelectedMemberIds(selectableIds);
|
||||||
}, [selectableIds]);
|
}, [selectableIds]);
|
||||||
|
|
||||||
const handleClose = useLastCallback(() => closeInviteViaLinkModal());
|
const handleClose = useLastCallback(() => closeInviteViaLinkModal());
|
||||||
|
|
||||||
const handleSendInviteLink = useCallback(() => {
|
const handleSendInviteLink = useLastCallback(() => {
|
||||||
sendInviteMessages({ chatId: chat!.id, userIds: selectedMemberIds });
|
sendInviteMessages({ chatId: chat!.id, userIds: selectedMemberIds });
|
||||||
closeInviteViaLinkModal();
|
closeInviteViaLinkModal();
|
||||||
}, [selectedMemberIds, chat]);
|
});
|
||||||
|
|
||||||
const handleOpenPremiumModal = useCallback(() => {
|
const handleOpenPremiumModal = useLastCallback(() => {
|
||||||
openPremiumModal();
|
openPremiumModal();
|
||||||
}, []);
|
});
|
||||||
|
|
||||||
const canSendInviteLink = useMemo(() => {
|
const canSendInviteLink = useMemo(() => {
|
||||||
if (!chat) return undefined;
|
if (!chat) return undefined;
|
||||||
@ -90,77 +79,80 @@ const InviteViaLinkModal: FC<OwnProps & StateProps> = ({
|
|||||||
const inviteSectionText = useMemo(() => {
|
const inviteSectionText = useMemo(() => {
|
||||||
return canSendInviteLink
|
return canSendInviteLink
|
||||||
? lang(missingUsers?.length === 1 ? 'InviteBlockedOneMessage' : 'InviteBlockedManyMessage')
|
? lang(missingUsers?.length === 1 ? 'InviteBlockedOneMessage' : 'InviteBlockedManyMessage')
|
||||||
: lang('InviteRestrictedUsers2', missingUsers?.length);
|
: lang('InviteRestrictedUsers', { count: missingUsers?.length }, {
|
||||||
|
pluralValue: missingUsers?.length || 0,
|
||||||
|
withMarkdown: true,
|
||||||
|
withNodes: true,
|
||||||
|
});
|
||||||
}, [canSendInviteLink, lang, missingUsers?.length]);
|
}, [canSendInviteLink, lang, missingUsers?.length]);
|
||||||
|
|
||||||
const premiumSectionText = useMemo(() => {
|
const premiumSectionText = useMemo(() => {
|
||||||
if (!invitableWithPremiumIds?.length || !topListPeers?.length) return undefined;
|
if (!invitableWithPremiumPeers?.length) return undefined;
|
||||||
const prefix = isEveryPremiumBlocksPm ? 'InviteMessagePremiumBlocked' : 'InvitePremiumBlocked';
|
if (invitableWithPremiumPeers.length === 1) {
|
||||||
let langKey = `${prefix}One`;
|
return lang('InviteRestrictedPremiumReasonSingle', { user: getUserFullName(invitableWithPremiumPeers[0]) }, {
|
||||||
let params = [getUserFullName(topListPeers[0])];
|
withMarkdown: true,
|
||||||
if (invitableWithPremiumIds.length === 2) {
|
withNodes: true,
|
||||||
langKey = `${prefix}Two`;
|
});
|
||||||
params = [getUserFullName(topListPeers[0]), getUserFullName(topListPeers[1])];
|
|
||||||
} else if (invitableWithPremiumIds.length === 3) {
|
|
||||||
langKey = `${prefix}Three`;
|
|
||||||
params = [getUserFullName(topListPeers[0]), getUserFullName(topListPeers[1]), getUserFullName(topListPeers[2])];
|
|
||||||
} else if (invitableWithPremiumIds.length > 3) {
|
|
||||||
langKey = `${prefix}Many`;
|
|
||||||
params = [
|
|
||||||
getUserFullName(topListPeers[0]),
|
|
||||||
getUserFullName(topListPeers[1]),
|
|
||||||
(invitableWithPremiumIds.length - 2).toString(),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return lang(langKey, params, undefined, topListPeers.length);
|
if (invitableWithPremiumPeers.length <= 3) {
|
||||||
}, [invitableWithPremiumIds, isEveryPremiumBlocksPm, lang, topListPeers]);
|
const list = lang.conjunction(invitableWithPremiumPeers.map((peer) => getUserFullName(peer)).filter(Boolean));
|
||||||
|
return lang('InviteRestrictedPremiumReasonMultiple', { list }, {
|
||||||
|
withMarkdown: true,
|
||||||
|
withNodes: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const hasPremiumSection = Boolean(topListPeers?.length);
|
if (invitableWithPremiumPeers.length > 3) {
|
||||||
|
const moreCount = invitableWithPremiumPeers.length - 2;
|
||||||
|
const peers = invitableWithPremiumPeers.slice(0, 2);
|
||||||
|
const list = lang.conjunction(peers.map((peer) => getUserFullName(peer)).filter(Boolean));
|
||||||
|
return lang('InviteRestrictedPremiumReasonMultipleMore', { list, count: moreCount }, {
|
||||||
|
pluralValue: moreCount,
|
||||||
|
withMarkdown: true,
|
||||||
|
withNodes: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}, [invitableWithPremiumPeers, lang]);
|
||||||
|
|
||||||
|
const hasPremiumSection = Boolean(invitableWithPremiumPeers?.length);
|
||||||
const hasSelectableSection = Boolean(selectableIds?.length);
|
const hasSelectableSection = Boolean(selectableIds?.length);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={Boolean(userIds && chat)}
|
isOpen={Boolean(userIds && chat)}
|
||||||
contentClassName={styles.content}
|
contentClassName={styles.content}
|
||||||
|
hasAbsoluteCloseButton
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
isSlim
|
isSlim
|
||||||
>
|
>
|
||||||
<Button
|
{hasPremiumSection && (
|
||||||
round
|
|
||||||
color="translucent"
|
|
||||||
size="smaller"
|
|
||||||
className={styles.closeButton}
|
|
||||||
ariaLabel={lang('Close')}
|
|
||||||
onClick={handleClose}
|
|
||||||
>
|
|
||||||
<Icon name="close" />
|
|
||||||
</Button>
|
|
||||||
{premiumSectionText && (
|
|
||||||
<>
|
<>
|
||||||
<AvatarList
|
<AvatarList
|
||||||
className={styles.avatarList}
|
className={styles.avatarList}
|
||||||
peers={topListPeers}
|
peers={invitableWithPremiumPeers}
|
||||||
size="large"
|
size="large"
|
||||||
/>
|
/>
|
||||||
<h3 className={styles.title}>
|
<h3 className={styles.title}>
|
||||||
{canSendInviteLink ? lang('InvitePremiumBlockedTitle') : lang('ChannelInviteViaLinkRestricted')}
|
{canSendInviteLink ? lang('InviteBlockedPremiumTitle') : lang('InviteBlockedNoLinkTitle')}
|
||||||
</h3>
|
</h3>
|
||||||
<p className={styles.contentText}>
|
<p className={styles.contentText}>
|
||||||
{renderText(premiumSectionText, ['simple_markdown'])}
|
{premiumSectionText}
|
||||||
</p>
|
</p>
|
||||||
<Button
|
<Button
|
||||||
withPremiumGradient
|
withPremiumGradient
|
||||||
isShiny
|
isShiny
|
||||||
onClick={handleOpenPremiumModal}
|
onClick={handleOpenPremiumModal}
|
||||||
>
|
>
|
||||||
{lang('InvitePremiumBlockedSubscribe')}
|
{lang('InviteBlockedPremiumButton')}
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{hasPremiumSection && hasSelectableSection && (
|
{hasPremiumSection && hasSelectableSection && (
|
||||||
<Separator className={styles.separator}>
|
<Separator className={styles.separator}>
|
||||||
{lang('InvitePremiumBlockedOr')}
|
{lang('InviteBlockedOr')}
|
||||||
</Separator>
|
</Separator>
|
||||||
)}
|
)}
|
||||||
{hasSelectableSection && (
|
{hasSelectableSection && (
|
||||||
@ -174,7 +166,7 @@ const InviteViaLinkModal: FC<OwnProps & StateProps> = ({
|
|||||||
itemIds={userIds}
|
itemIds={userIds}
|
||||||
selectedIds={selectedMemberIds}
|
selectedIds={selectedMemberIds}
|
||||||
lockedUnselectedIds={unselectableIds}
|
lockedUnselectedIds={unselectableIds}
|
||||||
lockedUnselectedSubtitle={lang('InvitePremiumBlockedUser')}
|
lockedUnselectedSubtitle={lang('InviteRestrictedPremiumReason')}
|
||||||
onSelectedIdsChange={setSelectedMemberIds}
|
onSelectedIdsChange={setSelectedMemberIds}
|
||||||
isViewOnly={!canSendInviteLink}
|
isViewOnly={!canSendInviteLink}
|
||||||
allowMultiple
|
allowMultiple
|
||||||
@ -187,7 +179,7 @@ const InviteViaLinkModal: FC<OwnProps & StateProps> = ({
|
|||||||
onClick={handleSendInviteLink}
|
onClick={handleSendInviteLink}
|
||||||
disabled={!selectedMemberIds.length}
|
disabled={!selectedMemberIds.length}
|
||||||
>
|
>
|
||||||
{lang('SendInviteLink.ActionInvite')}
|
{lang('InviteViaLinkButton')}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
22
src/types/language.d.ts
vendored
22
src/types/language.d.ts
vendored
@ -1729,6 +1729,15 @@ export interface LangPair {
|
|||||||
'UserNoteHint': undefined;
|
'UserNoteHint': undefined;
|
||||||
'EditUserNoteHint': undefined;
|
'EditUserNoteHint': undefined;
|
||||||
'AriaStoryTogglerOpen': undefined;
|
'AriaStoryTogglerOpen': undefined;
|
||||||
|
'InviteBlockedTitle': undefined;
|
||||||
|
'InviteBlockedOneMessage': undefined;
|
||||||
|
'InviteBlockedManyMessage': undefined;
|
||||||
|
'InviteBlockedOr': undefined;
|
||||||
|
'InviteBlockedNoLinkTitle': undefined;
|
||||||
|
'InviteBlockedPremiumTitle': undefined;
|
||||||
|
'InviteBlockedPremiumButton': undefined;
|
||||||
|
'InviteRestrictedPremiumReason': undefined;
|
||||||
|
'InviteViaLinkButton': undefined;
|
||||||
'StoryUnsupported': undefined;
|
'StoryUnsupported': undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2985,6 +2994,12 @@ export interface LangPairWithVariables<V = LangVariable> {
|
|||||||
'ActionStarGiftPrepaidUpgraded': {
|
'ActionStarGiftPrepaidUpgraded': {
|
||||||
'user': V;
|
'user': V;
|
||||||
};
|
};
|
||||||
|
'InviteRestrictedPremiumReasonSingle': {
|
||||||
|
'user': V;
|
||||||
|
};
|
||||||
|
'InviteRestrictedPremiumReasonMultiple': {
|
||||||
|
'list': V;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LangPairPlural {
|
export interface LangPairPlural {
|
||||||
@ -3334,6 +3349,13 @@ export interface LangPairPluralWithVariables<V = LangVariable> {
|
|||||||
'points': V;
|
'points': V;
|
||||||
'link': V;
|
'link': V;
|
||||||
};
|
};
|
||||||
|
'InviteRestrictedUsers': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'InviteRestrictedPremiumReasonMultipleMore': {
|
||||||
|
'list': V;
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
export type RegularLangKey = keyof LangPair;
|
export type RegularLangKey = keyof LangPair;
|
||||||
export type RegularLangKeyWithVariables = keyof LangPairWithVariables;
|
export type RegularLangKeyWithVariables = keyof LangPairWithVariables;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user