Improve context menus
This commit is contained in:
parent
fbf93374c1
commit
de45db255c
6 changed files with 221 additions and 56 deletions
1
images/icons/v2/trash-outline-24.svg
Normal file
1
images/icons/v2/trash-outline-24.svg
Normal 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 |
1
images/icons/v2/trash-solid-24.svg
Normal file
1
images/icons/v2/trash-solid-24.svg
Normal 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 |
|
@ -9638,22 +9638,20 @@ button.module-image__border-overlay:focus {
|
||||||
/* Third-party module: react-contextmenu*/
|
/* Third-party module: react-contextmenu*/
|
||||||
|
|
||||||
.react-contextmenu {
|
.react-contextmenu {
|
||||||
|
@include popper-shadow();
|
||||||
|
|
||||||
outline: none;
|
outline: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
min-width: 160px;
|
min-width: 220px;
|
||||||
padding: 0px;
|
padding: 6px 0;
|
||||||
padding-top: 8px;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
background-color: $color-gray-02;
|
background-color: $color-white;
|
||||||
border: 1px solid $color-gray-02;
|
|
||||||
}
|
}
|
||||||
@include dark-theme {
|
@include dark-theme {
|
||||||
background-color: $color-gray-90;
|
background-color: $color-gray-75;
|
||||||
border: 1px solid $color-gray-60;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9669,10 +9667,7 @@ button.module-image__border-overlay:focus {
|
||||||
|
|
||||||
@include font-body-2;
|
@include font-body-2;
|
||||||
|
|
||||||
padding-left: 16px;
|
padding: 7px 12px;
|
||||||
padding-top: 3px;
|
|
||||||
padding-bottom: 2px;
|
|
||||||
padding-right: 16px;
|
|
||||||
|
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
color: $color-gray-90;
|
color: $color-gray-90;
|
||||||
|
@ -9680,6 +9675,19 @@ button.module-image__border-overlay:focus {
|
||||||
@include dark-theme {
|
@include dark-theme {
|
||||||
color: $color-gray-02;
|
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 {
|
.react-contextmenu-item--checked:before {
|
||||||
|
@ -9706,15 +9714,25 @@ button.module-image__border-overlay:focus {
|
||||||
|
|
||||||
.react-contextmenu-item.react-contextmenu-submenu
|
.react-contextmenu-item.react-contextmenu-submenu
|
||||||
> .react-contextmenu-item:after {
|
> .react-contextmenu-item:after {
|
||||||
content: '\25B6';
|
content: ' ';
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
height: 18px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 7px;
|
right: 7px;
|
||||||
|
width: 12px;
|
||||||
|
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
|
@include color-svg(
|
||||||
|
'../images/icons/v2/chevron-right-16.svg',
|
||||||
|
$color-gray-75
|
||||||
|
);
|
||||||
color: $color-gray-90;
|
color: $color-gray-90;
|
||||||
}
|
}
|
||||||
@include dark-theme {
|
@include dark-theme {
|
||||||
|
@include color-svg(
|
||||||
|
'../images/icons/v2/chevron-right-16.svg',
|
||||||
|
$color-gray-15
|
||||||
|
);
|
||||||
color: $color-gray-02;
|
color: $color-gray-02;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9726,7 +9744,7 @@ button.module-image__border-overlay:focus {
|
||||||
background-color: $color-gray-15;
|
background-color: $color-gray-15;
|
||||||
}
|
}
|
||||||
@include dark-theme {
|
@include dark-theme {
|
||||||
background-color: $color-gray-75;
|
background-color: $color-gray-60;
|
||||||
color: $color-white;
|
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 */
|
/* Spec: container > 438px and container < 593px */
|
||||||
@media (min-width: 800px) and (max-width: 925px) {
|
@media (min-width: 800px) and (max-width: 925px) {
|
||||||
.module-message {
|
.module-message {
|
||||||
|
|
|
@ -350,6 +350,28 @@ export class ConversationHeader extends React.Component<PropsType> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenu id={triggerId}>
|
<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 : (
|
{disableTimerChanges ? null : (
|
||||||
<SubMenu title={disappearingTitle}>
|
<SubMenu title={disappearingTitle}>
|
||||||
{(timerOptions || []).map(item => (
|
{(timerOptions || []).map(item => (
|
||||||
|
@ -364,19 +386,6 @@ export class ConversationHeader extends React.Component<PropsType> {
|
||||||
))}
|
))}
|
||||||
</SubMenu>
|
</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>
|
<MenuItem onClick={onShowAllMedia}>{i18n('viewRecentMedia')}</MenuItem>
|
||||||
{isGroup ? (
|
{isGroup ? (
|
||||||
<MenuItem onClick={onShowGroupMembers}>
|
<MenuItem onClick={onShowGroupMembers}>
|
||||||
|
@ -388,6 +397,7 @@ export class ConversationHeader extends React.Component<PropsType> {
|
||||||
{i18n('showSafetyNumber')}
|
{i18n('showSafetyNumber')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
) : null}
|
) : null}
|
||||||
|
<MenuItem divider />
|
||||||
{!isGroup && acceptedMessageRequest ? (
|
{!isGroup && acceptedMessageRequest ? (
|
||||||
<MenuItem onClick={onResetSession}>{i18n('resetSession')}</MenuItem>
|
<MenuItem onClick={onResetSession}>{i18n('resetSession')}</MenuItem>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -398,15 +408,6 @@ export class ConversationHeader extends React.Component<PropsType> {
|
||||||
) : (
|
) : (
|
||||||
<MenuItem onClick={onArchive}>{i18n('archiveConversation')}</MenuItem>
|
<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>
|
<MenuItem onClick={onDeleteMessages}>{i18n('deleteMessages')}</MenuItem>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
);
|
);
|
||||||
|
|
|
@ -796,3 +796,21 @@ story.add('@Mentions', () => {
|
||||||
|
|
||||||
return renderBothDirections(props);
|
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" />;
|
||||||
|
});
|
||||||
|
|
|
@ -1347,7 +1347,9 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
const { canDeleteForEveryone } = this.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 multipleAttachments = attachments && attachments.length > 1;
|
||||||
|
|
||||||
const menu = (
|
const menu = (
|
||||||
|
@ -1360,7 +1362,8 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
attachments[0] ? (
|
attachments[0] ? (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
attributes={{
|
attributes={{
|
||||||
className: 'module-message__context__download',
|
className:
|
||||||
|
'module-message__context--icon module-message__context__download',
|
||||||
}}
|
}}
|
||||||
onClick={this.openGenericAttachment}
|
onClick={this.openGenericAttachment}
|
||||||
>
|
>
|
||||||
|
@ -1371,20 +1374,8 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
<>
|
<>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
attributes={{
|
attributes={{
|
||||||
className: 'module-message__context__react',
|
className:
|
||||||
}}
|
'module-message__context--icon module-message__context__reply',
|
||||||
onClick={(event: React.MouseEvent) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
this.toggleReactionPicker();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{i18n('reactToMessage')}
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
attributes={{
|
|
||||||
className: 'module-message__context__reply',
|
|
||||||
}}
|
}}
|
||||||
onClick={(event: React.MouseEvent) => {
|
onClick={(event: React.MouseEvent) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -1395,11 +1386,26 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
>
|
>
|
||||||
{i18n('replyToMessage')}
|
{i18n('replyToMessage')}
|
||||||
</MenuItem>
|
</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}
|
) : null}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
attributes={{
|
attributes={{
|
||||||
className: 'module-message__context__more-info',
|
className:
|
||||||
|
'module-message__context--icon module-message__context__more-info',
|
||||||
}}
|
}}
|
||||||
onClick={(event: React.MouseEvent) => {
|
onClick={(event: React.MouseEvent) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -1413,7 +1419,8 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
{showRetry ? (
|
{showRetry ? (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
attributes={{
|
attributes={{
|
||||||
className: 'module-message__context__retry-send',
|
className:
|
||||||
|
'module-message__context--icon module-message__context__retry-send',
|
||||||
}}
|
}}
|
||||||
onClick={(event: React.MouseEvent) => {
|
onClick={(event: React.MouseEvent) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -1427,7 +1434,8 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
) : null}
|
) : null}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
attributes={{
|
attributes={{
|
||||||
className: 'module-message__context__delete-message',
|
className:
|
||||||
|
'module-message__context--icon module-message__context__delete-message',
|
||||||
}}
|
}}
|
||||||
onClick={(event: React.MouseEvent) => {
|
onClick={(event: React.MouseEvent) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -1441,7 +1449,8 @@ export class Message extends React.PureComponent<Props, State> {
|
||||||
{canDeleteForEveryone ? (
|
{canDeleteForEveryone ? (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
attributes={{
|
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) => {
|
onClick={(event: React.MouseEvent) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
Loading…
Add table
Reference in a new issue