Middle Header: Add "Report Spam and Leave" button, fix animations (#1759)
This commit is contained in:
parent
ab78137640
commit
fc9b679a66
@ -10,6 +10,7 @@ import {
|
|||||||
ApiRestrictionReason,
|
ApiRestrictionReason,
|
||||||
ApiExportedInvite,
|
ApiExportedInvite,
|
||||||
ApiChatInviteImporter,
|
ApiChatInviteImporter,
|
||||||
|
ApiChatSettings,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
import { pick, pickTruthy } from '../../../util/iteratees';
|
import { pick, pickTruthy } from '../../../util/iteratees';
|
||||||
import {
|
import {
|
||||||
@ -434,3 +435,17 @@ export function buildChatInviteImporter(importer: GramJs.ChatInviteImporter): Ap
|
|||||||
isRequested: requested,
|
isRequested: requested,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildApiChatSettings({
|
||||||
|
autoarchived,
|
||||||
|
reportSpam,
|
||||||
|
addContact,
|
||||||
|
blockContact,
|
||||||
|
}: GramJs.PeerSettings): ApiChatSettings {
|
||||||
|
return {
|
||||||
|
isAutoArchived: Boolean(autoarchived),
|
||||||
|
canReportSpam: Boolean(reportSpam),
|
||||||
|
canAddContact: Boolean(addContact),
|
||||||
|
canBlockContact: Boolean(blockContact),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { Api as GramJs } from '../../../lib/gramjs';
|
import { Api as GramJs } from '../../../lib/gramjs';
|
||||||
import {
|
import {
|
||||||
ApiBotCommand, ApiUser, ApiUserSettings, ApiUserStatus, ApiUserType,
|
ApiBotCommand, ApiUser, ApiUserStatus, ApiUserType,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
import { buildApiPeerId } from './peers';
|
import { buildApiPeerId } from './peers';
|
||||||
|
|
||||||
export function buildApiUserFromFull(mtpUserFull: GramJs.users.UserFull): ApiUser {
|
export function buildApiUserFromFull(mtpUserFull: GramJs.users.UserFull): ApiUser {
|
||||||
const {
|
const {
|
||||||
fullUser: {
|
fullUser: {
|
||||||
about, commonChatsCount, pinnedMsgId, botInfo, blocked, settings,
|
about, commonChatsCount, pinnedMsgId, botInfo, blocked,
|
||||||
},
|
},
|
||||||
users,
|
users,
|
||||||
} = mtpUserFull;
|
} = mtpUserFull;
|
||||||
@ -16,7 +16,6 @@ export function buildApiUserFromFull(mtpUserFull: GramJs.users.UserFull): ApiUse
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
settings: buildApiUserSettings(settings),
|
|
||||||
fullInfo: {
|
fullInfo: {
|
||||||
bio: about,
|
bio: about,
|
||||||
commonChatsCount,
|
commonChatsCount,
|
||||||
@ -112,17 +111,3 @@ export function buildApiUsersAndStatuses(mtpUsers: GramJs.TypeUser[]) {
|
|||||||
|
|
||||||
return { users, userStatusesById };
|
return { users, userStatusesById };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildApiUserSettings({
|
|
||||||
autoarchived,
|
|
||||||
reportSpam,
|
|
||||||
addContact,
|
|
||||||
blockContact,
|
|
||||||
}: GramJs.PeerSettings): ApiUserSettings {
|
|
||||||
return {
|
|
||||||
isAutoArchived: Boolean(autoarchived),
|
|
||||||
canReportSpam: Boolean(reportSpam),
|
|
||||||
canAddContact: Boolean(addContact),
|
|
||||||
canBlockContact: Boolean(blockContact),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import {
|
|||||||
buildApiChatFolder,
|
buildApiChatFolder,
|
||||||
buildApiChatFolderFromSuggested,
|
buildApiChatFolderFromSuggested,
|
||||||
buildApiChatBotCommands,
|
buildApiChatBotCommands,
|
||||||
|
buildApiChatSettings,
|
||||||
} from '../apiBuilders/chats';
|
} from '../apiBuilders/chats';
|
||||||
import { buildApiMessage, buildMessageDraft } from '../apiBuilders/messages';
|
import { buildApiMessage, buildMessageDraft } from '../apiBuilders/messages';
|
||||||
import { buildApiUser, buildApiUsersAndStatuses } from '../apiBuilders/users';
|
import { buildApiUser, buildApiUsersAndStatuses } from '../apiBuilders/users';
|
||||||
@ -179,6 +180,20 @@ export function fetchFullChat(chat: ApiChat) {
|
|||||||
: getFullChatInfo(id);
|
: getFullChatInfo(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fetchChatSettings(chat: ApiChat) {
|
||||||
|
const { id, accessHash } = chat;
|
||||||
|
|
||||||
|
const result = await invokeRequest(new GramJs.messages.GetPeerSettings({
|
||||||
|
peer: buildInputPeer(id, accessHash),
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildApiChatSettings(result.settings);
|
||||||
|
}
|
||||||
|
|
||||||
export async function searchChats({ query }: { query: string }) {
|
export async function searchChats({ query }: { query: string }) {
|
||||||
const result = await invokeRequest(new GramJs.contacts.Search({ q: query }));
|
const result = await invokeRequest(new GramJs.contacts.Search({ q: query }));
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ export {
|
|||||||
} from './auth';
|
} from './auth';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
fetchChats, fetchFullChat, searchChats, requestChatUpdate,
|
fetchChats, fetchFullChat, searchChats, requestChatUpdate, fetchChatSettings,
|
||||||
saveDraft, clearDraft, fetchChat, updateChatMutedState,
|
saveDraft, clearDraft, fetchChat, updateChatMutedState,
|
||||||
createChannel, joinChannel, deleteChatUser, deleteChat, leaveChannel, deleteChannel, createGroupChat, editChatPhoto,
|
createChannel, joinChannel, deleteChatUser, deleteChat, leaveChannel, deleteChannel, createGroupChat, editChatPhoto,
|
||||||
toggleChatPinned, toggleChatArchived, toggleDialogUnread, setChatEnabledReactions,
|
toggleChatPinned, toggleChatArchived, toggleDialogUnread, setChatEnabledReactions,
|
||||||
@ -42,6 +42,7 @@ export {
|
|||||||
checkChatUsername, setChatUsername, updatePrivateLink,
|
checkChatUsername, setChatUsername, updatePrivateLink,
|
||||||
fetchExportedChatInvites, editExportedChatInvite, exportChatInvite, deleteExportedChatInvite,
|
fetchExportedChatInvites, editExportedChatInvite, exportChatInvite, deleteExportedChatInvite,
|
||||||
deleteRevokedExportedChatInvites, fetchChatInviteImporters, hideChatJoinRequest, hideAllChatJoinRequests,
|
deleteRevokedExportedChatInvites, fetchChatInviteImporters, hideChatJoinRequest, hideAllChatJoinRequests,
|
||||||
|
hideChatReportPanel,
|
||||||
} from './management';
|
} from './management';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@ -218,3 +218,11 @@ export function hideAllChatJoinRequests({
|
|||||||
link,
|
link,
|
||||||
}), true);
|
}), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function hideChatReportPanel(chat: ApiChat) {
|
||||||
|
const { id, accessHash } = chat;
|
||||||
|
|
||||||
|
return invokeRequest(new GramJs.messages.HidePeerSettingsBar({
|
||||||
|
peer: buildInputPeer(id, accessHash),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|||||||
@ -51,7 +51,6 @@ export async function fetchFullUser({
|
|||||||
'@type': 'updateUser',
|
'@type': 'updateUser',
|
||||||
id,
|
id,
|
||||||
user: {
|
user: {
|
||||||
settings: userWithFullInfo.settings,
|
|
||||||
fullInfo: userWithFullInfo.fullInfo,
|
fullInfo: userWithFullInfo.fullInfo,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -248,8 +247,8 @@ export async function fetchProfilePhotos(user?: ApiUser, chat?: ApiChat) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reportSpam(user: ApiUser) {
|
export function reportSpam(userOrChat: ApiUser | ApiChat) {
|
||||||
const { id, accessHash } = user;
|
const { id, accessHash } = userOrChat;
|
||||||
|
|
||||||
return invokeRequest(new GramJs.messages.ReportSpam({
|
return invokeRequest(new GramJs.messages.ReportSpam({
|
||||||
peer: buildInputPeer(id, accessHash),
|
peer: buildInputPeer(id, accessHash),
|
||||||
|
|||||||
@ -22,8 +22,9 @@ import {
|
|||||||
buildAvatarHash,
|
buildAvatarHash,
|
||||||
buildApiChatFromPreview,
|
buildApiChatFromPreview,
|
||||||
buildApiChatFolder,
|
buildApiChatFolder,
|
||||||
|
buildApiChatSettings,
|
||||||
} from './apiBuilders/chats';
|
} from './apiBuilders/chats';
|
||||||
import { buildApiUser, buildApiUserSettings, buildApiUserStatus } from './apiBuilders/users';
|
import { buildApiUser, buildApiUserStatus } from './apiBuilders/users';
|
||||||
import {
|
import {
|
||||||
buildMessageFromUpdate,
|
buildMessageFromUpdate,
|
||||||
isMessageWithMedia,
|
isMessageWithMedia,
|
||||||
@ -799,7 +800,7 @@ export function updater(update: Update, originRequest?: GramJs.AnyRequest) {
|
|||||||
id: user.id,
|
id: user.id,
|
||||||
user: {
|
user: {
|
||||||
...user,
|
...user,
|
||||||
...(settings && { settings: buildApiUserSettings(settings) }),
|
...(settings && { settings: buildApiChatSettings(settings) }),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -53,6 +53,8 @@ export interface ApiChat {
|
|||||||
accessHash?: string;
|
accessHash?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Obtained from GetChatSettings
|
||||||
|
settings?: ApiChatSettings;
|
||||||
// Obtained from GetFullChat / GetFullChannel
|
// Obtained from GetFullChat / GetFullChannel
|
||||||
fullInfo?: ApiChatFullInfo;
|
fullInfo?: ApiChatFullInfo;
|
||||||
// Obtained with UpdateUserTyping or UpdateChatUserTyping updates
|
// Obtained with UpdateUserTyping or UpdateChatUserTyping updates
|
||||||
@ -161,3 +163,10 @@ export interface ApiChatFolder {
|
|||||||
includedChatIds: string[];
|
includedChatIds: string[];
|
||||||
excludedChatIds: string[];
|
excludedChatIds: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiChatSettings {
|
||||||
|
isAutoArchived?: boolean;
|
||||||
|
canReportSpam?: boolean;
|
||||||
|
canAddContact?: boolean;
|
||||||
|
canBlockContact?: boolean;
|
||||||
|
}
|
||||||
|
|||||||
@ -26,14 +26,6 @@ export interface ApiUser {
|
|||||||
|
|
||||||
// Obtained from GetFullUser / UserFullInfo
|
// Obtained from GetFullUser / UserFullInfo
|
||||||
fullInfo?: ApiUserFullInfo;
|
fullInfo?: ApiUserFullInfo;
|
||||||
settings?: ApiUserSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ApiUserSettings {
|
|
||||||
isAutoArchived?: boolean;
|
|
||||||
canReportSpam?: boolean;
|
|
||||||
canAddContact?: boolean;
|
|
||||||
canBlockContact?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApiUserFullInfo {
|
export interface ApiUserFullInfo {
|
||||||
|
|||||||
@ -130,7 +130,7 @@ const VideoPlayer: FC<OwnProps> = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isMediaViewerOpen) return;
|
if (!isMediaViewerOpen) return undefined;
|
||||||
const togglePayingStateBySpace = (e: KeyboardEvent) => {
|
const togglePayingStateBySpace = (e: KeyboardEvent) => {
|
||||||
if (e.key === 'Enter' || e.key === ' ') {
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
.UserReportPanel {
|
.ChatReportPanel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
186
src/components/middle/ChatReportPanel.tsx
Normal file
186
src/components/middle/ChatReportPanel.tsx
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
import React, {
|
||||||
|
FC, memo, useCallback, useState,
|
||||||
|
} from '../../lib/teact/teact';
|
||||||
|
import { withGlobal, getActions } from '../../global';
|
||||||
|
|
||||||
|
import { ApiChat, ApiChatSettings, ApiUser } from '../../api/types';
|
||||||
|
|
||||||
|
import { selectChat, selectUser } from '../../global/selectors';
|
||||||
|
import {
|
||||||
|
getChatTitle, getUserFirstOrLastName, getUserFullName, isChatBasicGroup, isUserId,
|
||||||
|
} from '../../global/helpers';
|
||||||
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
|
import useFlag from '../../hooks/useFlag';
|
||||||
|
|
||||||
|
import Button from '../ui/Button';
|
||||||
|
import ConfirmDialog from '../ui/ConfirmDialog';
|
||||||
|
import Checkbox from '../ui/Checkbox';
|
||||||
|
|
||||||
|
import './ChatReportPanel.scss';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
chatId: string;
|
||||||
|
className?: string;
|
||||||
|
settings?: ApiChatSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
type StateProps = {
|
||||||
|
currentUserId?: string;
|
||||||
|
chat?: ApiChat;
|
||||||
|
user?: ApiUser;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ChatReportPanel: FC<OwnProps & StateProps> = ({
|
||||||
|
chatId, className, chat, user, settings, currentUserId,
|
||||||
|
}) => {
|
||||||
|
const {
|
||||||
|
addContact,
|
||||||
|
blockContact,
|
||||||
|
reportSpam,
|
||||||
|
deleteChat,
|
||||||
|
leaveChannel,
|
||||||
|
deleteChatUser,
|
||||||
|
deleteHistory,
|
||||||
|
toggleChatArchived,
|
||||||
|
hideChatReportPanel,
|
||||||
|
} = getActions();
|
||||||
|
|
||||||
|
const lang = useLang();
|
||||||
|
const [isBlockUserModalOpen, openBlockUserModal, closeBlockUserModal] = useFlag();
|
||||||
|
const [shouldReportSpam, setShouldReportSpam] = useState<boolean>(true);
|
||||||
|
const [shouldDeleteChat, setShouldDeleteChat] = useState<boolean>(true);
|
||||||
|
const { accessHash } = chat || {};
|
||||||
|
const {
|
||||||
|
isAutoArchived, canReportSpam, canAddContact, canBlockContact,
|
||||||
|
} = settings || {};
|
||||||
|
const isBasicGroup = chat && isChatBasicGroup(chat);
|
||||||
|
|
||||||
|
const handleAddContact = useCallback(() => {
|
||||||
|
addContact({ chatId });
|
||||||
|
if (isAutoArchived) {
|
||||||
|
toggleChatArchived({ chatId });
|
||||||
|
}
|
||||||
|
}, [addContact, isAutoArchived, toggleChatArchived, chatId]);
|
||||||
|
|
||||||
|
const handleConfirmBlock = useCallback(() => {
|
||||||
|
closeBlockUserModal();
|
||||||
|
blockContact({ contactId: chatId, accessHash });
|
||||||
|
if (canReportSpam && shouldReportSpam) {
|
||||||
|
reportSpam({ chatId });
|
||||||
|
}
|
||||||
|
if (shouldDeleteChat) {
|
||||||
|
deleteChat({ chatId });
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
accessHash, blockContact, closeBlockUserModal, deleteChat, reportSpam, canReportSpam, shouldDeleteChat,
|
||||||
|
shouldReportSpam, chatId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const handleCloseReportPanel = useCallback(() => {
|
||||||
|
hideChatReportPanel({ chatId });
|
||||||
|
}, [chatId, hideChatReportPanel]);
|
||||||
|
|
||||||
|
const handleChatReportSpam = useCallback(() => {
|
||||||
|
closeBlockUserModal();
|
||||||
|
reportSpam({ chatId });
|
||||||
|
if (isBasicGroup) {
|
||||||
|
deleteChatUser({ chatId, userId: currentUserId });
|
||||||
|
deleteHistory({ chatId, shouldDeleteForAll: false });
|
||||||
|
} else {
|
||||||
|
leaveChannel({ chatId });
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
chatId, closeBlockUserModal, currentUserId, deleteChatUser, deleteHistory, isBasicGroup, leaveChannel, reportSpam,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!settings) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={buildClassName('ChatReportPanel', className)} dir={lang.isRtl ? 'rtl' : undefined}>
|
||||||
|
{canAddContact && (
|
||||||
|
<Button
|
||||||
|
isText
|
||||||
|
ripple
|
||||||
|
fluid
|
||||||
|
size="tiny"
|
||||||
|
className="UserReportPanel--Button"
|
||||||
|
onClick={handleAddContact}
|
||||||
|
>
|
||||||
|
{lang('lng_new_contact_add')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{canBlockContact && (
|
||||||
|
<Button
|
||||||
|
color="danger"
|
||||||
|
isText
|
||||||
|
fluid
|
||||||
|
size="tiny"
|
||||||
|
className="UserReportPanel--Button"
|
||||||
|
onClick={openBlockUserModal}
|
||||||
|
>
|
||||||
|
{lang('lng_new_contact_block')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{canReportSpam && !canBlockContact && (
|
||||||
|
<Button
|
||||||
|
color="danger"
|
||||||
|
isText
|
||||||
|
fluid
|
||||||
|
size="tiny"
|
||||||
|
className="UserReportPanel--Button"
|
||||||
|
onClick={openBlockUserModal}
|
||||||
|
>
|
||||||
|
{lang('lng_report_spam_and_leave')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
round
|
||||||
|
ripple
|
||||||
|
size="tiny"
|
||||||
|
color="translucent"
|
||||||
|
onClick={handleCloseReportPanel}
|
||||||
|
ariaLabel={lang('Close')}
|
||||||
|
>
|
||||||
|
<i className="icon-close" />
|
||||||
|
</Button>
|
||||||
|
<ConfirmDialog
|
||||||
|
isOpen={isBlockUserModalOpen}
|
||||||
|
onClose={closeBlockUserModal}
|
||||||
|
title={lang('BlockUserTitle', user ? getUserFirstOrLastName(user) : getChatTitle(lang, chat!))}
|
||||||
|
text={user
|
||||||
|
? lang('UserInfo.BlockConfirmationTitle', getUserFullName(user))
|
||||||
|
: lang('Chat.Confirm.ReportSpam.Group')}
|
||||||
|
isButtonsInOneRow
|
||||||
|
confirmIsDestructive
|
||||||
|
confirmLabel={lang('Block')}
|
||||||
|
confirmHandler={user ? handleConfirmBlock : handleChatReportSpam}
|
||||||
|
>
|
||||||
|
{user && canReportSpam && (
|
||||||
|
<Checkbox
|
||||||
|
label={lang('DeleteReportSpam')}
|
||||||
|
checked={shouldReportSpam}
|
||||||
|
onCheck={setShouldReportSpam}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{user && (
|
||||||
|
<Checkbox
|
||||||
|
label={lang('DeleteThisChat')}
|
||||||
|
checked={shouldDeleteChat}
|
||||||
|
onCheck={setShouldDeleteChat}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</ConfirmDialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(withGlobal<OwnProps>(
|
||||||
|
(global, { chatId }): StateProps => ({
|
||||||
|
currentUserId: global.currentUserId,
|
||||||
|
chat: selectChat(global, chatId),
|
||||||
|
user: isUserId(chatId) ? selectUser(global, chatId) : undefined,
|
||||||
|
}),
|
||||||
|
)(ChatReportPanel));
|
||||||
@ -42,7 +42,6 @@ import {
|
|||||||
selectIsUserBlocked,
|
selectIsUserBlocked,
|
||||||
selectPinnedIds,
|
selectPinnedIds,
|
||||||
selectTheme,
|
selectTheme,
|
||||||
selectUser,
|
|
||||||
} from '../../global/selectors';
|
} from '../../global/selectors';
|
||||||
import {
|
import {
|
||||||
getCanPostInChat, getMessageSendingRestrictionReason, isChatChannel, isChatSuperGroup, isUserId,
|
getCanPostInChat, getMessageSendingRestrictionReason, isChatChannel, isChatSuperGroup, isUserId,
|
||||||
@ -107,7 +106,7 @@ type StateProps = {
|
|||||||
currentTransitionKey: number;
|
currentTransitionKey: number;
|
||||||
messageLists?: GlobalMessageList[];
|
messageLists?: GlobalMessageList[];
|
||||||
isChannel?: boolean;
|
isChannel?: boolean;
|
||||||
isUserFull?: boolean;
|
areChatSettingsLoaded?: boolean;
|
||||||
canSubscribe?: boolean;
|
canSubscribe?: boolean;
|
||||||
canStartBot?: boolean;
|
canStartBot?: boolean;
|
||||||
canRestartBot?: boolean;
|
canRestartBot?: boolean;
|
||||||
@ -150,7 +149,7 @@ const MiddleColumn: FC<StateProps> = ({
|
|||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
currentTransitionKey,
|
currentTransitionKey,
|
||||||
isChannel,
|
isChannel,
|
||||||
isUserFull,
|
areChatSettingsLoaded,
|
||||||
canSubscribe,
|
canSubscribe,
|
||||||
canStartBot,
|
canStartBot,
|
||||||
canRestartBot,
|
canRestartBot,
|
||||||
@ -161,7 +160,7 @@ const MiddleColumn: FC<StateProps> = ({
|
|||||||
openChat,
|
openChat,
|
||||||
unpinAllMessages,
|
unpinAllMessages,
|
||||||
loadUser,
|
loadUser,
|
||||||
loadFullUser,
|
loadChatSettings,
|
||||||
closeLocalTextSearch,
|
closeLocalTextSearch,
|
||||||
exitMessageSelectMode,
|
exitMessageSelectMode,
|
||||||
closePaymentModal,
|
closePaymentModal,
|
||||||
@ -258,10 +257,10 @@ const MiddleColumn: FC<StateProps> = ({
|
|||||||
}, [chatId, isPrivate, loadUser]);
|
}, [chatId, isPrivate, loadUser]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isPrivate && !isUserFull && lastSyncTime) {
|
if (!areChatSettingsLoaded && lastSyncTime) {
|
||||||
loadFullUser({ userId: chatId });
|
loadChatSettings({ chatId });
|
||||||
}
|
}
|
||||||
}, [chatId, isPrivate, isUserFull, lastSyncTime, loadFullUser]);
|
}, [chatId, isPrivate, areChatSettingsLoaded, lastSyncTime, loadChatSettings]);
|
||||||
|
|
||||||
const handleDragEnter = useCallback((e: React.DragEvent<HTMLDivElement>) => {
|
const handleDragEnter = useCallback((e: React.DragEvent<HTMLDivElement>) => {
|
||||||
if (IS_TOUCH_ENV) {
|
if (IS_TOUCH_ENV) {
|
||||||
@ -587,7 +586,6 @@ export default memo(withGlobal(
|
|||||||
const isPrivate = isUserId(chatId);
|
const isPrivate = isUserId(chatId);
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
const bot = selectChatBot(global, chatId);
|
const bot = selectChatBot(global, chatId);
|
||||||
const user = isPrivate ? selectUser(global, chatId) : undefined;
|
|
||||||
const pinnedIds = selectPinnedIds(global, chatId);
|
const pinnedIds = selectPinnedIds(global, chatId);
|
||||||
const { chatId: audioChatId, messageId: audioMessageId } = global.audioPlayer;
|
const { chatId: audioChatId, messageId: audioMessageId } = global.audioPlayer;
|
||||||
|
|
||||||
@ -609,7 +607,7 @@ export default memo(withGlobal(
|
|||||||
threadId,
|
threadId,
|
||||||
messageListType,
|
messageListType,
|
||||||
isPrivate,
|
isPrivate,
|
||||||
isUserFull: Boolean(user?.settings),
|
areChatSettingsLoaded: Boolean(chat?.settings),
|
||||||
canPost: !isPinnedMessageList && (!chat || canPost) && !isBotNotStarted,
|
canPost: !isPinnedMessageList && (!chat || canPost) && !isBotNotStarted,
|
||||||
isPinnedMessageList,
|
isPinnedMessageList,
|
||||||
isScheduledMessageList,
|
isScheduledMessageList,
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import {
|
|||||||
} from '../../config';
|
} from '../../config';
|
||||||
import { IS_SINGLE_COLUMN_LAYOUT, IS_TABLET_COLUMN_LAYOUT } from '../../util/environment';
|
import { IS_SINGLE_COLUMN_LAYOUT, IS_TABLET_COLUMN_LAYOUT } from '../../util/environment';
|
||||||
import {
|
import {
|
||||||
getChatTitle, getMessageKey, getPrivateChatUserId, getSenderTitle, isUserId,
|
getChatTitle, getMessageKey, getSenderTitle, isUserId,
|
||||||
} from '../../global/helpers';
|
} from '../../global/helpers';
|
||||||
import {
|
import {
|
||||||
selectAllowedMessageActions,
|
selectAllowedMessageActions,
|
||||||
@ -35,7 +35,6 @@ import {
|
|||||||
selectScheduledIds,
|
selectScheduledIds,
|
||||||
selectThreadInfo,
|
selectThreadInfo,
|
||||||
selectThreadTopMessageId,
|
selectThreadTopMessageId,
|
||||||
selectUser,
|
|
||||||
} from '../../global/selectors';
|
} from '../../global/selectors';
|
||||||
import useEnsureMessage from '../../hooks/useEnsureMessage';
|
import useEnsureMessage from '../../hooks/useEnsureMessage';
|
||||||
import useWindowSize from '../../hooks/useWindowSize';
|
import useWindowSize from '../../hooks/useWindowSize';
|
||||||
@ -54,7 +53,7 @@ import HeaderActions from './HeaderActions';
|
|||||||
import HeaderPinnedMessage from './HeaderPinnedMessage';
|
import HeaderPinnedMessage from './HeaderPinnedMessage';
|
||||||
import AudioPlayer from './AudioPlayer';
|
import AudioPlayer from './AudioPlayer';
|
||||||
import GroupCallTopPane from '../calls/group/GroupCallTopPane';
|
import GroupCallTopPane from '../calls/group/GroupCallTopPane';
|
||||||
import UserReportPanel from './UserReportPanel';
|
import ChatReportPanel from './ChatReportPanel';
|
||||||
|
|
||||||
import './MiddleHeader.scss';
|
import './MiddleHeader.scss';
|
||||||
|
|
||||||
@ -83,7 +82,6 @@ type StateProps = {
|
|||||||
isChatWithSelf?: boolean;
|
isChatWithSelf?: boolean;
|
||||||
isChatWithBot?: boolean;
|
isChatWithBot?: boolean;
|
||||||
lastSyncTime?: number;
|
lastSyncTime?: number;
|
||||||
shouldShowUserReportPanel?: boolean;
|
|
||||||
shouldSkipHistoryAnimations?: boolean;
|
shouldSkipHistoryAnimations?: boolean;
|
||||||
currentTransitionKey: number;
|
currentTransitionKey: number;
|
||||||
connectionState?: GlobalState['connectionState'];
|
connectionState?: GlobalState['connectionState'];
|
||||||
@ -109,7 +107,6 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
|||||||
isChatWithSelf,
|
isChatWithSelf,
|
||||||
isChatWithBot,
|
isChatWithBot,
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
shouldShowUserReportPanel,
|
|
||||||
shouldSkipHistoryAnimations,
|
shouldSkipHistoryAnimations,
|
||||||
currentTransitionKey,
|
currentTransitionKey,
|
||||||
connectionState,
|
connectionState,
|
||||||
@ -136,6 +133,7 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
|||||||
? pinnedMessageIds.length : (pinnedMessageIds ? 1 : undefined);
|
? pinnedMessageIds.length : (pinnedMessageIds ? 1 : undefined);
|
||||||
const chatTitleLength = chat && getChatTitle(lang, chat).length;
|
const chatTitleLength = chat && getChatTitle(lang, chat).length;
|
||||||
const topMessageTitle = topMessageSender ? getSenderTitle(lang, topMessageSender) : undefined;
|
const topMessageTitle = topMessageSender ? getSenderTitle(lang, topMessageSender) : undefined;
|
||||||
|
const { settings } = chat || {};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (threadId === MAIN_THREAD_ID && lastSyncTime && isReady) {
|
if (threadId === MAIN_THREAD_ID && lastSyncTime && isReady) {
|
||||||
@ -237,6 +235,13 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
|||||||
&& windowWidth < SAFE_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN
|
&& windowWidth < SAFE_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const hasChatSettings = Boolean(settings?.canAddContact || settings?.canBlockContact || settings?.canReportSpam);
|
||||||
|
const {
|
||||||
|
shouldRender: shouldShowChatReportPanel,
|
||||||
|
transitionClassNames: chatReportPanelClassNames,
|
||||||
|
} = useShowTransition(hasChatSettings);
|
||||||
|
const renderingChatSettings = useCurrentOrPrev(hasChatSettings ? settings : undefined, true);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
shouldRender: shouldRenderAudioPlayer,
|
shouldRender: shouldRenderAudioPlayer,
|
||||||
transitionClassNames: audioPlayerClassNames,
|
transitionClassNames: audioPlayerClassNames,
|
||||||
@ -400,7 +405,14 @@ const MiddleHeader: FC<OwnProps & StateProps> = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{shouldShowUserReportPanel && <UserReportPanel key={chatId} userId={chatId} />}
|
{shouldShowChatReportPanel && (
|
||||||
|
<ChatReportPanel
|
||||||
|
key={chatId}
|
||||||
|
chatId={chatId}
|
||||||
|
settings={renderingChatSettings}
|
||||||
|
className={chatReportPanelClassNames}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="header-tools">
|
<div className="header-tools">
|
||||||
{isAudioPlayerRendered && (
|
{isAudioPlayerRendered && (
|
||||||
@ -425,9 +437,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
(global, { chatId, threadId, messageListType }): StateProps => {
|
(global, { chatId, threadId, messageListType }): StateProps => {
|
||||||
const { isLeftColumnShown, lastSyncTime, shouldSkipHistoryAnimations } = global;
|
const { isLeftColumnShown, lastSyncTime, shouldSkipHistoryAnimations } = global;
|
||||||
const chat = selectChat(global, chatId);
|
const chat = selectChat(global, chatId);
|
||||||
const userId = chat && getPrivateChatUserId(chat);
|
|
||||||
const user = userId ? selectUser(global, userId) : undefined;
|
|
||||||
|
|
||||||
const { typingStatus } = chat || {};
|
const { typingStatus } = chat || {};
|
||||||
|
|
||||||
const { chatId: audioChatId, messageId: audioMessageId } = global.audioPlayer;
|
const { chatId: audioChatId, messageId: audioMessageId } = global.audioPlayer;
|
||||||
@ -455,7 +464,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
audioMessage,
|
audioMessage,
|
||||||
chat,
|
chat,
|
||||||
messagesCount,
|
messagesCount,
|
||||||
shouldShowUserReportPanel: Boolean(user?.settings?.canAddContact || user?.settings?.canBlockContact),
|
|
||||||
isChatWithSelf: selectIsChatWithSelf(global, chatId),
|
isChatWithSelf: selectIsChatWithSelf(global, chatId),
|
||||||
isChatWithBot: chat && selectIsChatWithBot(global, chat),
|
isChatWithBot: chat && selectIsChatWithBot(global, chat),
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
|
|||||||
@ -1,125 +0,0 @@
|
|||||||
import React, {
|
|
||||||
FC, memo, useCallback, useState,
|
|
||||||
} from '../../lib/teact/teact';
|
|
||||||
import { withGlobal, getActions } from '../../global';
|
|
||||||
|
|
||||||
import { ApiUser } from '../../api/types';
|
|
||||||
|
|
||||||
import { selectUser } from '../../global/selectors';
|
|
||||||
import { getUserFirstOrLastName, getUserFullName } from '../../global/helpers';
|
|
||||||
import useLang from '../../hooks/useLang';
|
|
||||||
import useFlag from '../../hooks/useFlag';
|
|
||||||
|
|
||||||
import Button from '../ui/Button';
|
|
||||||
import ConfirmDialog from '../ui/ConfirmDialog';
|
|
||||||
import Checkbox from '../ui/Checkbox';
|
|
||||||
|
|
||||||
import './UserReportPanel.scss';
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
userId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type StateProps = {
|
|
||||||
user?: ApiUser;
|
|
||||||
};
|
|
||||||
|
|
||||||
const UserReportPanel: FC<OwnProps & StateProps> = ({ userId, user }) => {
|
|
||||||
const {
|
|
||||||
addContact,
|
|
||||||
blockContact,
|
|
||||||
reportSpam,
|
|
||||||
deleteChat,
|
|
||||||
toggleChatArchived,
|
|
||||||
} = getActions();
|
|
||||||
|
|
||||||
const lang = useLang();
|
|
||||||
const [isBlockUserModalOpen, openBlockUserModal, closeBlockUserModal] = useFlag();
|
|
||||||
const [shouldReportSpam, setShouldReportSpam] = useState<boolean>(true);
|
|
||||||
const [shouldDeleteChat, setShouldDeleteChat] = useState<boolean>(true);
|
|
||||||
const { settings, accessHash } = user || {};
|
|
||||||
const {
|
|
||||||
isAutoArchived, canReportSpam, canAddContact, canBlockContact,
|
|
||||||
} = settings || {};
|
|
||||||
const handleAddContact = useCallback(() => {
|
|
||||||
addContact({ userId });
|
|
||||||
if (isAutoArchived) {
|
|
||||||
toggleChatArchived({ chatId: userId });
|
|
||||||
}
|
|
||||||
}, [addContact, isAutoArchived, toggleChatArchived, userId]);
|
|
||||||
|
|
||||||
const handleConfirmBlock = useCallback(() => {
|
|
||||||
closeBlockUserModal();
|
|
||||||
blockContact({ contactId: userId, accessHash });
|
|
||||||
if (canReportSpam && shouldReportSpam) {
|
|
||||||
reportSpam({ userId });
|
|
||||||
}
|
|
||||||
if (shouldDeleteChat) {
|
|
||||||
deleteChat({ chatId: userId });
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
accessHash, blockContact, closeBlockUserModal, deleteChat, reportSpam, canReportSpam, shouldDeleteChat,
|
|
||||||
shouldReportSpam, userId,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (!settings) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="UserReportPanel">
|
|
||||||
{canAddContact && (
|
|
||||||
<Button
|
|
||||||
isText
|
|
||||||
ripple
|
|
||||||
fluid
|
|
||||||
size="tiny"
|
|
||||||
className="UserReportPanel--Button"
|
|
||||||
onClick={handleAddContact}
|
|
||||||
>
|
|
||||||
{lang('lng_new_contact_add')}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{canBlockContact && (
|
|
||||||
<Button
|
|
||||||
color="danger"
|
|
||||||
isText
|
|
||||||
ripple
|
|
||||||
fluid
|
|
||||||
size="tiny"
|
|
||||||
className="UserReportPanel--Button"
|
|
||||||
onClick={openBlockUserModal}
|
|
||||||
>
|
|
||||||
{lang('lng_new_contact_block')}
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
<ConfirmDialog
|
|
||||||
isOpen={isBlockUserModalOpen}
|
|
||||||
onClose={closeBlockUserModal}
|
|
||||||
title={lang('BlockUserTitle', getUserFirstOrLastName(user))}
|
|
||||||
text={lang('UserInfo.BlockConfirmationTitle', getUserFullName(user))}
|
|
||||||
isButtonsInOneRow
|
|
||||||
confirmIsDestructive
|
|
||||||
confirmLabel={lang('Block')}
|
|
||||||
confirmHandler={handleConfirmBlock}
|
|
||||||
>
|
|
||||||
{canReportSpam && (
|
|
||||||
<Checkbox
|
|
||||||
label={lang('DeleteReportSpam')}
|
|
||||||
checked={shouldReportSpam}
|
|
||||||
onCheck={setShouldReportSpam}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<Checkbox
|
|
||||||
label={lang('DeleteThisChat')}
|
|
||||||
checked={shouldDeleteChat}
|
|
||||||
onCheck={setShouldDeleteChat}
|
|
||||||
/>
|
|
||||||
</ConfirmDialog>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(withGlobal<OwnProps>(
|
|
||||||
(global, { userId }): StateProps => ({ user: selectUser(global, userId) }),
|
|
||||||
)(UserReportPanel));
|
|
||||||
@ -981,6 +981,17 @@ addActionHandler('setChatEnabledReactions', async (global, actions, payload) =>
|
|||||||
void loadFullChat(chat);
|
void loadFullChat(chat);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('loadChatSettings', async (global, actions, payload) => {
|
||||||
|
const { chatId } = payload!;
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
if (!chat) return undefined;
|
||||||
|
|
||||||
|
const settings = await callApi('fetchChatSettings', chat);
|
||||||
|
if (!settings) return undefined;
|
||||||
|
|
||||||
|
return updateChat(getGlobal(), chat.id, { settings });
|
||||||
|
});
|
||||||
|
|
||||||
async function loadChats(
|
async function loadChats(
|
||||||
listType: 'active' | 'archived', offsetId?: string, offsetDate?: number, shouldReplace = false,
|
listType: 'active' | 'archived', offsetId?: string, offsetDate?: number, shouldReplace = false,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@ -357,3 +357,16 @@ addActionHandler('hideAllChatJoinRequests', async (global, actions, payload) =>
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addActionHandler('hideChatReportPanel', async (global, actions, payload) => {
|
||||||
|
const { chatId } = payload!;
|
||||||
|
const chat = selectChat(global, chatId);
|
||||||
|
if (!chat) return undefined;
|
||||||
|
|
||||||
|
const result = await callApi('hideChatReportPanel', chat);
|
||||||
|
if (!result) return undefined;
|
||||||
|
|
||||||
|
return updateChat(getGlobal(), chatId, {
|
||||||
|
settings: undefined,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@ -268,13 +268,13 @@ addActionHandler('addContact', (global, actions, payload) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
addActionHandler('reportSpam', (global, actions, payload) => {
|
addActionHandler('reportSpam', (global, actions, payload) => {
|
||||||
const { userId } = payload!;
|
const { chatId } = payload!;
|
||||||
const user = selectUser(global, userId);
|
const userOrChat = isUserId(chatId) ? selectUser(global, chatId) : selectChat(global, chatId);
|
||||||
if (!user) {
|
if (!userOrChat) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void callApi('reportSpam', user);
|
void callApi('reportSpam', userOrChat);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function searchUsers(query: string) {
|
async function searchUsers(query: string) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { ApiUser, ApiUserStatus } from '../../api/types';
|
|||||||
|
|
||||||
import { omit, pick } from '../../util/iteratees';
|
import { omit, pick } from '../../util/iteratees';
|
||||||
import { MEMO_EMPTY_ARRAY } from '../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../util/memo';
|
||||||
|
import { updateChat } from './chats';
|
||||||
|
|
||||||
export function replaceUsers(global: GlobalState, newById: Record<string, ApiUser>): GlobalState {
|
export function replaceUsers(global: GlobalState, newById: Record<string, ApiUser>): GlobalState {
|
||||||
return {
|
return {
|
||||||
@ -133,13 +134,17 @@ export function deleteContact(global: GlobalState, userId: string): GlobalState
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return replaceUsers(global, {
|
global = replaceUsers(global, {
|
||||||
...byId,
|
...byId,
|
||||||
[userId]: {
|
[userId]: {
|
||||||
...byId[userId],
|
...byId[userId],
|
||||||
isContact: undefined,
|
isContact: undefined,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return updateChat(global, userId, {
|
||||||
|
settings: undefined,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateUserSearch(
|
export function updateUserSearch(
|
||||||
|
|||||||
@ -533,7 +533,7 @@ export type NonTypedActionNames = (
|
|||||||
// chats
|
// chats
|
||||||
'preloadTopChatMessages' | 'loadAllChats' | 'openChatWithInfo' | 'openLinkedChat' |
|
'preloadTopChatMessages' | 'loadAllChats' | 'openChatWithInfo' | 'openLinkedChat' |
|
||||||
'openSupportChat' | 'openTipsChat' | 'focusMessageInComments' | 'openChatByPhoneNumber' |
|
'openSupportChat' | 'openTipsChat' | 'focusMessageInComments' | 'openChatByPhoneNumber' |
|
||||||
'loadFullChat' | 'loadTopChats' | 'requestChatUpdate' | 'updateChatMutedState' |
|
'loadChatSettings' | 'loadFullChat' | 'loadTopChats' | 'requestChatUpdate' | 'updateChatMutedState' |
|
||||||
'joinChannel' | 'leaveChannel' | 'deleteChannel' | 'toggleChatPinned' | 'toggleChatArchived' | 'toggleChatUnread' |
|
'joinChannel' | 'leaveChannel' | 'deleteChannel' | 'toggleChatPinned' | 'toggleChatArchived' | 'toggleChatUnread' |
|
||||||
'loadChatFolders' | 'loadRecommendedChatFolders' | 'editChatFolder' | 'addChatFolder' | 'deleteChatFolder' |
|
'loadChatFolders' | 'loadRecommendedChatFolders' | 'editChatFolder' | 'addChatFolder' | 'deleteChatFolder' |
|
||||||
'updateChat' | 'toggleSignatures' | 'loadGroupsForDiscussion' | 'linkDiscussionGroup' | 'unlinkDiscussionGroup' |
|
'updateChat' | 'toggleSignatures' | 'loadGroupsForDiscussion' | 'linkDiscussionGroup' | 'unlinkDiscussionGroup' |
|
||||||
@ -571,7 +571,7 @@ export type NonTypedActionNames = (
|
|||||||
'setEditingExportedInvite' | 'loadExportedChatInvites' | 'editExportedChatInvite' | 'exportChatInvite' |
|
'setEditingExportedInvite' | 'loadExportedChatInvites' | 'editExportedChatInvite' | 'exportChatInvite' |
|
||||||
'deleteExportedChatInvite' | 'deleteRevokedExportedChatInvites' | 'setOpenedInviteInfo' | 'loadChatInviteImporters' |
|
'deleteExportedChatInvite' | 'deleteRevokedExportedChatInvites' | 'setOpenedInviteInfo' | 'loadChatInviteImporters' |
|
||||||
'loadChatJoinRequests' | 'hideChatJoinRequest' | 'hideAllChatJoinRequests' | 'requestNextManagementScreen' |
|
'loadChatJoinRequests' | 'hideChatJoinRequest' | 'hideAllChatJoinRequests' | 'requestNextManagementScreen' |
|
||||||
'loadChatInviteRequesters' |
|
'loadChatInviteRequesters' | 'hideChatReportPanel' |
|
||||||
// groups
|
// groups
|
||||||
'togglePreHistoryHidden' | 'updateChatDefaultBannedRights' | 'updateChatMemberBannedRights' | 'updateChatAdmin' |
|
'togglePreHistoryHidden' | 'updateChatDefaultBannedRights' | 'updateChatMemberBannedRights' | 'updateChatAdmin' |
|
||||||
'acceptInviteConfirmation' |
|
'acceptInviteConfirmation' |
|
||||||
|
|||||||
@ -1028,6 +1028,7 @@ messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true
|
|||||||
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||||
messages.forwardMessages#cc30290b flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
messages.forwardMessages#cc30290b flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||||
|
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
||||||
messages.report#8953ab4e peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool;
|
messages.report#8953ab4e peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool;
|
||||||
messages.getChats#49e9528f id:Vector<long> = messages.Chats;
|
messages.getChats#49e9528f id:Vector<long> = messages.Chats;
|
||||||
messages.getFullChat#aeb00b34 chat_id:long = messages.ChatFull;
|
messages.getFullChat#aeb00b34 chat_id:long = messages.ChatFull;
|
||||||
@ -1078,6 +1079,7 @@ messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
|
|||||||
messages.editChatAbout#def60797 peer:InputPeer about:string = Bool;
|
messages.editChatAbout#def60797 peer:InputPeer about:string = Bool;
|
||||||
messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates;
|
messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates;
|
||||||
messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
|
messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
|
||||||
|
messages.hidePeerSettingsBar#4facb138 peer:InputPeer = Bool;
|
||||||
messages.getScheduledHistory#f516760b peer:InputPeer hash:long = messages.Messages;
|
messages.getScheduledHistory#f516760b peer:InputPeer hash:long = messages.Messages;
|
||||||
messages.sendScheduledMessages#bd38850a peer:InputPeer id:Vector<int> = Updates;
|
messages.sendScheduledMessages#bd38850a peer:InputPeer id:Vector<int> = Updates;
|
||||||
messages.deleteScheduledMessages#59ae2b16 peer:InputPeer id:Vector<int> = Updates;
|
messages.deleteScheduledMessages#59ae2b16 peer:InputPeer id:Vector<int> = Updates;
|
||||||
|
|||||||
@ -69,6 +69,7 @@
|
|||||||
"messages.sendMedia",
|
"messages.sendMedia",
|
||||||
"messages.forwardMessages",
|
"messages.forwardMessages",
|
||||||
"messages.reportSpam",
|
"messages.reportSpam",
|
||||||
|
"messages.getPeerSettings",
|
||||||
"messages.report",
|
"messages.report",
|
||||||
"messages.getChats",
|
"messages.getChats",
|
||||||
"messages.getFullChat",
|
"messages.getFullChat",
|
||||||
@ -124,6 +125,7 @@
|
|||||||
"messages.editChatAbout",
|
"messages.editChatAbout",
|
||||||
"messages.editChatDefaultBannedRights",
|
"messages.editChatDefaultBannedRights",
|
||||||
"messages.getEmojiKeywordsDifference",
|
"messages.getEmojiKeywordsDifference",
|
||||||
|
"messages.hidePeerSettingsBar",
|
||||||
"messages.getScheduledHistory",
|
"messages.getScheduledHistory",
|
||||||
"messages.sendScheduledMessages",
|
"messages.sendScheduledMessages",
|
||||||
"messages.deleteScheduledMessages",
|
"messages.deleteScheduledMessages",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user