Support "Report Peer" and "Report Profile Photo" (#126)
This commit is contained in:
parent
a7e2695f2e
commit
91c2015052
@ -11,7 +11,9 @@ import {
|
|||||||
ApiGroupCall,
|
ApiGroupCall,
|
||||||
ApiMessageEntity,
|
ApiMessageEntity,
|
||||||
ApiMessageEntityTypes,
|
ApiMessageEntityTypes,
|
||||||
ApiNewPoll, ApiPhoneCall,
|
ApiNewPoll,
|
||||||
|
ApiPhoto,
|
||||||
|
ApiPhoneCall,
|
||||||
ApiReportReason,
|
ApiReportReason,
|
||||||
ApiSendMessageAction,
|
ApiSendMessageAction,
|
||||||
ApiSticker,
|
ApiSticker,
|
||||||
@ -343,6 +345,20 @@ export function buildChatPhotoForLocalDb(photo: GramJs.TypePhoto) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildInputPhoto(photo: ApiPhoto) {
|
||||||
|
const localPhoto = localDb.photos[photo?.id];
|
||||||
|
|
||||||
|
if (!localPhoto) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new GramJs.InputPhoto(pick(localPhoto, [
|
||||||
|
'id',
|
||||||
|
'accessHash',
|
||||||
|
'fileReference',
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
export function buildInputContact({
|
export function buildInputContact({
|
||||||
phone,
|
phone,
|
||||||
firstName,
|
firstName,
|
||||||
|
|||||||
43
src/api/gramjs/methods/account.ts
Normal file
43
src/api/gramjs/methods/account.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import {
|
||||||
|
ApiChat, ApiPhoto, ApiReportReason, ApiUser,
|
||||||
|
} from '../../types';
|
||||||
|
import { invokeRequest } from './client';
|
||||||
|
import { Api as GramJs } from '../../../lib/gramjs';
|
||||||
|
import { buildInputPeer, buildInputReportReason, buildInputPhoto } from '../gramjsBuilders';
|
||||||
|
|
||||||
|
export async function reportPeer({
|
||||||
|
peer,
|
||||||
|
reason,
|
||||||
|
description,
|
||||||
|
}: {
|
||||||
|
peer: ApiChat | ApiUser; reason: ApiReportReason; description?: string;
|
||||||
|
}) {
|
||||||
|
const result = await invokeRequest(new GramJs.account.ReportPeer({
|
||||||
|
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||||
|
reason: buildInputReportReason(reason),
|
||||||
|
message: description,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function reportProfilePhoto({
|
||||||
|
peer,
|
||||||
|
photo,
|
||||||
|
reason,
|
||||||
|
description,
|
||||||
|
}: {
|
||||||
|
peer: ApiChat | ApiUser; photo: ApiPhoto; reason: ApiReportReason; description?: string;
|
||||||
|
}) {
|
||||||
|
const photoId = buildInputPhoto(photo);
|
||||||
|
if (!photoId) return undefined;
|
||||||
|
|
||||||
|
const result = await invokeRequest(new GramJs.account.ReportProfilePhoto({
|
||||||
|
peer: buildInputPeer(peer.id, peer.accessHash),
|
||||||
|
photoId,
|
||||||
|
reason: buildInputReportReason(reason),
|
||||||
|
message: description,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@ -2,6 +2,10 @@ export {
|
|||||||
destroy, disconnect, downloadMedia, fetchCurrentUser, repairFileReference,
|
destroy, disconnect, downloadMedia, fetchCurrentUser, repairFileReference,
|
||||||
} from './client';
|
} from './client';
|
||||||
|
|
||||||
|
export {
|
||||||
|
reportPeer, reportProfilePhoto,
|
||||||
|
} from './account';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
provideAuthPhoneNumber, provideAuthCode, provideAuthPassword, provideAuthRegistration, restartAuth, restartAuthWithQr,
|
provideAuthPhoneNumber, provideAuthCode, provideAuthPassword, provideAuthRegistration, restartAuth, restartAuthWithQr,
|
||||||
} from './auth';
|
} from './auth';
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
|
|
||||||
import React, {
|
import React, {
|
||||||
FC, memo, useCallback, useState,
|
FC, memo, useCallback, useMemo, useState,
|
||||||
} from '../../lib/teact/teact';
|
} from '../../lib/teact/teact';
|
||||||
import { getActions } from '../../global';
|
import { getActions } from '../../global';
|
||||||
|
|
||||||
import { ApiReportReason } from '../../api/types';
|
import { ApiPhoto, ApiReportReason } from '../../api/types';
|
||||||
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
@ -16,17 +16,27 @@ import InputText from '../ui/InputText';
|
|||||||
|
|
||||||
export type OwnProps = {
|
export type OwnProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
|
subject?: 'peer' | 'messages' | 'media';
|
||||||
|
chatId?: string;
|
||||||
|
photo?: ApiPhoto;
|
||||||
messageIds?: number[];
|
messageIds?: number[];
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
onCloseAnimationEnd?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ReportMessageModal: FC<OwnProps> = ({
|
const ReportModal: FC<OwnProps> = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
|
subject = 'messages',
|
||||||
|
chatId,
|
||||||
|
photo,
|
||||||
messageIds,
|
messageIds,
|
||||||
onClose,
|
onClose,
|
||||||
|
onCloseAnimationEnd,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
reportMessages,
|
reportMessages,
|
||||||
|
reportPeer,
|
||||||
|
reportProfilePhoto,
|
||||||
exitMessageSelectMode,
|
exitMessageSelectMode,
|
||||||
} = getActions();
|
} = getActions();
|
||||||
|
|
||||||
@ -34,10 +44,34 @@ const ReportMessageModal: FC<OwnProps> = ({
|
|||||||
const [description, setDescription] = useState('');
|
const [description, setDescription] = useState('');
|
||||||
|
|
||||||
const handleReport = useCallback(() => {
|
const handleReport = useCallback(() => {
|
||||||
reportMessages({ messageIds, reason: selectedReason, description });
|
switch (subject) {
|
||||||
exitMessageSelectMode();
|
case 'messages':
|
||||||
|
reportMessages({ messageIds, reason: selectedReason, description });
|
||||||
|
exitMessageSelectMode();
|
||||||
|
break;
|
||||||
|
case 'peer':
|
||||||
|
reportPeer({ chatId, reason: selectedReason, description });
|
||||||
|
break;
|
||||||
|
case 'media':
|
||||||
|
reportProfilePhoto({
|
||||||
|
chatId, photo, reason: selectedReason, description,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
onClose();
|
onClose();
|
||||||
}, [description, exitMessageSelectMode, messageIds, onClose, reportMessages, selectedReason]);
|
}, [
|
||||||
|
description,
|
||||||
|
exitMessageSelectMode,
|
||||||
|
messageIds,
|
||||||
|
photo,
|
||||||
|
onClose,
|
||||||
|
reportMessages,
|
||||||
|
selectedReason,
|
||||||
|
chatId,
|
||||||
|
reportProfilePhoto,
|
||||||
|
reportPeer,
|
||||||
|
subject,
|
||||||
|
]);
|
||||||
|
|
||||||
const handleSelectReason = useCallback((value: string) => {
|
const handleSelectReason = useCallback((value: string) => {
|
||||||
setSelectedReason(value as ApiReportReason);
|
setSelectedReason(value as ApiReportReason);
|
||||||
@ -49,7 +83,7 @@ const ReportMessageModal: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const REPORT_OPTIONS: { value: ApiReportReason; label: string }[] = [
|
const REPORT_OPTIONS: { value: ApiReportReason; label: string }[] = useMemo(() => [
|
||||||
{ value: 'spam', label: lang('lng_report_reason_spam') },
|
{ value: 'spam', label: lang('lng_report_reason_spam') },
|
||||||
{ value: 'violence', label: lang('lng_report_reason_violence') },
|
{ value: 'violence', label: lang('lng_report_reason_violence') },
|
||||||
{ value: 'pornography', label: lang('lng_report_reason_pornography') },
|
{ value: 'pornography', label: lang('lng_report_reason_pornography') },
|
||||||
@ -58,19 +92,28 @@ const ReportMessageModal: FC<OwnProps> = ({
|
|||||||
{ value: 'illegalDrugs', label: 'Illegal Drugs' },
|
{ value: 'illegalDrugs', label: 'Illegal Drugs' },
|
||||||
{ value: 'personalDetails', label: 'Personal Details' },
|
{ value: 'personalDetails', label: 'Personal Details' },
|
||||||
{ value: 'other', label: lang('lng_report_reason_other') },
|
{ value: 'other', label: lang('lng_report_reason_other') },
|
||||||
];
|
], [lang]);
|
||||||
|
|
||||||
if (!messageIds) {
|
if (
|
||||||
|
(subject === 'messages' && !messageIds)
|
||||||
|
|| (subject === 'peer' && !chatId)
|
||||||
|
|| (subject === 'media' && (!chatId || !photo))
|
||||||
|
) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const title = subject === 'messages'
|
||||||
|
? lang('lng_report_message_title')
|
||||||
|
: lang('ReportPeer.Report');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onEnter={isOpen ? handleReport : undefined}
|
onEnter={isOpen ? handleReport : undefined}
|
||||||
|
onCloseAnimationEnd={onCloseAnimationEnd}
|
||||||
className="report"
|
className="report"
|
||||||
title={lang('lng_report_message_title')}
|
title={title}
|
||||||
>
|
>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name="report-message"
|
name="report-message"
|
||||||
@ -91,4 +134,4 @@ const ReportMessageModal: FC<OwnProps> = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(ReportMessageModal);
|
export default memo(ReportModal);
|
||||||
@ -50,6 +50,7 @@ import ListItem from '../../ui/ListItem';
|
|||||||
import Badge from './Badge';
|
import Badge from './Badge';
|
||||||
import ChatFolderModal from '../ChatFolderModal.async';
|
import ChatFolderModal from '../ChatFolderModal.async';
|
||||||
import ChatCallStatus from './ChatCallStatus';
|
import ChatCallStatus from './ChatCallStatus';
|
||||||
|
import ReportModal from '../../common/ReportModal';
|
||||||
import FakeIcon from '../../common/FakeIcon';
|
import FakeIcon from '../../common/FakeIcon';
|
||||||
|
|
||||||
import './Chat.scss';
|
import './Chat.scss';
|
||||||
@ -116,8 +117,10 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag();
|
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag();
|
||||||
const [isChatFolderModalOpen, openChatFolderModal, closeChatFolderModal] = useFlag();
|
const [isChatFolderModalOpen, openChatFolderModal, closeChatFolderModal] = useFlag();
|
||||||
|
const [isReportModalOpen, openReportModal, closeReportModal] = useFlag();
|
||||||
const [shouldRenderDeleteModal, markRenderDeleteModal, unmarkRenderDeleteModal] = useFlag();
|
const [shouldRenderDeleteModal, markRenderDeleteModal, unmarkRenderDeleteModal] = useFlag();
|
||||||
const [shouldRenderChatFolderModal, markRenderChatFolderModal, unmarkRenderChatFolderModal] = useFlag();
|
const [shouldRenderChatFolderModal, markRenderChatFolderModal, unmarkRenderChatFolderModal] = useFlag();
|
||||||
|
const [shouldRenderReportModal, markRenderReportModal, unmarkRenderReportModal] = useFlag();
|
||||||
|
|
||||||
const { lastMessage, typingStatus } = chat || {};
|
const { lastMessage, typingStatus } = chat || {};
|
||||||
const isAction = lastMessage && isActionMessage(lastMessage);
|
const isAction = lastMessage && isActionMessage(lastMessage);
|
||||||
@ -190,21 +193,27 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
focusLastMessage,
|
focusLastMessage,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function handleDelete() {
|
const handleDelete = useCallback(() => {
|
||||||
markRenderDeleteModal();
|
markRenderDeleteModal();
|
||||||
openDeleteModal();
|
openDeleteModal();
|
||||||
}
|
}, [markRenderDeleteModal, openDeleteModal]);
|
||||||
|
|
||||||
function handleChatFolderChange() {
|
const handleChatFolderChange = useCallback(() => {
|
||||||
markRenderChatFolderModal();
|
markRenderChatFolderModal();
|
||||||
openChatFolderModal();
|
openChatFolderModal();
|
||||||
}
|
}, [markRenderChatFolderModal, openChatFolderModal]);
|
||||||
|
|
||||||
|
const handleReport = useCallback(() => {
|
||||||
|
markRenderReportModal();
|
||||||
|
openReportModal();
|
||||||
|
}, [markRenderReportModal, openReportModal]);
|
||||||
|
|
||||||
const contextActions = useChatContextActions({
|
const contextActions = useChatContextActions({
|
||||||
chat,
|
chat,
|
||||||
user,
|
user,
|
||||||
handleDelete,
|
handleDelete,
|
||||||
handleChatFolderChange,
|
handleChatFolderChange,
|
||||||
|
handleReport,
|
||||||
folderId,
|
folderId,
|
||||||
isPinned,
|
isPinned,
|
||||||
isMuted,
|
isMuted,
|
||||||
@ -330,6 +339,15 @@ const Chat: FC<OwnProps & StateProps> = ({
|
|||||||
chatId={chatId}
|
chatId={chatId}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{shouldRenderReportModal && (
|
||||||
|
<ReportModal
|
||||||
|
isOpen={isReportModalOpen}
|
||||||
|
onClose={closeReportModal}
|
||||||
|
onCloseAnimationEnd={unmarkRenderReportModal}
|
||||||
|
chatId={chatId}
|
||||||
|
subject="peer"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck'
|
|||||||
import useHistoryBack from '../../hooks/useHistoryBack';
|
import useHistoryBack from '../../hooks/useHistoryBack';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import useMedia from '../../hooks/useMedia';
|
import useMedia from '../../hooks/useMedia';
|
||||||
|
import useFlag from '../../hooks/useFlag';
|
||||||
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
|
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
|
||||||
import usePrevious from '../../hooks/usePrevious';
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
import {
|
import {
|
||||||
@ -40,6 +41,7 @@ import {
|
|||||||
selectChatMessage,
|
selectChatMessage,
|
||||||
selectChatMessages,
|
selectChatMessages,
|
||||||
selectCurrentMediaSearch,
|
selectCurrentMediaSearch,
|
||||||
|
selectIsChatWithSelf,
|
||||||
selectListedIds,
|
selectListedIds,
|
||||||
selectOutlyingIds,
|
selectOutlyingIds,
|
||||||
selectScheduledMessage,
|
selectScheduledMessage,
|
||||||
@ -63,6 +65,7 @@ import PanZoom from './PanZoom';
|
|||||||
import SenderInfo from './SenderInfo';
|
import SenderInfo from './SenderInfo';
|
||||||
import SlideTransition from './SlideTransition';
|
import SlideTransition from './SlideTransition';
|
||||||
import ZoomControls from './ZoomControls';
|
import ZoomControls from './ZoomControls';
|
||||||
|
import ReportModal from '../common/ReportModal';
|
||||||
|
|
||||||
import './MediaViewer.scss';
|
import './MediaViewer.scss';
|
||||||
|
|
||||||
@ -71,6 +74,7 @@ type StateProps = {
|
|||||||
threadId?: number;
|
threadId?: number;
|
||||||
messageId?: number;
|
messageId?: number;
|
||||||
senderId?: string;
|
senderId?: string;
|
||||||
|
isChatWithSelf?: boolean;
|
||||||
origin?: MediaViewerOrigin;
|
origin?: MediaViewerOrigin;
|
||||||
avatarOwner?: ApiChat | ApiUser;
|
avatarOwner?: ApiChat | ApiUser;
|
||||||
profilePhotoIndex?: number;
|
profilePhotoIndex?: number;
|
||||||
@ -87,6 +91,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
threadId,
|
threadId,
|
||||||
messageId,
|
messageId,
|
||||||
senderId,
|
senderId,
|
||||||
|
isChatWithSelf,
|
||||||
origin,
|
origin,
|
||||||
avatarOwner,
|
avatarOwner,
|
||||||
profilePhotoIndex,
|
profilePhotoIndex,
|
||||||
@ -144,6 +149,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
const isGhostAnimation = animationLevel === 2;
|
const isGhostAnimation = animationLevel === 2;
|
||||||
|
|
||||||
/* Controls */
|
/* Controls */
|
||||||
|
const [isReportModalOpen, openReportModal, closeReportModal] = useFlag();
|
||||||
const [canPanZoomWrap, setCanPanZoomWrap] = useState(false);
|
const [canPanZoomWrap, setCanPanZoomWrap] = useState(false);
|
||||||
const [isZoomed, setIsZoomed] = useState<boolean>(false);
|
const [isZoomed, setIsZoomed] = useState<boolean>(false);
|
||||||
const [zoomLevel, setZoomLevel] = useState<number>(1);
|
const [zoomLevel, setZoomLevel] = useState<number>(1);
|
||||||
@ -186,6 +192,8 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
undefined,
|
undefined,
|
||||||
isGhostAnimation && ANIMATION_DURATION,
|
isGhostAnimation && ANIMATION_DURATION,
|
||||||
);
|
);
|
||||||
|
const avatarPhoto = avatarOwner?.photos?.[profilePhotoIndex!];
|
||||||
|
const canReport = !!avatarPhoto && profilePhotoIndex! > 0 && !isChatWithSelf;
|
||||||
|
|
||||||
const localBlobUrl = (photo || video) ? (photo || video)!.blobUrl : undefined;
|
const localBlobUrl = (photo || video) ? (photo || video)!.blobUrl : undefined;
|
||||||
let bestImageData = (!isVideo && (localBlobUrl || fullMediaBlobUrl)) || previewBlobUrl || pictogramBlobUrl;
|
let bestImageData = (!isVideo && (localBlobUrl || fullMediaBlobUrl)) || previewBlobUrl || pictogramBlobUrl;
|
||||||
@ -483,11 +491,20 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
isZoomed={isZoomed}
|
isZoomed={isZoomed}
|
||||||
message={message}
|
message={message}
|
||||||
fileName={fileName}
|
fileName={fileName}
|
||||||
|
canReport={canReport}
|
||||||
|
onReport={openReportModal}
|
||||||
onCloseMediaViewer={close}
|
onCloseMediaViewer={close}
|
||||||
onForward={handleForward}
|
onForward={handleForward}
|
||||||
onZoomToggle={handleZoomToggle}
|
onZoomToggle={handleZoomToggle}
|
||||||
isAvatar={isAvatar}
|
isAvatar={isAvatar}
|
||||||
/>
|
/>
|
||||||
|
<ReportModal
|
||||||
|
isOpen={isReportModalOpen}
|
||||||
|
onClose={closeReportModal}
|
||||||
|
subject="media"
|
||||||
|
photo={avatarPhoto}
|
||||||
|
chatId={avatarOwner?.id}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<PanZoom
|
<PanZoom
|
||||||
noWrap={!canPanZoomWrap}
|
noWrap={!canPanZoomWrap}
|
||||||
@ -565,6 +582,8 @@ export default memo(withGlobal(
|
|||||||
animationLevel,
|
animationLevel,
|
||||||
} = global.settings.byKey;
|
} = global.settings.byKey;
|
||||||
|
|
||||||
|
let isChatWithSelf = !!chatId && selectIsChatWithSelf(global, chatId);
|
||||||
|
|
||||||
if (origin === MediaViewerOrigin.SearchResult) {
|
if (origin === MediaViewerOrigin.SearchResult) {
|
||||||
if (!(chatId && messageId)) {
|
if (!(chatId && messageId)) {
|
||||||
return { animationLevel };
|
return { animationLevel };
|
||||||
@ -579,6 +598,7 @@ export default memo(withGlobal(
|
|||||||
chatId,
|
chatId,
|
||||||
messageId,
|
messageId,
|
||||||
senderId: message.senderId,
|
senderId: message.senderId,
|
||||||
|
isChatWithSelf,
|
||||||
origin,
|
origin,
|
||||||
message,
|
message,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
@ -587,11 +607,13 @@ export default memo(withGlobal(
|
|||||||
|
|
||||||
if (avatarOwnerId) {
|
if (avatarOwnerId) {
|
||||||
const sender = selectUser(global, avatarOwnerId) || selectChat(global, avatarOwnerId);
|
const sender = selectUser(global, avatarOwnerId) || selectChat(global, avatarOwnerId);
|
||||||
|
isChatWithSelf = selectIsChatWithSelf(global, avatarOwnerId);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
messageId: -1,
|
messageId: -1,
|
||||||
senderId: avatarOwnerId,
|
senderId: avatarOwnerId,
|
||||||
avatarOwner: sender,
|
avatarOwner: sender,
|
||||||
|
isChatWithSelf,
|
||||||
profilePhotoIndex: profilePhotoIndex || 0,
|
profilePhotoIndex: profilePhotoIndex || 0,
|
||||||
animationLevel,
|
animationLevel,
|
||||||
origin,
|
origin,
|
||||||
@ -635,6 +657,7 @@ export default memo(withGlobal(
|
|||||||
threadId,
|
threadId,
|
||||||
messageId,
|
messageId,
|
||||||
senderId: message.senderId,
|
senderId: message.senderId,
|
||||||
|
isChatWithSelf,
|
||||||
origin,
|
origin,
|
||||||
message,
|
message,
|
||||||
chatMessages,
|
chatMessages,
|
||||||
|
|||||||
@ -33,6 +33,8 @@ type OwnProps = {
|
|||||||
message?: ApiMessage;
|
message?: ApiMessage;
|
||||||
fileName?: string;
|
fileName?: string;
|
||||||
isAvatar?: boolean;
|
isAvatar?: boolean;
|
||||||
|
canReport?: boolean;
|
||||||
|
onReport: NoneToVoidFunction;
|
||||||
onCloseMediaViewer: NoneToVoidFunction;
|
onCloseMediaViewer: NoneToVoidFunction;
|
||||||
onForward: NoneToVoidFunction;
|
onForward: NoneToVoidFunction;
|
||||||
onZoomToggle: NoneToVoidFunction;
|
onZoomToggle: NoneToVoidFunction;
|
||||||
@ -47,6 +49,8 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
|
|||||||
isAvatar,
|
isAvatar,
|
||||||
isDownloading,
|
isDownloading,
|
||||||
isProtected,
|
isProtected,
|
||||||
|
canReport,
|
||||||
|
onReport,
|
||||||
onCloseMediaViewer,
|
onCloseMediaViewer,
|
||||||
onForward,
|
onForward,
|
||||||
onZoomToggle,
|
onZoomToggle,
|
||||||
@ -154,6 +158,14 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
|
|||||||
{lang('AccActionDownload')}
|
{lang('AccActionDownload')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
{canReport && (
|
||||||
|
<MenuItem
|
||||||
|
icon="flag"
|
||||||
|
onClick={onReport}
|
||||||
|
>
|
||||||
|
{lang('ReportPeer.Report')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
{isDownloading && <ProgressSpinner progress={downloadProgress} size="s" noCross />}
|
{isDownloading && <ProgressSpinner progress={downloadProgress} size="s" noCross />}
|
||||||
</div>
|
</div>
|
||||||
@ -183,6 +195,17 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
|
|||||||
>
|
>
|
||||||
<i className={isZoomed ? 'icon-zoom-out' : 'icon-zoom-in'} />
|
<i className={isZoomed ? 'icon-zoom-out' : 'icon-zoom-in'} />
|
||||||
</Button>
|
</Button>
|
||||||
|
{canReport && (
|
||||||
|
<Button
|
||||||
|
round
|
||||||
|
size="smaller"
|
||||||
|
color="translucent-white"
|
||||||
|
ariaLabel={lang(isVideo ? 'PeerInfo.ReportProfileVideo' : 'PeerInfo.ReportProfilePhoto')}
|
||||||
|
onClick={onReport}
|
||||||
|
>
|
||||||
|
<i className="icon-flag" />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<Button
|
<Button
|
||||||
round
|
round
|
||||||
size="smaller"
|
size="smaller"
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import {
|
|||||||
selectChat, selectNotifySettings, selectNotifyExceptions, selectUser, selectChatBot,
|
selectChat, selectNotifySettings, selectNotifyExceptions, selectUser, selectChatBot,
|
||||||
} from '../../global/selectors';
|
} from '../../global/selectors';
|
||||||
import {
|
import {
|
||||||
isUserId, getCanDeleteChat, selectIsChatMuted, getCanAddContact,
|
isUserId, getCanDeleteChat, selectIsChatMuted, getCanAddContact, isChatChannel, isChatGroup,
|
||||||
} from '../../global/helpers';
|
} from '../../global/helpers';
|
||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
@ -22,6 +22,7 @@ import Portal from '../ui/Portal';
|
|||||||
import Menu from '../ui/Menu';
|
import Menu from '../ui/Menu';
|
||||||
import MenuItem from '../ui/MenuItem';
|
import MenuItem from '../ui/MenuItem';
|
||||||
import DeleteChatModal from '../common/DeleteChatModal';
|
import DeleteChatModal from '../common/DeleteChatModal';
|
||||||
|
import ReportModal from '../common/ReportModal';
|
||||||
|
|
||||||
import './HeaderMenuContainer.scss';
|
import './HeaderMenuContainer.scss';
|
||||||
|
|
||||||
@ -69,6 +70,7 @@ type StateProps = {
|
|||||||
isPrivate?: boolean;
|
isPrivate?: boolean;
|
||||||
isMuted?: boolean;
|
isMuted?: boolean;
|
||||||
canAddContact?: boolean;
|
canAddContact?: boolean;
|
||||||
|
canReportChat?: boolean;
|
||||||
canDeleteChat?: boolean;
|
canDeleteChat?: boolean;
|
||||||
hasLinkedChat?: boolean;
|
hasLinkedChat?: boolean;
|
||||||
};
|
};
|
||||||
@ -93,6 +95,7 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
chat,
|
chat,
|
||||||
isPrivate,
|
isPrivate,
|
||||||
isMuted,
|
isMuted,
|
||||||
|
canReportChat,
|
||||||
canDeleteChat,
|
canDeleteChat,
|
||||||
hasLinkedChat,
|
hasLinkedChat,
|
||||||
canAddContact,
|
canAddContact,
|
||||||
@ -115,10 +118,21 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
} = getActions();
|
} = getActions();
|
||||||
const [isMenuOpen, setIsMenuOpen] = useState(true);
|
const [isMenuOpen, setIsMenuOpen] = useState(true);
|
||||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
|
const [isReportModalOpen, setIsReportModalOpen] = useState(false);
|
||||||
const { x, y } = anchor;
|
const { x, y } = anchor;
|
||||||
|
|
||||||
useShowTransition(isOpen, onCloseAnimationEnd, undefined, false);
|
useShowTransition(isOpen, onCloseAnimationEnd, undefined, false);
|
||||||
|
|
||||||
|
const handleReport = useCallback(() => {
|
||||||
|
setIsMenuOpen(false);
|
||||||
|
setIsReportModalOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const closeReportModal = useCallback(() => {
|
||||||
|
setIsReportModalOpen(false);
|
||||||
|
onClose();
|
||||||
|
}, [onClose]);
|
||||||
|
|
||||||
const handleDelete = useCallback(() => {
|
const handleDelete = useCallback(() => {
|
||||||
setIsMenuOpen(false);
|
setIsMenuOpen(false);
|
||||||
setIsDeleteModalOpen(true);
|
setIsDeleteModalOpen(true);
|
||||||
@ -334,6 +348,14 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
{lang('Statistics')}
|
{lang('Statistics')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
{canReportChat && (
|
||||||
|
<MenuItem
|
||||||
|
icon="flag"
|
||||||
|
onClick={handleReport}
|
||||||
|
>
|
||||||
|
{lang('ReportPeer.Report')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
{botButtons}
|
{botButtons}
|
||||||
{canLeave && (
|
{canLeave && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
@ -354,6 +376,14 @@ const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
chat={chat}
|
chat={chat}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{canReportChat && chat?.id && (
|
||||||
|
<ReportModal
|
||||||
|
isOpen={isReportModalOpen}
|
||||||
|
onClose={closeReportModal}
|
||||||
|
subject="peer"
|
||||||
|
chatId={chat.id}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Portal>
|
</Portal>
|
||||||
);
|
);
|
||||||
@ -368,6 +398,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
const isPrivate = isUserId(chat.id);
|
const isPrivate = isUserId(chat.id);
|
||||||
const user = isPrivate ? selectUser(global, chatId) : undefined;
|
const user = isPrivate ? selectUser(global, chatId) : undefined;
|
||||||
const canAddContact = user && getCanAddContact(user);
|
const canAddContact = user && getCanAddContact(user);
|
||||||
|
const canReportChat = isChatChannel(chat) || isChatGroup(chat) || (user && !user.isSelf);
|
||||||
|
|
||||||
const chatBot = chatId !== REPLIES_USER_ID ? selectChatBot(global, chatId) : undefined;
|
const chatBot = chatId !== REPLIES_USER_ID ? selectChatBot(global, chatId) : undefined;
|
||||||
|
|
||||||
@ -376,6 +407,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),
|
isMuted: selectIsChatMuted(chat, selectNotifySettings(global), selectNotifyExceptions(global)),
|
||||||
isPrivate,
|
isPrivate,
|
||||||
canAddContact,
|
canAddContact,
|
||||||
|
canReportChat,
|
||||||
canDeleteChat: getCanDeleteChat(chat),
|
canDeleteChat: getCanDeleteChat(chat),
|
||||||
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
|
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
|
||||||
botCommands: chatBot?.fullInfo?.botCommands,
|
botCommands: chatBot?.fullInfo?.botCommands,
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import useCopySelectedMessages from './hooks/useCopySelectedMessages';
|
|||||||
import Button from '../ui/Button';
|
import Button from '../ui/Button';
|
||||||
|
|
||||||
import DeleteSelectedMessageModal from './DeleteSelectedMessageModal';
|
import DeleteSelectedMessageModal from './DeleteSelectedMessageModal';
|
||||||
import ReportMessageModal from '../common/ReportMessageModal';
|
import ReportModal from '../common/ReportModal';
|
||||||
|
|
||||||
import './MessageSelectToolbar.scss';
|
import './MessageSelectToolbar.scss';
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ const MessageSelectToolbar: FC<OwnProps & StateProps> = ({
|
|||||||
isSchedule={isSchedule}
|
isSchedule={isSchedule}
|
||||||
onClose={closeDeleteModal}
|
onClose={closeDeleteModal}
|
||||||
/>
|
/>
|
||||||
<ReportMessageModal
|
<ReportModal
|
||||||
isOpen={isReportModalOpen}
|
isOpen={isReportModalOpen}
|
||||||
onClose={closeReportModal}
|
onClose={closeReportModal}
|
||||||
messageIds={selectedMessageIds}
|
messageIds={selectedMessageIds}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import useFlag from '../../../hooks/useFlag';
|
|||||||
import { REM } from '../../common/helpers/mediaDimensions';
|
import { REM } from '../../common/helpers/mediaDimensions';
|
||||||
|
|
||||||
import DeleteMessageModal from '../../common/DeleteMessageModal';
|
import DeleteMessageModal from '../../common/DeleteMessageModal';
|
||||||
import ReportMessageModal from '../../common/ReportMessageModal';
|
import ReportModal from '../../common/ReportModal';
|
||||||
import PinMessageModal from '../../common/PinMessageModal';
|
import PinMessageModal from '../../common/PinMessageModal';
|
||||||
import MessageContextMenu from './MessageContextMenu';
|
import MessageContextMenu from './MessageContextMenu';
|
||||||
import CalendarModal from '../../common/CalendarModal';
|
import CalendarModal from '../../common/CalendarModal';
|
||||||
@ -396,7 +396,7 @@ const ContextMenuContainer: FC<OwnProps & StateProps> = ({
|
|||||||
album={album}
|
album={album}
|
||||||
message={message}
|
message={message}
|
||||||
/>
|
/>
|
||||||
<ReportMessageModal
|
<ReportModal
|
||||||
isOpen={isReportModalOpen}
|
isOpen={isReportModalOpen}
|
||||||
onClose={closeReportModal}
|
onClose={closeReportModal}
|
||||||
messageIds={reportMessageIds}
|
messageIds={reportMessageIds}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import './api/globalSearch';
|
|||||||
import './api/localSearch';
|
import './api/localSearch';
|
||||||
import './api/management';
|
import './api/management';
|
||||||
import './api/sync';
|
import './api/sync';
|
||||||
|
import './api/accounts';
|
||||||
import './api/users';
|
import './api/users';
|
||||||
import './api/bots';
|
import './api/bots';
|
||||||
import './api/settings';
|
import './api/settings';
|
||||||
|
|||||||
62
src/global/actions/api/accounts.ts
Normal file
62
src/global/actions/api/accounts.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { addActionHandler } from '../../index';
|
||||||
|
import { selectChat } from '../../selectors';
|
||||||
|
import { callApi } from '../../../api/gramjs';
|
||||||
|
import { getTranslation } from '../../../util/langProvider';
|
||||||
|
|
||||||
|
addActionHandler('reportPeer', async (global, actions, payload) => {
|
||||||
|
const {
|
||||||
|
chatId,
|
||||||
|
reason,
|
||||||
|
description,
|
||||||
|
} = payload;
|
||||||
|
if (!chatId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chat = selectChat(global, chatId)!;
|
||||||
|
if (!chat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await callApi('reportPeer', {
|
||||||
|
peer: chat,
|
||||||
|
reason,
|
||||||
|
description,
|
||||||
|
});
|
||||||
|
|
||||||
|
actions.showNotification({
|
||||||
|
message: result
|
||||||
|
? getTranslation('ReportPeer.AlertSuccess')
|
||||||
|
: 'An error occurred while submitting your report. Please, try again later.',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
addActionHandler('reportProfilePhoto', async (global, actions, payload) => {
|
||||||
|
const {
|
||||||
|
chatId,
|
||||||
|
reason,
|
||||||
|
description,
|
||||||
|
photo,
|
||||||
|
} = payload;
|
||||||
|
if (!chatId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const chat = selectChat(global, chatId)!;
|
||||||
|
if (!chat || !photo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await callApi('reportProfilePhoto', {
|
||||||
|
peer: chat,
|
||||||
|
photo,
|
||||||
|
reason,
|
||||||
|
description,
|
||||||
|
});
|
||||||
|
|
||||||
|
actions.showNotification({
|
||||||
|
message: result
|
||||||
|
? getTranslation('ReportPeer.AlertSuccess')
|
||||||
|
: 'An error occurred while submitting your report. Please, try again later.',
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -67,6 +67,7 @@ import {
|
|||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
import { debounce, onTickEnd, rafPromise } from '../../../util/schedulers';
|
import { debounce, onTickEnd, rafPromise } from '../../../util/schedulers';
|
||||||
import { isServiceNotificationMessage } from '../../helpers';
|
import { isServiceNotificationMessage } from '../../helpers';
|
||||||
|
import { getTranslation } from '../../../util/langProvider';
|
||||||
|
|
||||||
const uploadProgressCallbacks = new Map<number, ApiOnProgress>();
|
const uploadProgressCallbacks = new Map<number, ApiOnProgress>();
|
||||||
|
|
||||||
@ -460,8 +461,8 @@ addActionHandler('reportMessages', async (global, actions, payload) => {
|
|||||||
|
|
||||||
actions.showNotification({
|
actions.showNotification({
|
||||||
message: result
|
message: result
|
||||||
? 'Thank you! Your report will be reviewed by our team.'
|
? getTranslation('ReportPeer.AlertSuccess')
|
||||||
: 'Error occured while submiting report. Please, try again later.',
|
: 'An error occurred while submitting your report. Please, try again later.',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,8 @@ import {
|
|||||||
ApiGroupStatistics,
|
ApiGroupStatistics,
|
||||||
ApiPaymentFormNativeParams,
|
ApiPaymentFormNativeParams,
|
||||||
ApiUpdate,
|
ApiUpdate,
|
||||||
|
ApiReportReason,
|
||||||
|
ApiPhoto,
|
||||||
ApiKeyboardButton,
|
ApiKeyboardButton,
|
||||||
ApiPhoneCall,
|
ApiPhoneCall,
|
||||||
} from '../api/types';
|
} from '../api/types';
|
||||||
@ -552,6 +554,19 @@ export interface ActionPayloads {
|
|||||||
signOut: { forceInitApi?: boolean } | undefined;
|
signOut: { forceInitApi?: boolean } | undefined;
|
||||||
apiUpdate: ApiUpdate;
|
apiUpdate: ApiUpdate;
|
||||||
|
|
||||||
|
// Accounts
|
||||||
|
reportPeer: {
|
||||||
|
chatId?: string;
|
||||||
|
reason: ApiReportReason;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
reportProfilePhoto: {
|
||||||
|
chatId?: string;
|
||||||
|
reason: ApiReportReason;
|
||||||
|
description: string;
|
||||||
|
photo?: ApiPhoto;
|
||||||
|
};
|
||||||
|
|
||||||
// Chats
|
// Chats
|
||||||
openChat: {
|
openChat: {
|
||||||
id: string | undefined;
|
id: string | undefined;
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { ApiChat, ApiUser } from '../api/types';
|
|||||||
|
|
||||||
import { SERVICE_NOTIFICATIONS_USER_ID } from '../config';
|
import { SERVICE_NOTIFICATIONS_USER_ID } from '../config';
|
||||||
import {
|
import {
|
||||||
isChatArchived, getCanDeleteChat, isUserId, isChatChannel,
|
isChatArchived, getCanDeleteChat, isUserId, isChatChannel, isChatGroup,
|
||||||
} from '../global/helpers';
|
} from '../global/helpers';
|
||||||
import { compact } from '../util/iteratees';
|
import { compact } from '../util/iteratees';
|
||||||
import useLang from './useLang';
|
import useLang from './useLang';
|
||||||
@ -19,6 +19,7 @@ const useChatContextActions = ({
|
|||||||
canChangeFolder,
|
canChangeFolder,
|
||||||
handleDelete,
|
handleDelete,
|
||||||
handleChatFolderChange,
|
handleChatFolderChange,
|
||||||
|
handleReport,
|
||||||
}: {
|
}: {
|
||||||
chat: ApiChat | undefined;
|
chat: ApiChat | undefined;
|
||||||
user: ApiUser | undefined;
|
user: ApiUser | undefined;
|
||||||
@ -28,6 +29,7 @@ const useChatContextActions = ({
|
|||||||
canChangeFolder?: boolean;
|
canChangeFolder?: boolean;
|
||||||
handleDelete: () => void;
|
handleDelete: () => void;
|
||||||
handleChatFolderChange: () => void;
|
handleChatFolderChange: () => void;
|
||||||
|
handleReport?: () => void;
|
||||||
}, isInSearch = false) => {
|
}, isInSearch = false) => {
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
@ -84,6 +86,11 @@ const useChatContextActions = ({
|
|||||||
? { title: lang('Unarchive'), icon: 'unarchive', handler: () => toggleChatArchived({ id: chat.id }) }
|
? { title: lang('Unarchive'), icon: 'unarchive', handler: () => toggleChatArchived({ id: chat.id }) }
|
||||||
: { title: lang('Archive'), icon: 'archive', handler: () => toggleChatArchived({ id: chat.id }) };
|
: { title: lang('Archive'), icon: 'archive', handler: () => toggleChatArchived({ id: chat.id }) };
|
||||||
|
|
||||||
|
const canReport = handleReport && (isChatChannel(chat) || isChatGroup(chat) || (user && !user.isSelf));
|
||||||
|
const actionReport = canReport
|
||||||
|
? { title: lang('ReportPeer.Report'), icon: 'flag', handler: handleReport }
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const actionDelete = {
|
const actionDelete = {
|
||||||
title: isUserId(chat.id)
|
title: isUserId(chat.id)
|
||||||
? lang('Delete')
|
? lang('Delete')
|
||||||
@ -103,11 +110,12 @@ const useChatContextActions = ({
|
|||||||
actionPin,
|
actionPin,
|
||||||
!isSelf && actionMute,
|
!isSelf && actionMute,
|
||||||
!isSelf && !isServiceNotifications && !isInFolder && actionArchive,
|
!isSelf && !isServiceNotifications && !isInFolder && actionArchive,
|
||||||
|
actionReport,
|
||||||
actionDelete,
|
actionDelete,
|
||||||
]);
|
]);
|
||||||
}, [
|
}, [
|
||||||
chat, canChangeFolder, lang, handleChatFolderChange, isPinned, isInSearch, isMuted, handleDelete, folderId, isSelf,
|
chat, user, canChangeFolder, lang, handleChatFolderChange, isPinned, isInSearch, isMuted,
|
||||||
isServiceNotifications,
|
handleDelete, handleReport, folderId, isSelf, isServiceNotifications,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -982,6 +982,7 @@ account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
|||||||
account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
|
account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
|
||||||
account.updateStatus#6628562c offline:Bool = Bool;
|
account.updateStatus#6628562c offline:Bool = Bool;
|
||||||
account.getWallPapers#7967d36 hash:long = account.WallPapers;
|
account.getWallPapers#7967d36 hash:long = account.WallPapers;
|
||||||
|
account.reportPeer#c5ba3d86 peer:InputPeer reason:ReportReason message:string = Bool;
|
||||||
account.checkUsername#2714d86c username:string = Bool;
|
account.checkUsername#2714d86c username:string = Bool;
|
||||||
account.updateUsername#3e0bdd7c username:string = User;
|
account.updateUsername#3e0bdd7c username:string = User;
|
||||||
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
|
account.getPrivacy#dadbc950 key:InputPrivacyKey = account.PrivacyRules;
|
||||||
@ -1002,6 +1003,7 @@ account.getNotifyExceptions#53577479 flags:# compare_sound:flags.1?true peer:fla
|
|||||||
account.uploadWallPaper#dd853661 file:InputFile mime_type:string settings:WallPaperSettings = WallPaper;
|
account.uploadWallPaper#dd853661 file:InputFile mime_type:string settings:WallPaperSettings = WallPaper;
|
||||||
account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool;
|
account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool;
|
||||||
account.getContentSettings#8b9b4dae = account.ContentSettings;
|
account.getContentSettings#8b9b4dae = account.ContentSettings;
|
||||||
|
account.reportProfilePhoto#fa8cc6f5 peer:InputPeer photo_id:InputPhoto reason:ReportReason message:string = Bool;
|
||||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||||
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
||||||
contacts.getContacts#5dd69e12 hash:long = contacts.Contacts;
|
contacts.getContacts#5dd69e12 hash:long = contacts.Contacts;
|
||||||
|
|||||||
@ -43,6 +43,8 @@
|
|||||||
"account.uploadWallPaper",
|
"account.uploadWallPaper",
|
||||||
"account.setContentSettings",
|
"account.setContentSettings",
|
||||||
"account.getContentSettings",
|
"account.getContentSettings",
|
||||||
|
"account.reportPeer",
|
||||||
|
"account.reportProfilePhoto",
|
||||||
"users.getUsers",
|
"users.getUsers",
|
||||||
"users.getFullUser",
|
"users.getFullUser",
|
||||||
"contacts.getContacts",
|
"contacts.getContacts",
|
||||||
|
|||||||
@ -197,11 +197,11 @@ $color-message-reaction-own-hover: #b5e0a4;
|
|||||||
}
|
}
|
||||||
|
|
||||||
--z-ui-loader-mask: 2000;
|
--z-ui-loader-mask: 2000;
|
||||||
--z-notification: 1000;
|
--z-notification: 1520;
|
||||||
--z-right-column: 900;
|
--z-right-column: 900;
|
||||||
--z-header-menu: 990;
|
--z-header-menu: 990;
|
||||||
--z-header-menu-backdrop: 980;
|
--z-header-menu-backdrop: 980;
|
||||||
--z-modal: 1000;
|
--z-modal: 1510;
|
||||||
--z-media-viewer: 1500;
|
--z-media-viewer: 1500;
|
||||||
--z-drop-area: 55;
|
--z-drop-area: 55;
|
||||||
--z-animation-fade: 50;
|
--z-animation-fade: 50;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user