Improve context menus

This commit is contained in:
Josh Perez 2020-10-21 14:26:35 -04:00 committed by Evan Hahn
parent fbf93374c1
commit de45db255c
6 changed files with 221 additions and 56 deletions

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>trash-outline-24</title><path d="M22,4.5H16.35a4.45,4.45,0,0,0-8.7,0H2V6H3.5L4.86,20A2.25,2.25,0,0,0,7.1,22h9.8a2.25,2.25,0,0,0,2.24-2L20.5,6H22Zm-10-2a3,3,0,0,1,2.82,2H9.18A3,3,0,0,1,12,2.5Zm5.65,17.33a.76.76,0,0,1-.75.67H7.1a.76.76,0,0,1-.75-.67L5,6H19ZM11.25,18V8h1.5V18Zm3.25,0L15,8h1.5L16,18ZM8,18,7.5,8H9l.5,10Z"/></svg>

After

Width:  |  Height:  |  Size: 416 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>trash-solid-24</title><path d="M16.38,4.5a4.49,4.49,0,0,0-8.76,0H2V6H3.5L4.86,20A2.25,2.25,0,0,0,7.1,22h9.8a2.25,2.25,0,0,0,2.24-2L20.5,6H22V4.5ZM12,2.5a3,3,0,0,1,2.82,2H9.18A3,3,0,0,1,12,2.5ZM8,18,7.5,8H9l.5,10Zm4.75,0h-1.5V8h1.5ZM16,18H14.5L15,8h1.5Z"/></svg>

After

Width:  |  Height:  |  Size: 351 B

View File

@ -9638,22 +9638,20 @@ button.module-image__border-overlay:focus {
/* Third-party module: react-contextmenu*/
.react-contextmenu {
@include popper-shadow();
outline: none;
border-radius: 4px;
min-width: 160px;
padding: 0px;
padding-top: 8px;
padding-bottom: 8px;
min-width: 220px;
padding: 6px 0;
opacity: 0;
user-select: none;
@include light-theme {
background-color: $color-gray-02;
border: 1px solid $color-gray-02;
background-color: $color-white;
}
@include dark-theme {
background-color: $color-gray-90;
border: 1px solid $color-gray-60;
background-color: $color-gray-75;
}
}
@ -9669,10 +9667,7 @@ button.module-image__border-overlay:focus {
@include font-body-2;
padding-left: 16px;
padding-top: 3px;
padding-bottom: 2px;
padding-right: 16px;
padding: 7px 12px;
@include light-theme {
color: $color-gray-90;
@ -9680,6 +9675,19 @@ button.module-image__border-overlay:focus {
@include dark-theme {
color: $color-gray-02;
}
&--divider {
height: 1px;
margin: 6px 0;
padding: 0;
@include light-theme {
background-color: $color-gray-15;
}
@include dark-theme {
background-color: $color-gray-60;
}
}
}
.react-contextmenu-item--checked:before {
@ -9706,15 +9714,25 @@ button.module-image__border-overlay:focus {
.react-contextmenu-item.react-contextmenu-submenu
> .react-contextmenu-item:after {
content: '\25B6';
content: ' ';
display: inline-block;
height: 18px;
position: absolute;
right: 7px;
width: 12px;
@include light-theme {
@include color-svg(
'../images/icons/v2/chevron-right-16.svg',
$color-gray-75
);
color: $color-gray-90;
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/chevron-right-16.svg',
$color-gray-15
);
color: $color-gray-02;
}
}
@ -9726,7 +9744,7 @@ button.module-image__border-overlay:focus {
background-color: $color-gray-15;
}
@include dark-theme {
background-color: $color-gray-75;
background-color: $color-gray-60;
color: $color-white;
}
}
@ -9777,6 +9795,123 @@ button.module-image__border-overlay:focus {
}
}
.module-message__context {
&--icon::before {
content: ' ';
display: inline-block;
height: 14px;
margin-right: 8px;
width: 14px;
vertical-align: middle;
}
&__download::before {
@include light-theme {
@include color-svg(
'../images/icons/v2/save-outline-24.svg',
$color-black
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/save-solid-24.svg',
$color-gray-15
);
}
}
&__reply::before {
@include light-theme {
@include color-svg(
'../images/icons/v2/reply-outline-24.svg',
$color-black
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/reply-solid-24.svg',
$color-gray-15
);
}
}
&__react::before {
@include light-theme {
@include color-svg(
'../images/icons/v2/add-emoji-outline-24.svg',
$color-black
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/add-emoji-outline-24.svg',
$color-gray-15
);
}
}
&__more-info::before {
@include light-theme {
@include color-svg(
'../images/icons/v2/info-outline-24.svg',
$color-black
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/info-outline-24.svg',
$color-gray-15
);
}
}
&__retry-send::before {
@include light-theme {
@include color-svg('../images/icons/v2/send-24.svg', $color-black);
}
@include dark-theme {
@include color-svg('../images/icons/v2/send-24.svg', $color-gray-15);
}
}
&__delete-message::before {
@include light-theme {
@include color-svg(
'../images/icons/v2/trash-outline-24.svg',
$color-black
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/trash-solid-24.svg',
$color-gray-15
);
}
}
&__delete-message-for-everyone::before {
@include light-theme {
@include color-svg(
'../images/icons/v2/trash-outline-24.svg',
$color-black
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/trash-solid-24.svg',
$color-gray-15
);
}
}
}
/* Spec: container > 438px and container < 593px */
@media (min-width: 800px) and (max-width: 925px) {
.module-message {

View File

@ -350,6 +350,28 @@ export class ConversationHeader extends React.Component<PropsType> {
return (
<ContextMenu id={triggerId}>
<SubMenu title={muteTitle}>
{muteOptions.map(item => (
<MenuItem
key={item.name}
disabled={item.disabled}
onClick={() => {
onSetMuteNotifications(item.value);
}}
>
{item.name}
</MenuItem>
))}
</SubMenu>
{isPinned ? (
<MenuItem onClick={() => onSetPin(false)}>
{i18n('unpinConversation')}
</MenuItem>
) : (
<MenuItem onClick={() => onSetPin(true)}>
{i18n('pinConversation')}
</MenuItem>
)}
{disableTimerChanges ? null : (
<SubMenu title={disappearingTitle}>
{(timerOptions || []).map(item => (
@ -364,19 +386,6 @@ export class ConversationHeader extends React.Component<PropsType> {
))}
</SubMenu>
)}
<SubMenu title={muteTitle}>
{muteOptions.map(item => (
<MenuItem
key={item.name}
disabled={item.disabled}
onClick={() => {
onSetMuteNotifications(item.value);
}}
>
{item.name}
</MenuItem>
))}
</SubMenu>
<MenuItem onClick={onShowAllMedia}>{i18n('viewRecentMedia')}</MenuItem>
{isGroup ? (
<MenuItem onClick={onShowGroupMembers}>
@ -388,6 +397,7 @@ export class ConversationHeader extends React.Component<PropsType> {
{i18n('showSafetyNumber')}
</MenuItem>
) : null}
<MenuItem divider />
{!isGroup && acceptedMessageRequest ? (
<MenuItem onClick={onResetSession}>{i18n('resetSession')}</MenuItem>
) : null}
@ -398,15 +408,6 @@ export class ConversationHeader extends React.Component<PropsType> {
) : (
<MenuItem onClick={onArchive}>{i18n('archiveConversation')}</MenuItem>
)}
{isPinned ? (
<MenuItem onClick={() => onSetPin(false)}>
{i18n('unpinConversation')}
</MenuItem>
) : (
<MenuItem onClick={() => onSetPin(true)}>
{i18n('pinConversation')}
</MenuItem>
)}
<MenuItem onClick={onDeleteMessages}>{i18n('deleteMessages')}</MenuItem>
</ContextMenu>
);

View File

@ -796,3 +796,21 @@ story.add('@Mentions', () => {
return renderBothDirections(props);
});
story.add('All the context menus', () => {
const props = createProps({
attachments: [
{
url: '/fixtures/tina-rolf-269345-unsplash.jpg',
fileName: 'tina-rolf-269345-unsplash.jpg',
contentType: IMAGE_JPEG,
width: 128,
height: 128,
},
],
status: 'partial-sent',
canDeleteForEveryone: true,
});
return <Message {...props} direction="outgoing" />;
});

View File

@ -1347,7 +1347,9 @@ export class Message extends React.PureComponent<Props, State> {
const { canDeleteForEveryone } = this.state;
const showRetry = status === 'error' && direction === 'outgoing';
const showRetry =
(status === 'error' || status === 'partial-sent') &&
direction === 'outgoing';
const multipleAttachments = attachments && attachments.length > 1;
const menu = (
@ -1360,7 +1362,8 @@ export class Message extends React.PureComponent<Props, State> {
attachments[0] ? (
<MenuItem
attributes={{
className: 'module-message__context__download',
className:
'module-message__context--icon module-message__context__download',
}}
onClick={this.openGenericAttachment}
>
@ -1371,20 +1374,8 @@ export class Message extends React.PureComponent<Props, State> {
<>
<MenuItem
attributes={{
className: 'module-message__context__react',
}}
onClick={(event: React.MouseEvent) => {
event.stopPropagation();
event.preventDefault();
this.toggleReactionPicker();
}}
>
{i18n('reactToMessage')}
</MenuItem>
<MenuItem
attributes={{
className: 'module-message__context__reply',
className:
'module-message__context--icon module-message__context__reply',
}}
onClick={(event: React.MouseEvent) => {
event.stopPropagation();
@ -1395,11 +1386,26 @@ export class Message extends React.PureComponent<Props, State> {
>
{i18n('replyToMessage')}
</MenuItem>
<MenuItem
attributes={{
className:
'module-message__context--icon module-message__context__react',
}}
onClick={(event: React.MouseEvent) => {
event.stopPropagation();
event.preventDefault();
this.toggleReactionPicker();
}}
>
{i18n('reactToMessage')}
</MenuItem>
</>
) : null}
<MenuItem
attributes={{
className: 'module-message__context__more-info',
className:
'module-message__context--icon module-message__context__more-info',
}}
onClick={(event: React.MouseEvent) => {
event.stopPropagation();
@ -1413,7 +1419,8 @@ export class Message extends React.PureComponent<Props, State> {
{showRetry ? (
<MenuItem
attributes={{
className: 'module-message__context__retry-send',
className:
'module-message__context--icon module-message__context__retry-send',
}}
onClick={(event: React.MouseEvent) => {
event.stopPropagation();
@ -1427,7 +1434,8 @@ export class Message extends React.PureComponent<Props, State> {
) : null}
<MenuItem
attributes={{
className: 'module-message__context__delete-message',
className:
'module-message__context--icon module-message__context__delete-message',
}}
onClick={(event: React.MouseEvent) => {
event.stopPropagation();
@ -1441,7 +1449,8 @@ export class Message extends React.PureComponent<Props, State> {
{canDeleteForEveryone ? (
<MenuItem
attributes={{
className: 'module-message__context__delete-message-for-everyone',
className:
'module-message__context--icon module-message__context__delete-message-for-everyone',
}}
onClick={(event: React.MouseEvent) => {
event.stopPropagation();