mirror of https://github.com/vector-im/riot-web
Promote reply button up to message action bar
This moves the reply action out of the existing options menu and up to the message action bar for easier access.pull/21833/head
parent
8ef9fe951d
commit
739c8c0314
|
@ -55,8 +55,8 @@ limitations under the License.
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
height: 100%;
|
||||||
right: 0;
|
width: 100%;
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
mask-position: center;
|
mask-position: center;
|
||||||
background-color: $primary-fg-color;
|
background-color: $primary-fg-color;
|
||||||
|
@ -64,6 +64,10 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_MessageActionBar_replyButton::after {
|
||||||
|
mask-image: url('$(res)/img/reply.svg');
|
||||||
|
}
|
||||||
|
|
||||||
.mx_MessageActionBar_optionsButton::after {
|
.mx_MessageActionBar_optionsButton::after {
|
||||||
mask-image: url('$(res)/img/icon_context.svg');
|
mask-image: url('$(res)/img/icon_context.svg');
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<svg width="13" height="13" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g stroke="#2E2F32" stroke-width=".75" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M8.75 4.75L12.5 8.5l-3.75 3.75"/>
|
||||||
|
<path d="M.5.25V5.5a3 3 0 0 0 3 3h9"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 289 B |
|
@ -201,14 +201,6 @@ module.exports = React.createClass({
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
},
|
},
|
||||||
|
|
||||||
onReplyClick: function() {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'reply_to_event',
|
|
||||||
event: this.props.mxEvent,
|
|
||||||
});
|
|
||||||
this.closeMenu();
|
|
||||||
},
|
|
||||||
|
|
||||||
onCollapseReplyThreadClick: function() {
|
onCollapseReplyThreadClick: function() {
|
||||||
this.props.collapseReplyThread();
|
this.props.collapseReplyThread();
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
|
@ -226,7 +218,6 @@ module.exports = React.createClass({
|
||||||
let unhidePreviewButton;
|
let unhidePreviewButton;
|
||||||
let externalURLButton;
|
let externalURLButton;
|
||||||
let quoteButton;
|
let quoteButton;
|
||||||
let replyButton;
|
|
||||||
let collapseReplyThread;
|
let collapseReplyThread;
|
||||||
|
|
||||||
// status is SENT before remote-echo, null after
|
// status is SENT before remote-echo, null after
|
||||||
|
@ -265,12 +256,6 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
replyButton = (
|
|
||||||
<div className="mx_MessageContextMenu_field" onClick={this.onReplyClick}>
|
|
||||||
{ _t('Reply') }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.state.canPin) {
|
if (this.state.canPin) {
|
||||||
pinButton = (
|
pinButton = (
|
||||||
<div className="mx_MessageContextMenu_field" onClick={this.onPinClick}>
|
<div className="mx_MessageContextMenu_field" onClick={this.onPinClick}>
|
||||||
|
@ -368,7 +353,6 @@ module.exports = React.createClass({
|
||||||
{ unhidePreviewButton }
|
{ unhidePreviewButton }
|
||||||
{ permalinkButton }
|
{ permalinkButton }
|
||||||
{ quoteButton }
|
{ quoteButton }
|
||||||
{ replyButton }
|
|
||||||
{ externalURLButton }
|
{ externalURLButton }
|
||||||
{ collapseReplyThread }
|
{ collapseReplyThread }
|
||||||
{ e2eInfo }
|
{ e2eInfo }
|
||||||
|
|
|
@ -16,8 +16,11 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import {EventStatus} from 'matrix-js-sdk';
|
||||||
|
|
||||||
import { _t } from '../../../languageHandler';
|
import { _t } from '../../../languageHandler';
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
|
import dis from '../../../dispatcher';
|
||||||
import Modal from '../../../Modal';
|
import Modal from '../../../Modal';
|
||||||
import { createMenu } from '../../structures/ContextualMenu';
|
import { createMenu } from '../../structures/ContextualMenu';
|
||||||
|
|
||||||
|
@ -45,7 +48,14 @@ export default class MessageActionBar extends React.PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onOptionsClicked = (ev) => {
|
onReplyClick = (ev) => {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'reply_to_event',
|
||||||
|
event: this.props.mxEvent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onOptionsClick = (ev) => {
|
||||||
const MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu');
|
const MessageContextMenu = sdk.getComponent('context_menus.MessageContextMenu');
|
||||||
const buttonRect = ev.target.getBoundingClientRect();
|
const buttonRect = ev.target.getBoundingClientRect();
|
||||||
|
|
||||||
|
@ -78,10 +88,33 @@ export default class MessageActionBar extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { mxEvent } = this.props;
|
||||||
|
const { status: eventStatus } = mxEvent;
|
||||||
|
|
||||||
|
// status is SENT before remote-echo, null after
|
||||||
|
const isSent = !eventStatus || eventStatus === EventStatus.SENT;
|
||||||
|
|
||||||
|
let replyButton;
|
||||||
|
|
||||||
|
if (isSent && mxEvent.getType() === 'm.room.message') {
|
||||||
|
const content = mxEvent.getContent();
|
||||||
|
if (
|
||||||
|
content.msgtype &&
|
||||||
|
content.msgtype !== 'm.bad.encrypted' &&
|
||||||
|
content.hasOwnProperty('body')
|
||||||
|
) {
|
||||||
|
replyButton = <span className="mx_MessageActionBar_replyButton"
|
||||||
|
title={_t("Reply")}
|
||||||
|
onClick={this.onReplyClick}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return <div className="mx_MessageActionBar">
|
return <div className="mx_MessageActionBar">
|
||||||
|
{replyButton}
|
||||||
<span className="mx_MessageActionBar_optionsButton"
|
<span className="mx_MessageActionBar_optionsButton"
|
||||||
title={_t("Options")}
|
title={_t("Options")}
|
||||||
onClick={this.onOptionsClicked}
|
onClick={this.onOptionsClick}
|
||||||
/>
|
/>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue