MessageView: Show menu w/ 'reply to message' on triple-dot click

pull/1/head
Scott Nonnenberg 6 years ago
parent f4d9ab8ba0
commit 12257e1560
No known key found for this signature in database
GPG Key ID: 5F82280C35134661

@ -428,6 +428,10 @@
"selectAContact": {
"message": "Select a contact or group to start chatting."
},
"replyToMessage": {
"message": "Reply to Message",
"description": "Shown in triple-dot menu next to message to allow user to start crafting a message with a quotation"
},
"replyingToYourself": {
"message": "Replying to Yourself",
"description": "Shown in iOS theme when you quote yourself"

@ -297,8 +297,13 @@
<span class='timer'></span>
</div>
{{ #hoverIcon }}
<div class='hover-icon-container'>
<span class='dots-horizontal-icon'></span>
<div class='menu-container menu'>
<div class='menu-anchor'>
<span class='dots-horizontal-icon'></span>
<ul class='menu-list'>
<li class='reply'>{{ reply }}</li>
</ul>
</div>
</div>
{{ /hoverIcon }}
</div>

@ -4,6 +4,7 @@
/* global _: false */
/* global emoji_util: false */
/* global Mustache: false */
/* global $: false */
// eslint-disable-next-line func-names
(function () {
@ -216,7 +217,8 @@
'click .status': 'select',
'click .some-failed': 'select',
'click .error-message': 'select',
'click .hover-icon-container': 'onReply',
'click .menu-container': 'showMenu',
'click .menu-list .reply': 'onReply',
},
retryMessage() {
const retrys = _.filter(
@ -227,6 +229,23 @@
this.model.resend(number);
});
},
showMenu(e) {
if (this.menuVisible) {
return;
}
this.menuVisible = true;
e.stopPropagation();
this.$('.menu-list').show();
$(document).one('click', () => {
this.hideMenu();
});
},
hideMenu() {
this.menuVisible = false;
this.$('.menu-list').hide();
},
onReply() {
this.model.trigger('reply', this.model);
},
@ -428,6 +447,7 @@
innerBubbleClasses: this.isImageWithoutCaption() ? '' : 'with-tail',
hoverIcon: !hasErrors,
hasAttachments,
reply: i18n('replyToMessage'),
}, this.render_partials()));
this.timeStampView.setElement(this.$('.timestamp'));
this.timeStampView.update();

@ -353,26 +353,46 @@ li.entry .error-icon-container {
&:hover .error-message { display: inline-block; }
}
li.entry .hover-icon-container {
li.entry .menu-container {
position: absolute;
top: 0;
left: calc(100% + 5px);
height: 100%;
visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
.dots-horizontal-icon {
display: block;
height: 100%;
.menu-anchor {
position: relative;
}
li {
margin: 0px;
}
cursor: pointer;
}
li.entry:hover .hover-icon-container {
.dots-horizontal-icon {
visibility: hidden;
}
li.entry:hover .dots-horizontal-icon {
visibility: visible;
}
li.entry.outgoing .menu-container {
left: auto;
right: calc(100% + 5px);
}
.incoming .menu-list {
left: 0;
right: auto;
}
.error-icon {
display: inline-block;
width: $error-icon-size;
@ -557,10 +577,6 @@ span.status {
left: auto;
right: calc(100% + 5px);
}
.hover-icon-container {
left: auto;
right: calc(100% + 5px);
}
.avatar, .bubble {
float: right;

@ -232,8 +232,13 @@
<span class='timer'></span>
</div>
{{ #hoverIcon }}
<div class='hover-icon-container'>
<span class='dots-horizontal-icon'></span>
<div class='menu-container menu'>
<div class='menu-anchor'>
<span class='dots-horizontal-icon'></span>
<ul class='menu-list'>
<li class='reply'>{{ reply }}</li>
</ul>
</div>
</div>
{{ /hoverIcon }}
</div>

@ -52,8 +52,13 @@ window.Whisper.View.Templates = {
<span class='timer'></span>
</div>
{{ #hoverIcon }}
<div class='hover-icon-container'>
<span class='dots-horizontal-icon'></span>
<div class='menu-container menu'>
<div class='menu-anchor'>
<span class='dots-horizontal-icon'></span>
<ul class='menu-list'>
<li class='reply'>{{ reply }}</li>
</ul>
</div>
</div>
{{ /hoverIcon }}
</div>

@ -161,10 +161,17 @@ export class Quote extends React.Component<Props, {}> {
return null;
}
// We don't want the overall click handler for the quote to fire, so we stop
// propagation before handing control to the caller's callback.
const onClick = (e: React.MouseEvent<{}>): void => {
e.stopPropagation();
onClose();
};
// We need the container to give us the flexibility to implement the iOS design.
return (
<div className="close-container">
<div className="close-button" onClick={onClose}></div>
<div className="close-button" onClick={onClick}></div>
</div>
);
}

Loading…
Cancel
Save