Send As: Fix error in some chats (#5966)
This commit is contained in:
parent
f1a538ed8e
commit
91b8463b35
@ -52,67 +52,77 @@ function buildApiChatFieldsFromPeerEntity(
|
|||||||
peerEntity: Entity,
|
peerEntity: Entity,
|
||||||
isSupport = false,
|
isSupport = false,
|
||||||
): PeerEntityApiChatFields {
|
): PeerEntityApiChatFields {
|
||||||
|
const user = peerEntity instanceof GramJs.User ? peerEntity : undefined;
|
||||||
|
const channel = peerEntity instanceof GramJs.Channel ? peerEntity : undefined;
|
||||||
|
|
||||||
|
const userOrChannel = user || channel;
|
||||||
|
|
||||||
|
// Shared fields
|
||||||
const isMin = Boolean('min' in peerEntity && peerEntity.min);
|
const isMin = Boolean('min' in peerEntity && peerEntity.min);
|
||||||
const accessHash = ('accessHash' in peerEntity) ? String(peerEntity.accessHash) : undefined;
|
const accessHash = ('accessHash' in peerEntity) ? String(peerEntity.accessHash) : undefined;
|
||||||
const hasVideoAvatar = 'photo' in peerEntity && peerEntity.photo && 'hasVideo' in peerEntity.photo
|
const hasVideoAvatar = 'photo' in peerEntity && peerEntity.photo && 'hasVideo' in peerEntity.photo
|
||||||
&& peerEntity.photo.hasVideo;
|
&& peerEntity.photo.hasVideo;
|
||||||
const avatarPhotoId = ('photo' in peerEntity) && peerEntity.photo ? buildAvatarPhotoId(peerEntity.photo) : undefined;
|
const avatarPhotoId = ('photo' in peerEntity) && peerEntity.photo ? buildAvatarPhotoId(peerEntity.photo) : undefined;
|
||||||
const areSignaturesShown = Boolean('signatures' in peerEntity && peerEntity.signatures);
|
const hasUsername = Boolean('username' in peerEntity && peerEntity.username);
|
||||||
const hasPrivateLink = Boolean('hasLink' in peerEntity && peerEntity.hasLink);
|
|
||||||
const isScam = Boolean('scam' in peerEntity && peerEntity.scam);
|
|
||||||
const isFake = Boolean('fake' in peerEntity && peerEntity.fake);
|
|
||||||
const isJoinToSend = Boolean('joinToSend' in peerEntity && peerEntity.joinToSend);
|
|
||||||
const isJoinRequest = Boolean('joinRequest' in peerEntity && peerEntity.joinRequest);
|
|
||||||
const usernames = buildApiUsernames(peerEntity);
|
const usernames = buildApiUsernames(peerEntity);
|
||||||
const isForum = Boolean('forum' in peerEntity && peerEntity.forum);
|
|
||||||
const areStoriesHidden = Boolean('storiesHidden' in peerEntity && peerEntity.storiesHidden);
|
// Chat and channel shared fields
|
||||||
const maxStoryId = 'storiesMaxId' in peerEntity ? peerEntity.storiesMaxId : undefined;
|
const isCallActive = 'callActive' in peerEntity && peerEntity.callActive;
|
||||||
const botVerificationIconId = 'botVerificationIcon' in peerEntity
|
const isCallNotEmpty = 'callNotEmpty' in peerEntity && peerEntity.callNotEmpty;
|
||||||
? peerEntity.botVerificationIcon?.toString() : undefined;
|
const creationDate = 'date' in peerEntity ? peerEntity.date : undefined;
|
||||||
const storiesUnavailable = Boolean('storiesUnavailable' in peerEntity && peerEntity.storiesUnavailable);
|
const membersCount = 'participantsCount' in peerEntity ? peerEntity.participantsCount : undefined;
|
||||||
const color = ('color' in peerEntity && peerEntity.color) ? buildApiPeerColor(peerEntity.color) : undefined;
|
const isProtected = 'noforwards' in peerEntity && peerEntity.noforwards;
|
||||||
const emojiStatus = ('emojiStatus' in peerEntity && peerEntity.emojiStatus)
|
const isCreator = 'creator' in peerEntity && peerEntity.creator;
|
||||||
? buildApiEmojiStatus(peerEntity.emojiStatus) : undefined;
|
|
||||||
const boostLevel = ('level' in peerEntity) ? peerEntity.level : undefined;
|
// User and channel shared fields
|
||||||
const areProfilesShown = Boolean('signatureProfiles' in peerEntity && peerEntity.signatureProfiles);
|
const isScam = userOrChannel?.scam;
|
||||||
const subscriptionUntil = 'subscriptionUntilDate' in peerEntity ? peerEntity.subscriptionUntilDate : undefined;
|
const isFake = userOrChannel?.fake;
|
||||||
const paidMessagesStars = 'sendPaidMessagesStars' in peerEntity ? peerEntity.sendPaidMessagesStars : undefined;
|
const areStoriesHidden = userOrChannel?.storiesHidden;
|
||||||
|
const maxStoryId = userOrChannel?.storiesMaxId;
|
||||||
|
const botVerificationIconId = userOrChannel?.botVerificationIcon?.toString();
|
||||||
|
const storiesUnavailable = userOrChannel?.storiesUnavailable;
|
||||||
|
const color = userOrChannel?.color ? buildApiPeerColor(userOrChannel.color) : undefined;
|
||||||
|
const emojiStatus = userOrChannel?.emojiStatus ? buildApiEmojiStatus(userOrChannel.emojiStatus) : undefined;
|
||||||
|
const paidMessagesStars = userOrChannel?.sendPaidMessagesStars;
|
||||||
|
const isVerified = userOrChannel?.verified;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isMin,
|
isMin,
|
||||||
hasPrivateLink,
|
isLinkedInDiscussion: channel?.hasLink,
|
||||||
areSignaturesShown,
|
areSignaturesShown: channel?.signatures,
|
||||||
areProfilesShown,
|
areProfilesShown: channel?.signatureProfiles,
|
||||||
usernames,
|
usernames,
|
||||||
accessHash,
|
accessHash,
|
||||||
hasVideoAvatar,
|
hasVideoAvatar,
|
||||||
avatarPhotoId,
|
avatarPhotoId,
|
||||||
...('verified' in peerEntity && { isVerified: peerEntity.verified }),
|
isVerified,
|
||||||
...('callActive' in peerEntity && { isCallActive: peerEntity.callActive }),
|
isCallActive,
|
||||||
...('callNotEmpty' in peerEntity && { isCallNotEmpty: peerEntity.callNotEmpty }),
|
isCallNotEmpty,
|
||||||
...('date' in peerEntity && { creationDate: peerEntity.date }),
|
creationDate,
|
||||||
...('participantsCount' in peerEntity && peerEntity.participantsCount !== undefined && {
|
hasUsername,
|
||||||
membersCount: peerEntity.participantsCount,
|
...(membersCount !== undefined && { membersCount }),
|
||||||
}),
|
isProtected,
|
||||||
...('noforwards' in peerEntity && { isProtected: Boolean(peerEntity.noforwards) }),
|
|
||||||
isSupport: isSupport || undefined,
|
isSupport: isSupport || undefined,
|
||||||
...buildApiChatPermissions(peerEntity),
|
isCreator,
|
||||||
...('creator' in peerEntity && { isCreator: peerEntity.creator }),
|
|
||||||
...buildApiChatRestrictions(peerEntity),
|
|
||||||
...buildApiChatMigrationInfo(peerEntity),
|
|
||||||
fakeType: isScam ? 'scam' : (isFake ? 'fake' : undefined),
|
fakeType: isScam ? 'scam' : (isFake ? 'fake' : undefined),
|
||||||
color,
|
color,
|
||||||
isJoinToSend,
|
isJoinToSend: channel?.joinToSend,
|
||||||
isJoinRequest,
|
isJoinRequest: channel?.joinRequest,
|
||||||
isForum,
|
isForum: channel?.forum,
|
||||||
areStoriesHidden,
|
areStoriesHidden,
|
||||||
maxStoryId,
|
maxStoryId,
|
||||||
hasStories: Boolean(maxStoryId) && !storiesUnavailable,
|
hasStories: Boolean(maxStoryId) && !storiesUnavailable,
|
||||||
emojiStatus,
|
emojiStatus,
|
||||||
boostLevel,
|
boostLevel: channel?.level,
|
||||||
botVerificationIconId,
|
botVerificationIconId,
|
||||||
subscriptionUntil,
|
hasGeo: channel?.hasGeo,
|
||||||
|
subscriptionUntil: channel?.subscriptionUntilDate,
|
||||||
paidMessagesStars: paidMessagesStars?.toJSNumber(),
|
paidMessagesStars: paidMessagesStars?.toJSNumber(),
|
||||||
|
|
||||||
|
...buildApiChatPermissions(peerEntity),
|
||||||
|
...buildApiChatRestrictions(peerEntity),
|
||||||
|
...buildApiChatMigrationInfo(peerEntity),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -96,7 +96,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
|||||||
const {
|
const {
|
||||||
id, firstName, lastName, fake, scam, support, closeFriend, storiesUnavailable, storiesMaxId,
|
id, firstName, lastName, fake, scam, support, closeFriend, storiesUnavailable, storiesMaxId,
|
||||||
bot, botActiveUsers, botVerificationIcon, botInlinePlaceholder, botAttachMenu, botCanEdit,
|
bot, botActiveUsers, botVerificationIcon, botInlinePlaceholder, botAttachMenu, botCanEdit,
|
||||||
sendPaidMessagesStars,
|
sendPaidMessagesStars, username,
|
||||||
} = mtpUser;
|
} = mtpUser;
|
||||||
const hasVideoAvatar = mtpUser.photo instanceof GramJs.UserProfilePhoto ? Boolean(mtpUser.photo.hasVideo) : undefined;
|
const hasVideoAvatar = mtpUser.photo instanceof GramJs.UserProfilePhoto ? Boolean(mtpUser.photo.hasVideo) : undefined;
|
||||||
const avatarPhotoId = mtpUser.photo && buildAvatarPhotoId(mtpUser.photo);
|
const avatarPhotoId = mtpUser.photo && buildAvatarPhotoId(mtpUser.photo);
|
||||||
@ -121,6 +121,7 @@ export function buildApiUser(mtpUser: GramJs.TypeUser): ApiUser | undefined {
|
|||||||
canEditBot: botCanEdit,
|
canEditBot: botCanEdit,
|
||||||
...(userType === 'userTypeBot' && { canBeInvitedToGroup: !mtpUser.botNochats }),
|
...(userType === 'userTypeBot' && { canBeInvitedToGroup: !mtpUser.botNochats }),
|
||||||
...(usernames && { usernames }),
|
...(usernames && { usernames }),
|
||||||
|
hasUsername: Boolean(username),
|
||||||
phoneNumber: mtpUser.phone || '',
|
phoneNumber: mtpUser.phone || '',
|
||||||
noStatus: !mtpUser.status,
|
noStatus: !mtpUser.status,
|
||||||
...(mtpUser.accessHash && { accessHash: String(mtpUser.accessHash) }),
|
...(mtpUser.accessHash && { accessHash: String(mtpUser.accessHash) }),
|
||||||
|
|||||||
@ -29,12 +29,14 @@ export interface ApiChat {
|
|||||||
isVerified?: true;
|
isVerified?: true;
|
||||||
areSignaturesShown?: boolean;
|
areSignaturesShown?: boolean;
|
||||||
areProfilesShown?: boolean;
|
areProfilesShown?: boolean;
|
||||||
hasPrivateLink?: boolean;
|
isLinkedInDiscussion?: boolean;
|
||||||
|
hasGeo?: boolean;
|
||||||
accessHash?: string;
|
accessHash?: string;
|
||||||
isMin?: boolean;
|
isMin?: boolean;
|
||||||
hasVideoAvatar?: boolean;
|
hasVideoAvatar?: boolean;
|
||||||
avatarPhotoId?: string;
|
avatarPhotoId?: string;
|
||||||
usernames?: ApiUsername[];
|
usernames?: ApiUsername[];
|
||||||
|
hasUsername?: boolean;
|
||||||
membersCount?: number;
|
membersCount?: number;
|
||||||
creationDate?: number;
|
creationDate?: number;
|
||||||
isSupport?: true;
|
isSupport?: true;
|
||||||
|
|||||||
@ -20,6 +20,7 @@ export interface ApiUser {
|
|||||||
lastName?: string;
|
lastName?: string;
|
||||||
noStatus?: boolean;
|
noStatus?: boolean;
|
||||||
usernames?: ApiUsername[];
|
usernames?: ApiUsername[];
|
||||||
|
hasUsername?: boolean;
|
||||||
phoneNumber: string;
|
phoneNumber: string;
|
||||||
accessHash?: string;
|
accessHash?: string;
|
||||||
hasVideoAvatar?: boolean;
|
hasVideoAvatar?: boolean;
|
||||||
|
|||||||
@ -1304,6 +1304,7 @@
|
|||||||
"ComposerSilentPostingEnabledTootlip" = "Subscribers will receive a silent notification.";
|
"ComposerSilentPostingEnabledTootlip" = "Subscribers will receive a silent notification.";
|
||||||
"ComposerSilentPostingDisabledTootlip" = "Subscribers will be notified when you post.";
|
"ComposerSilentPostingDisabledTootlip" = "Subscribers will be notified when you post.";
|
||||||
"ComposerPlaceholder" = "Message";
|
"ComposerPlaceholder" = "Message";
|
||||||
|
"ComposerPlaceholderAnonymous" = "Send anonymously";
|
||||||
"ComposerPlaceholderBroadcast" = "Broadcast";
|
"ComposerPlaceholderBroadcast" = "Broadcast";
|
||||||
"ComposerPlaceholderBroadcastSilent" = "Silent Broadcast";
|
"ComposerPlaceholderBroadcastSilent" = "Silent Broadcast";
|
||||||
"ComposerPlaceholderTopic" = "Message in {topic}";
|
"ComposerPlaceholderTopic" = "Message in {topic}";
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import type {
|
|||||||
ApiMessage,
|
ApiMessage,
|
||||||
ApiMessageEntity,
|
ApiMessageEntity,
|
||||||
ApiNewPoll,
|
ApiNewPoll,
|
||||||
|
ApiPeer,
|
||||||
ApiQuickReply,
|
ApiQuickReply,
|
||||||
ApiReaction,
|
ApiReaction,
|
||||||
ApiStealthMode,
|
ApiStealthMode,
|
||||||
@ -62,6 +63,7 @@ import {
|
|||||||
getStoryKey,
|
getStoryKey,
|
||||||
isChatAdmin,
|
isChatAdmin,
|
||||||
isChatChannel,
|
isChatChannel,
|
||||||
|
isChatPublic,
|
||||||
isChatSuperGroup,
|
isChatSuperGroup,
|
||||||
isSameReaction,
|
isSameReaction,
|
||||||
isSystemBot,
|
isSystemBot,
|
||||||
@ -253,8 +255,7 @@ type StateProps =
|
|||||||
inlineBots?: Record<string, false | InlineBotSettings>;
|
inlineBots?: Record<string, false | InlineBotSettings>;
|
||||||
botCommands?: ApiBotCommand[] | false;
|
botCommands?: ApiBotCommand[] | false;
|
||||||
botMenuButton?: ApiBotMenuButton;
|
botMenuButton?: ApiBotMenuButton;
|
||||||
sendAsUser?: ApiUser;
|
sendAsPeer?: ApiPeer;
|
||||||
sendAsChat?: ApiChat;
|
|
||||||
sendAsId?: string;
|
sendAsId?: string;
|
||||||
editingDraft?: ApiFormattedText;
|
editingDraft?: ApiFormattedText;
|
||||||
requestedDraft?: ApiFormattedText;
|
requestedDraft?: ApiFormattedText;
|
||||||
@ -374,8 +375,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
inlineBots,
|
inlineBots,
|
||||||
isInlineBotLoading,
|
isInlineBotLoading,
|
||||||
botCommands,
|
botCommands,
|
||||||
sendAsUser,
|
sendAsPeer,
|
||||||
sendAsChat,
|
|
||||||
sendAsId,
|
sendAsId,
|
||||||
editingDraft,
|
editingDraft,
|
||||||
requestedDraft,
|
requestedDraft,
|
||||||
@ -472,8 +472,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
const isInMessageList = type === 'messageList';
|
const isInMessageList = type === 'messageList';
|
||||||
const isInStoryViewer = type === 'story';
|
const isInStoryViewer = type === 'story';
|
||||||
const sendAsPeerIds = isInMessageList ? chat?.sendAsPeerIds : undefined;
|
const sendAsPeerIds = isInMessageList ? chat?.sendAsPeerIds : undefined;
|
||||||
const canShowSendAs = sendAsPeerIds
|
const canShowSendAs = Boolean(sendAsPeerIds?.length);
|
||||||
&& (sendAsPeerIds.length > 1 || !sendAsPeerIds.some((peer) => peer.id === currentUserId!));
|
|
||||||
// Prevent Symbol Menu from closing when calendar is open
|
// Prevent Symbol Menu from closing when calendar is open
|
||||||
const [isSymbolMenuForced, forceShowSymbolMenu, cancelForceShowSymbolMenu] = useFlag();
|
const [isSymbolMenuForced, forceShowSymbolMenu, cancelForceShowSymbolMenu] = useFlag();
|
||||||
const sendMessageAction = useSendMessageAction(chatId, threadId);
|
const sendMessageAction = useSendMessageAction(chatId, threadId);
|
||||||
@ -518,7 +517,9 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const isChannelWithProfiles = isChannel && chat?.areProfilesShown;
|
const isChannelWithProfiles = isChannel && chat?.areProfilesShown;
|
||||||
if (chatId && chat && !sendAsPeerIds && isReady && (isChatSuperGroup(chat) || isChannelWithProfiles)) {
|
const isChatWithSendAs = chat && isChatSuperGroup(chat)
|
||||||
|
&& Boolean(isChatPublic(chat) || chat.isLinkedInDiscussion || chat.hasGeo);
|
||||||
|
if (!sendAsPeerIds && isReady && (isChatWithSendAs || isChannelWithProfiles)) {
|
||||||
loadSendAs({ chatId });
|
loadSendAs({ chatId });
|
||||||
}
|
}
|
||||||
}, [chat, chatId, isChannel, isReady, loadSendAs, sendAsPeerIds]);
|
}, [chat, chatId, isChannel, isReady, loadSendAs, sendAsPeerIds]);
|
||||||
@ -1586,6 +1587,11 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
withNodes: true,
|
withNodes: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chat?.adminRights?.anonymous) {
|
||||||
|
return lang('ComposerPlaceholderAnonymous');
|
||||||
|
}
|
||||||
|
|
||||||
if (chat?.isForum && chat?.isForumAsMessages && threadId === MAIN_THREAD_ID) {
|
if (chat?.isForum && chat?.isForumAsMessages && threadId === MAIN_THREAD_ID) {
|
||||||
return replyToTopic
|
return replyToTopic
|
||||||
? lang('ComposerPlaceholderTopic', { topic: replyToTopic.title })
|
? lang('ComposerPlaceholderTopic', { topic: replyToTopic.title })
|
||||||
@ -1978,7 +1984,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
<Icon name="bot-commands-filled" />
|
<Icon name="bot-commands-filled" />
|
||||||
</ResponsiveHoverButton>
|
</ResponsiveHoverButton>
|
||||||
)}
|
)}
|
||||||
{canShowSendAs && (sendAsUser || sendAsChat) && (
|
{canShowSendAs && sendAsPeer && (
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
color="translucent"
|
color="translucent"
|
||||||
@ -1991,7 +1997,7 @@ const Composer: FC<OwnProps & StateProps> = ({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Avatar
|
<Avatar
|
||||||
peer={sendAsUser || sendAsChat}
|
peer={sendAsPeer}
|
||||||
size="tiny"
|
size="tiny"
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
@ -2363,13 +2369,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const { currentUserId } = global;
|
const { currentUserId } = global;
|
||||||
const currentUser = selectUser(global, currentUserId!)!;
|
const currentUser = selectUser(global, currentUserId!)!;
|
||||||
const defaultSendAsId = chatFullInfo ? chatFullInfo?.sendAsId || currentUserId : undefined;
|
const defaultSendAsId = chatFullInfo ? chatFullInfo?.sendAsId || currentUserId : undefined;
|
||||||
const sendAsId = chat?.sendAsPeerIds && defaultSendAsId && (
|
const sendAsId = defaultSendAsId;
|
||||||
chat.sendAsPeerIds.some((peer) => peer.id === defaultSendAsId)
|
const sendAsPeer = sendAsId ? selectPeer(global, sendAsId) : undefined;
|
||||||
? defaultSendAsId
|
|
||||||
: (chat?.adminRights?.anonymous ? chat?.id : undefined)
|
|
||||||
);
|
|
||||||
const sendAsUser = sendAsId ? selectUser(global, sendAsId) : undefined;
|
|
||||||
const sendAsChat = !sendAsUser && sendAsId ? selectChat(global, sendAsId) : undefined;
|
|
||||||
const requestedDraft = selectRequestedDraft(global, chatId);
|
const requestedDraft = selectRequestedDraft(global, chatId);
|
||||||
const requestedDraftFiles = selectRequestedDraftFiles(global, chatId);
|
const requestedDraftFiles = selectRequestedDraftFiles(global, chatId);
|
||||||
|
|
||||||
@ -2467,8 +2468,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isInlineBotLoading: tabState.inlineBots.isLoading,
|
isInlineBotLoading: tabState.inlineBots.isLoading,
|
||||||
botCommands: userFullInfo ? (userFullInfo.botInfo?.commands || false) : undefined,
|
botCommands: userFullInfo ? (userFullInfo.botInfo?.commands || false) : undefined,
|
||||||
botMenuButton: userFullInfo?.botInfo?.menuButton,
|
botMenuButton: userFullInfo?.botInfo?.menuButton,
|
||||||
sendAsUser,
|
sendAsPeer,
|
||||||
sendAsChat,
|
|
||||||
sendAsId,
|
sendAsId,
|
||||||
editingDraft,
|
editingDraft,
|
||||||
requestedDraft,
|
requestedDraft,
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import type { CustomPeerType, UniqueCustomPeer } from '../../../types';
|
|||||||
|
|
||||||
import { DEBUG } from '../../../config';
|
import { DEBUG } from '../../../config';
|
||||||
import { requestMeasure } from '../../../lib/fasterdom/fasterdom';
|
import { requestMeasure } from '../../../lib/fasterdom/fasterdom';
|
||||||
import { getGroupStatus, getUserStatus, isUserOnline } from '../../../global/helpers';
|
import { getGroupStatus, getMainUsername, getUserStatus, isUserOnline } from '../../../global/helpers';
|
||||||
import { getPeerTypeKey, isApiPeerChat } from '../../../global/helpers/peers';
|
import { getPeerTypeKey, isApiPeerChat } from '../../../global/helpers/peers';
|
||||||
import { selectPeer, selectUserStatus } from '../../../global/selectors';
|
import { selectPeer, selectUserStatus } from '../../../global/selectors';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
@ -279,7 +279,7 @@ const PeerPicker = <CategoryType extends string = CustomPeerType>({
|
|||||||
if (!peer) return undefined;
|
if (!peer) return undefined;
|
||||||
|
|
||||||
if (withPeerUsernames) {
|
if (withPeerUsernames) {
|
||||||
const username = peer.usernames?.[0]?.username;
|
const username = getMainUsername(peer);
|
||||||
if (username) {
|
if (username) {
|
||||||
return [`@${username}`];
|
return [`@${username}`];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import type {
|
|||||||
} from '../../../api/types';
|
} from '../../../api/types';
|
||||||
import type { Signal } from '../../../util/signals';
|
import type { Signal } from '../../../util/signals';
|
||||||
|
|
||||||
|
import { getMainUsername } from '../../../global/helpers';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import freezeWhenClosed from '../../../util/hoc/freezeWhenClosed';
|
import freezeWhenClosed from '../../../util/hoc/freezeWhenClosed';
|
||||||
import setTooltipItemVisible from '../../../util/setTooltipItemVisible';
|
import setTooltipItemVisible from '../../../util/setTooltipItemVisible';
|
||||||
@ -63,7 +64,7 @@ const ChatCommandTooltip: FC<OwnProps> = ({
|
|||||||
const bot = usersById[botId];
|
const bot = usersById[botId];
|
||||||
|
|
||||||
sendBotCommand({
|
sendBotCommand({
|
||||||
command: `/${command}${withUsername && bot ? `@${bot.usernames![0].username}` : ''}`,
|
command: `/${command}${withUsername && bot ? `@${getMainUsername(bot)}` : ''}`,
|
||||||
});
|
});
|
||||||
onClick();
|
onClick();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -102,7 +102,7 @@ export default function useMentionTooltip(
|
|||||||
forceFocus = false,
|
forceFocus = false,
|
||||||
insertAtEnd = false,
|
insertAtEnd = false,
|
||||||
) => {
|
) => {
|
||||||
if (!peer.usernames && !getPeerTitle(lang, peer)) {
|
if (!peer.hasUsername && !getPeerTitle(lang, peer)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
TME_LINK_PREFIX,
|
TME_LINK_PREFIX,
|
||||||
} from '../../../config';
|
} from '../../../config';
|
||||||
import {
|
import {
|
||||||
|
getMainUsername,
|
||||||
getMessageInvoice, getMessageText, isChatChannel,
|
getMessageInvoice, getMessageText, isChatChannel,
|
||||||
} from '../../../global/helpers';
|
} from '../../../global/helpers';
|
||||||
import { getPeerTitle } from '../../../global/helpers/peers';
|
import { getPeerTitle } from '../../../global/helpers/peers';
|
||||||
@ -386,10 +387,9 @@ const ActionMessageText = ({
|
|||||||
if (isAttachMenu) return lang('ActionAttachMenuBotAllowed');
|
if (isAttachMenu) return lang('ActionAttachMenuBotAllowed');
|
||||||
if (isFromRequest) return lang('ActionWebappBotAllowed');
|
if (isFromRequest) return lang('ActionWebappBotAllowed');
|
||||||
if (app) {
|
if (app) {
|
||||||
const link = sender?.usernames?.length
|
const senderUsername = sender && getMainUsername(sender);
|
||||||
&& `${TME_LINK_PREFIX + sender.usernames[0].username}/${app.shortName}`;
|
const link = senderUsername && `${TME_LINK_PREFIX + senderUsername}/${app.shortName}`;
|
||||||
const appLink = link
|
const appLink = link
|
||||||
|
|
||||||
? <Link onClick={() => openTelegramLink({ url: link })}>{app.title}</Link>
|
? <Link onClick={() => openTelegramLink({ url: link })}>{app.title}</Link>
|
||||||
: lang('ActionBotAppPlaceholder');
|
: lang('ActionBotAppPlaceholder');
|
||||||
return lang('ActionBotAllowedFromApp', { app: appLink }, { withNodes: true });
|
return lang('ActionBotAllowedFromApp', { app: appLink }, { withNodes: true });
|
||||||
|
|||||||
@ -47,6 +47,7 @@ import { EMOJI_STATUS_LOOP_LIMIT, MESSAGE_APPEARANCE_DELAY } from '../../../conf
|
|||||||
import {
|
import {
|
||||||
areReactionsEmpty,
|
areReactionsEmpty,
|
||||||
getIsDownloading,
|
getIsDownloading,
|
||||||
|
getMainUsername,
|
||||||
getMessageContent,
|
getMessageContent,
|
||||||
getMessageCustomShape,
|
getMessageCustomShape,
|
||||||
getMessageDownloadableMedia,
|
getMessageDownloadableMedia,
|
||||||
@ -1499,7 +1500,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
const senderIsPremium = senderPeer && 'isPremium' in senderPeer && senderPeer.isPremium;
|
const senderIsPremium = senderPeer && 'isPremium' in senderPeer && senderPeer.isPremium;
|
||||||
|
|
||||||
const shouldRenderForwardAvatar = asForwarded && senderPeer;
|
const shouldRenderForwardAvatar = asForwarded && senderPeer;
|
||||||
const hasBotSenderUsername = botSender?.usernames?.length;
|
const hasBotSenderUsername = botSender?.hasUsername;
|
||||||
return (
|
return (
|
||||||
<div className="message-title" dir="ltr">
|
<div className="message-title" dir="ltr">
|
||||||
{(senderTitle || asForwarded) ? (
|
{(senderTitle || asForwarded) ? (
|
||||||
@ -1543,14 +1544,14 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
) : !botSender ? (
|
) : !botSender ? (
|
||||||
NBSP
|
NBSP
|
||||||
) : undefined}
|
) : undefined}
|
||||||
{Boolean(botSender?.usernames?.length) && (
|
{botSender?.hasUsername && (
|
||||||
<span className="interactive">
|
<span className="interactive">
|
||||||
<span className="via">{lang('ViaBot')}</span>
|
<span className="via">{lang('ViaBot')}</span>
|
||||||
<span
|
<span
|
||||||
className="sender-title"
|
className="sender-title"
|
||||||
onClick={handleViaBotClick}
|
onClick={handleViaBotClick}
|
||||||
>
|
>
|
||||||
{renderText(`@${botSender.usernames[0].username}`)}
|
{renderText(`@${getMainUsername(botSender)}`)}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { getActions, withGlobal } from '../../../global';
|
|||||||
|
|
||||||
import type { TabState } from '../../../global/types';
|
import type { TabState } from '../../../global/types';
|
||||||
|
|
||||||
|
import { getMainUsername } from '../../../global/helpers';
|
||||||
import { selectUser } from '../../../global/selectors';
|
import { selectUser } from '../../../global/selectors';
|
||||||
import { formatDateToString } from '../../../util/dates/dateFormat';
|
import { formatDateToString } from '../../../util/dates/dateFormat';
|
||||||
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
|
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
|
||||||
@ -130,9 +131,8 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
(global): StateProps => {
|
(global): StateProps => {
|
||||||
const freezeUntilDate = global.appConfig?.freezeUntilDate;
|
const freezeUntilDate = global.appConfig?.freezeUntilDate;
|
||||||
const freezeAppealUrl = global.appConfig?.freezeAppealUrl;
|
const freezeAppealUrl = global.appConfig?.freezeAppealUrl;
|
||||||
const botFreezeAppealId = global.botFreezeAppealId;
|
const botFreezeAppeal = global.botFreezeAppealId ? selectUser(global, global.botFreezeAppealId) : undefined;
|
||||||
const botFreezeAppealUsername = botFreezeAppealId
|
const botFreezeAppealUsername = botFreezeAppeal && getMainUsername(botFreezeAppeal);
|
||||||
? selectUser(global, botFreezeAppealId)?.usernames?.[0]?.username : undefined;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
freezeUntilDate,
|
freezeUntilDate,
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import type { ApiChat } from '../../../api/types';
|
|||||||
import { ManagementScreens } from '../../../types';
|
import { ManagementScreens } from '../../../types';
|
||||||
|
|
||||||
import { STICKER_SIZE_DISCUSSION_GROUPS } from '../../../config';
|
import { STICKER_SIZE_DISCUSSION_GROUPS } from '../../../config';
|
||||||
import { isChatChannel } from '../../../global/helpers';
|
import { isChatChannel, isChatPublic } from '../../../global/helpers';
|
||||||
import { selectChat, selectChatFullInfo } from '../../../global/selectors';
|
import { selectChat, selectChatFullInfo } from '../../../global/selectors';
|
||||||
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
|
import { LOCAL_TGS_URLS } from '../../common/helpers/animatedAssets';
|
||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
@ -152,7 +152,7 @@ const ManageDiscussion: FC<OwnProps & StateProps> = ({
|
|||||||
const linkedGroup = chatsByIds[linkedGroupId];
|
const linkedGroup = chatsByIds[linkedGroupId];
|
||||||
if (!linkedGroup) return undefined;
|
if (!linkedGroup) return undefined;
|
||||||
|
|
||||||
if (linkedGroup.hasPrivateLink) {
|
if (isChatPublic(linkedGroup)) {
|
||||||
return renderText(
|
return renderText(
|
||||||
`Do you want to make **${linkedGroup.title}** the discussion board for **${chat!.title}**?`,
|
`Do you want to make **${linkedGroup.title}** the discussion board for **${chat!.title}**?`,
|
||||||
['br', 'simple_markdown'],
|
['br', 'simple_markdown'],
|
||||||
|
|||||||
@ -100,9 +100,9 @@ const ManageInvites: FC<OwnProps & StateProps> = ({
|
|||||||
const primaryInvite = exportedInvites?.find(({ isPermanent }) => isPermanent);
|
const primaryInvite = exportedInvites?.find(({ isPermanent }) => isPermanent);
|
||||||
const primaryInviteLink = chatMainUsername ? `${TME_LINK_PREFIX}${chatMainUsername}` : primaryInvite?.link;
|
const primaryInviteLink = chatMainUsername ? `${TME_LINK_PREFIX}${chatMainUsername}` : primaryInvite?.link;
|
||||||
const temporalInvites = useMemo(() => {
|
const temporalInvites = useMemo(() => {
|
||||||
const invites = chat?.usernames ? exportedInvites : exportedInvites?.filter(({ isPermanent }) => !isPermanent);
|
const invites = chat?.hasUsername ? exportedInvites : exportedInvites?.filter(({ isPermanent }) => !isPermanent);
|
||||||
return invites?.sort(inviteComparator);
|
return invites?.sort(inviteComparator);
|
||||||
}, [chat?.usernames, exportedInvites]);
|
}, [chat?.hasUsername, exportedInvites]);
|
||||||
|
|
||||||
const editInvite = (invite: ApiExportedInvite) => {
|
const editInvite = (invite: ApiExportedInvite) => {
|
||||||
setEditingExportedInvite({ chatId, invite });
|
setEditingExportedInvite({ chatId, invite });
|
||||||
|
|||||||
@ -216,7 +216,7 @@ function Story({
|
|||||||
isLoadedStory
|
isLoadedStory
|
||||||
&& story.isPublic
|
&& story.isPublic
|
||||||
&& !isChangelog
|
&& !isChangelog
|
||||||
&& peer?.usernames?.length,
|
&& peer?.hasUsername,
|
||||||
);
|
);
|
||||||
|
|
||||||
const canShare = Boolean(
|
const canShare = Boolean(
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import { debounce } from '../../../util/schedulers';
|
|||||||
import { getServerTime } from '../../../util/serverTime';
|
import { getServerTime } from '../../../util/serverTime';
|
||||||
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
import { extractCurrentThemeParams } from '../../../util/themeStyle';
|
||||||
import { callApi } from '../../../api/gramjs';
|
import { callApi } from '../../../api/gramjs';
|
||||||
|
import { getMainUsername } from '../../helpers';
|
||||||
import {
|
import {
|
||||||
getWebAppKey,
|
getWebAppKey,
|
||||||
} from '../../helpers/bots';
|
} from '../../helpers/bots';
|
||||||
@ -377,7 +378,7 @@ addActionHandler('switchBotInline', (global, actions, payload): ActionReturnType
|
|||||||
|
|
||||||
actions.openChatWithDraft({
|
actions.openChatWithDraft({
|
||||||
text: {
|
text: {
|
||||||
text: `@${botSender.usernames![0].username} ${query}`,
|
text: `@${getMainUsername(botSender)} ${query}`,
|
||||||
},
|
},
|
||||||
chatId: isSamePeer ? chat.id : undefined,
|
chatId: isSamePeer ? chat.id : undefined,
|
||||||
filter,
|
filter,
|
||||||
|
|||||||
@ -36,6 +36,7 @@ import {
|
|||||||
import { copyTextToClipboard } from '../../../util/clipboard';
|
import { copyTextToClipboard } from '../../../util/clipboard';
|
||||||
import { formatShareText, processDeepLink } from '../../../util/deeplink';
|
import { formatShareText, processDeepLink } from '../../../util/deeplink';
|
||||||
import { isDeepLink } from '../../../util/deepLinkParser';
|
import { isDeepLink } from '../../../util/deepLinkParser';
|
||||||
|
import { isUserId } from '../../../util/entities/ids';
|
||||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||||
import { getOrderedIds } from '../../../util/folderManager';
|
import { getOrderedIds } from '../../../util/folderManager';
|
||||||
import {
|
import {
|
||||||
@ -564,6 +565,30 @@ addActionHandler('loadFullChat', (global, actions, payload): ActionReturnType =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('invalidateFullInfo', (global, actions, payload): ActionReturnType => {
|
||||||
|
const { peerId } = payload;
|
||||||
|
|
||||||
|
const isUser = isUserId(peerId);
|
||||||
|
|
||||||
|
if (isUser) {
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
users: {
|
||||||
|
...global.users,
|
||||||
|
fullInfoById: omit(global.users.fullInfoById, [peerId]),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
chats: {
|
||||||
|
...global.chats,
|
||||||
|
fullInfoById: omit(global.chats.fullInfoById, [peerId]),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
addActionHandler('loadTopChats', (): ActionReturnType => {
|
addActionHandler('loadTopChats', (): ActionReturnType => {
|
||||||
runThrottledForLoadTopChats(() => {
|
runThrottledForLoadTopChats(() => {
|
||||||
loadChats('active', undefined, true);
|
loadChats('active', undefined, true);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import type { ApiMessage, ApiUpdateChat } from '../../../api/types';
|
import type { ApiChat, ApiMessage, ApiUpdateChat } from '../../../api/types';
|
||||||
import type { ActionReturnType } from '../../types';
|
import type { ActionReturnType } from '../../types';
|
||||||
import { MAIN_THREAD_ID } from '../../../api/types';
|
import { MAIN_THREAD_ID } from '../../../api/types';
|
||||||
|
|
||||||
@ -43,6 +43,10 @@ import {
|
|||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
|
|
||||||
const TYPING_STATUS_CLEAR_DELAY = 6000; // 6 seconds
|
const TYPING_STATUS_CLEAR_DELAY = 6000; // 6 seconds
|
||||||
|
const INVALIDATE_FULL_CHAT_FIELDS = new Set<keyof ApiChat>([
|
||||||
|
'boostLevel', 'isForum', 'isLinkedInDiscussion', 'fakeType', 'restrictionReason', 'isJoinToSend', 'isJoinRequest',
|
||||||
|
'type',
|
||||||
|
]);
|
||||||
|
|
||||||
addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||||
switch (update['@type']) {
|
switch (update['@type']) {
|
||||||
@ -93,6 +97,15 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (localChat) {
|
||||||
|
const chatUpdate = update.chat;
|
||||||
|
const changedFields = (Object.keys(chatUpdate) as (keyof ApiChat)[])
|
||||||
|
.filter((key) => localChat[key] !== chatUpdate[key]);
|
||||||
|
if (changedFields.some((key) => INVALIDATE_FULL_CHAT_FIELDS.has(key))) {
|
||||||
|
actions.invalidateFullInfo({ peerId: update.id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -328,7 +328,7 @@ export function getFolderDescriptionText(lang: OldLangFn, folder: ApiChatFolder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isChatPublic(chat: ApiChat) {
|
export function isChatPublic(chat: ApiChat) {
|
||||||
return chat.usernames?.some(({ isActive }) => isActive);
|
return chat.hasUsername;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOrderedTopics(
|
export function getOrderedTopics(
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import {
|
|||||||
getHasAdminRight,
|
getHasAdminRight,
|
||||||
getPrivateChatUserId,
|
getPrivateChatUserId,
|
||||||
isChatChannel,
|
isChatChannel,
|
||||||
|
isChatPublic,
|
||||||
isChatSuperGroup,
|
isChatSuperGroup,
|
||||||
isHistoryClearMessage,
|
isHistoryClearMessage,
|
||||||
isUserBot,
|
isUserBot,
|
||||||
@ -256,7 +257,7 @@ export function selectCanInviteToChat<T extends GlobalState>(global: T, chatId:
|
|||||||
// https://github.com/TelegramMessenger/Telegram-iOS/blob/5126be83b3b9578fb014eb52ca553da9e7a8b83a/submodules/TelegramCore/Sources/TelegramEngine/Peers/Communities.swift#L6
|
// https://github.com/TelegramMessenger/Telegram-iOS/blob/5126be83b3b9578fb014eb52ca553da9e7a8b83a/submodules/TelegramCore/Sources/TelegramEngine/Peers/Communities.swift#L6
|
||||||
return !chat.migratedTo && Boolean(!isUserId(chatId) && ((isChatChannel(chat) || isChatSuperGroup(chat)) ? (
|
return !chat.migratedTo && Boolean(!isUserId(chatId) && ((isChatChannel(chat) || isChatSuperGroup(chat)) ? (
|
||||||
chat.isCreator || getHasAdminRight(chat, 'inviteUsers')
|
chat.isCreator || getHasAdminRight(chat, 'inviteUsers')
|
||||||
|| (chat.usernames?.length && !chat.isJoinRequest)
|
|| (isChatPublic(chat) && !chat.isJoinRequest)
|
||||||
) : (chat.isCreator || getHasAdminRight(chat, 'inviteUsers'))));
|
) : (chat.isCreator || getHasAdminRight(chat, 'inviteUsers'))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1154,6 +1154,9 @@ export interface ActionPayloads {
|
|||||||
withPhotos?: boolean;
|
withPhotos?: boolean;
|
||||||
force?: boolean;
|
force?: boolean;
|
||||||
};
|
};
|
||||||
|
invalidateFullInfo: {
|
||||||
|
peerId: string;
|
||||||
|
};
|
||||||
updateChatPhoto: {
|
updateChatPhoto: {
|
||||||
chatId: string;
|
chatId: string;
|
||||||
photo: ApiPhoto;
|
photo: ApiPhoto;
|
||||||
|
|||||||
1
src/types/language.d.ts
vendored
1
src/types/language.d.ts
vendored
@ -1112,6 +1112,7 @@ export interface LangPair {
|
|||||||
'ComposerSilentPostingEnabledTootlip': undefined;
|
'ComposerSilentPostingEnabledTootlip': undefined;
|
||||||
'ComposerSilentPostingDisabledTootlip': undefined;
|
'ComposerSilentPostingDisabledTootlip': undefined;
|
||||||
'ComposerPlaceholder': undefined;
|
'ComposerPlaceholder': undefined;
|
||||||
|
'ComposerPlaceholderAnonymous': undefined;
|
||||||
'ComposerPlaceholderBroadcast': undefined;
|
'ComposerPlaceholderBroadcast': undefined;
|
||||||
'ComposerPlaceholderBroadcastSilent': undefined;
|
'ComposerPlaceholderBroadcastSilent': undefined;
|
||||||
'ComposerPlaceholderTopicGeneral': undefined;
|
'ComposerPlaceholderTopicGeneral': undefined;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user