From df19a8489bbfff3b3e3ab84388b2cad28e380202 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Tue, 1 Nov 2022 18:53:09 +0100 Subject: [PATCH] Media Viewer: Support deleting messages (#2086) --- .../mediaViewer/MediaViewerActions.tsx | 129 +++++++++++++----- src/components/ui/MenuItem.tsx | 4 +- 2 files changed, 100 insertions(+), 33 deletions(-) diff --git a/src/components/mediaViewer/MediaViewerActions.tsx b/src/components/mediaViewer/MediaViewerActions.tsx index c9d6c4276..2c13f7abe 100644 --- a/src/components/mediaViewer/MediaViewerActions.tsx +++ b/src/components/mediaViewer/MediaViewerActions.tsx @@ -7,23 +7,31 @@ import React, { import { getActions, withGlobal } from '../../global'; import type { ApiMessage } from '../../api/types'; +import type { MessageListType } from '../../global/types'; import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment'; import { getMessageMediaFormat, getMessageMediaHash } from '../../global/helpers'; import useLang from '../../hooks/useLang'; import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress'; -import { selectIsDownloading, selectIsMessageProtected } from '../../global/selectors'; +import useFlag from '../../hooks/useFlag'; +import { + selectIsDownloading, selectIsMessageProtected, selectAllowedMessageActions, selectCurrentMessageList, +} from '../../global/selectors'; import Button from '../ui/Button'; import DropdownMenu from '../ui/DropdownMenu'; +import type { MenuItemProps } from '../ui/MenuItem'; import MenuItem from '../ui/MenuItem'; import ProgressSpinner from '../ui/ProgressSpinner'; +import DeleteMessageModal from '../common/DeleteMessageModal'; import './MediaViewerActions.scss'; type StateProps = { isDownloading: boolean; isProtected?: boolean; + canDelete?: boolean; + messageListType?: MessageListType; }; type OwnProps = { @@ -53,8 +61,12 @@ const MediaViewerActions: FC = ({ onCloseMediaViewer, zoomLevelChange, setZoomLevelChange, + canDelete, onForward, + messageListType, }) => { + const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag(false); + const { downloadMessageMedia, cancelMessageMediaDownload, @@ -135,7 +147,48 @@ const MediaViewerActions: FC = ({ } if (IS_SINGLE_COLUMN_LAYOUT) { - if (isProtected) { + const menuItems: MenuItemProps[] = []; + if (!isAvatar && !isProtected) { + menuItems.push({ + icon: 'forward', + onClick: onForward, + children: lang('Forward'), + }); + } + if (!isProtected) { + if (isVideo) { + menuItems.push({ + icon: isDownloading ? 'cancel' : 'download', + onClick: handleDownloadClick, + children: isDownloading ? `${Math.round(downloadProgress * 100)}% Downloading...` : 'Download', + }); + } else { + menuItems.push({ + icon: 'download', + href: mediaData, + download: fileName, + children: lang('AccActionDownload'), + }); + } + } + + if (canReport) { + menuItems.push({ + icon: 'report', + onClick: onReport, + children: lang('ReportPeer.Report'), + }); + } + + if (canDelete) { + menuItems.push({ + icon: 'delete', + onClick: openDeleteModal, + children: lang('Delete'), + }); + } + + if (menuItems.length === 0) { return undefined; } @@ -145,40 +198,29 @@ const MediaViewerActions: FC = ({ trigger={MenuButton} positionX="right" > - {!isAvatar && ( + {menuItems.map(({ + icon, onClick, href, download, children, + }) => ( - {lang('Forward')} + {children} - )} - {isVideo ? ( - - {isDownloading ? `${Math.round(downloadProgress * 100)}% Downloading...` : 'Download'} - - ) : ( - - {lang('AccActionDownload')} - - )} - {canReport && ( - - {lang('ReportPeer.Report')} - - )} + ))} {isDownloading && } + {message && canDelete && ( + + )} ); } @@ -226,6 +268,17 @@ const MediaViewerActions: FC = ({ )} + {canDelete && ( + + )} + {message && canDelete && ( + + )} ); }; export default memo(withGlobal( (global, { message }): StateProps => { + const currentMessageList = selectCurrentMessageList(global); + const { threadId } = selectCurrentMessageList(global) || {}; const isDownloading = message ? selectIsDownloading(global, message) : false; const isProtected = selectIsMessageProtected(global, message); + const { canDelete } = (threadId && message && selectAllowedMessageActions(global, message, threadId)) || {}; + const messageListType = currentMessageList?.type; return { isDownloading, isProtected, + canDelete, + messageListType, }; }, )(MediaViewerActions)); diff --git a/src/components/ui/MenuItem.tsx b/src/components/ui/MenuItem.tsx index 88a4cc36f..18e040faf 100644 --- a/src/components/ui/MenuItem.tsx +++ b/src/components/ui/MenuItem.tsx @@ -10,7 +10,7 @@ import './MenuItem.scss'; type OnClickHandler = (e: React.SyntheticEvent) => void; -type OwnProps = { +export type MenuItemProps = { icon?: string; customIcon?: React.ReactNode; className?: string; @@ -25,7 +25,7 @@ type OwnProps = { withWrap?: boolean; }; -const MenuItem: FC = (props) => { +const MenuItem: FC = (props) => { const { icon, customIcon,