diff --git a/res/css/_components.scss b/res/css/_components.scss index 9770010324..50e8eb11d1 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -53,7 +53,7 @@ @import "./views/elements/_InlineSpinner.scss"; @import "./views/elements/_MemberEventListSummary.scss"; @import "./views/elements/_ProgressBar.scss"; -@import "./views/elements/_Quote.scss"; +@import "./views/elements/_ReplyThread.scss"; @import "./views/elements/_RichText.scss"; @import "./views/elements/_RoleButton.scss"; @import "./views/elements/_Spinner.scss"; @@ -89,7 +89,7 @@ @import "./views/rooms/_PinnedEventTile.scss"; @import "./views/rooms/_PinnedEventsPanel.scss"; @import "./views/rooms/_PresenceLabel.scss"; -@import "./views/rooms/_QuotePreview.scss"; +@import "./views/rooms/_ReplyPreview.scss"; @import "./views/rooms/_RoomDropTarget.scss"; @import "./views/rooms/_RoomHeader.scss"; @import "./views/rooms/_RoomList.scss"; diff --git a/res/css/views/elements/_Quote.scss b/res/css/views/elements/_ReplyThread.scss similarity index 74% rename from res/css/views/elements/_Quote.scss rename to res/css/views/elements/_ReplyThread.scss index 0af555b5aa..a02f42751c 100644 --- a/res/css/views/elements/_Quote.scss +++ b/res/css/views/elements/_ReplyThread.scss @@ -1,5 +1,5 @@ /* -Copyright 2017 Vector Creations Ltd +Copyright 2018 Vector Creations Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -14,13 +14,19 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_Quote .mx_DateSeparator { +.mx_ReplyThread .mx_DateSeparator { font-size: 1em !important; margin-bottom: 0; padding-bottom: 1px; bottom: -5px; } -.mx_Quote_show { +.mx_ReplyThread_show { cursor: pointer; } + +blockquote.mx_ReplyThread { + margin-left: 0; + padding-left: 10px; + border-left: 4px solid $blockquote-bar-color; +} diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 4bb81a2e53..d721e1f7cd 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -84,7 +84,7 @@ limitations under the License. position: absolute; } -.mx_EventTile_line { +.mx_EventTile_line, .mx_EventTile_reply { position: relative; /* ideally should be 100px, but 95px gives us a max thumbnail size of 800x600, which is nice */ margin-right: 110px; @@ -96,7 +96,7 @@ limitations under the License. line-height: 22px; } -.mx_EventTile_quote { +.mx_EventTile_reply { margin-right: 10px; } @@ -119,7 +119,7 @@ limitations under the License. background-color: $event-selected-color; } -.mx_EventTile:hover .mx_EventTile_line:not(.mx_EventTile_quote), +..mx_EventTile:hover .mx_EventTile_line, .mx_EventTile.menu .mx_EventTile_line { background-color: $event-selected-color; @@ -157,7 +157,8 @@ limitations under the License. color: $event-notsent-color; } -.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody { +.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody, +.mx_EventTile_redacted .mx_EventTile_reply .mx_UnknownBody { display: block; width: 100%; height: 22px; @@ -202,10 +203,9 @@ limitations under the License. text-decoration: none; } -.mx_EventTile_last .mx_MessageTimestamp, -.mx_EventTile:hover .mx_MessageTimestamp, -.mx_EventTile.menu .mx_MessageTimestamp -{ +.mx_EventTile_last > div > a > .mx_MessageTimestamp, +.mx_EventTile:hover > div > a > .mx_MessageTimestamp, +.mx_EventTile.menu > div > a > .mx_MessageTimestamp { visibility: visible; } @@ -235,12 +235,7 @@ limitations under the License. } .mx_EventTile:hover .mx_EventTile_editButton, -.mx_EventTile.menu .mx_EventTile_editButton -{ - visibility: visible; -} - -.mx_EventTile.menu .mx_MessageTimestamp { +.mx_EventTile.menu .mx_EventTile_editButton { visibility: visible; } @@ -348,8 +343,8 @@ limitations under the License. border-left: $e2e-unverified-color 5px solid; } -.mx_EventTile:hover.mx_EventTile_verified .mx_MessageTimestamp, -.mx_EventTile:hover.mx_EventTile_unverified .mx_MessageTimestamp { +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > a > .mx_MessageTimestamp, +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > a > .mx_MessageTimestamp { left: 3px; width: auto; } @@ -360,8 +355,8 @@ limitations under the License. } */ -.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_e2eIcon, -.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_e2eIcon { +.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_line > .mx_EventTile_e2eIcon, +.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_line > .mx_EventTile_e2eIcon { display: block; left: 41px; } @@ -456,7 +451,7 @@ limitations under the License. // same as the padding for non-compact .mx_EventTile.mx_EventTile_info padding-top: 0px; font-size: 13px; - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { line-height: 20px; } .mx_EventTile_avatar { @@ -474,7 +469,7 @@ limitations under the License. .mx_EventTile_avatar { top: 2px; } - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 1px; } @@ -482,13 +477,13 @@ limitations under the License. .mx_EventTile.mx_EventTile_emote.mx_EventTile_continuation { padding-top: 0; - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 0px; } } - .mx_EventTile_line { + .mx_EventTile_line, .mx_EventTile_reply { padding-top: 0px; padding-bottom: 0px; } diff --git a/res/css/views/rooms/_QuotePreview.scss b/res/css/views/rooms/_QuotePreview.scss deleted file mode 100644 index 86fd79d473..0000000000 --- a/res/css/views/rooms/_QuotePreview.scss +++ /dev/null @@ -1,36 +0,0 @@ -.mx_QuotePreview { - position: absolute; - bottom: 0; - z-index: 1000; - width: 100%; - border: 1px solid $primary-hairline-color; - background: $primary-bg-color; - border-bottom: none; - border-radius: 4px 4px 0 0; - max-height: 50vh; - overflow: auto -} - -.mx_QuotePreview_section { - border-bottom: 1px solid $primary-hairline-color; -} - -.mx_QuotePreview_header { - margin: 12px; - color: $primary-fg-color; - font-weight: 400; - opacity: 0.4; -} - -.mx_QuotePreview_title { - float: left; -} - -.mx_QuotePreview_cancel { - float: right; - cursor: pointer; -} - -.mx_QuotePreview_clear { - clear: both; -} diff --git a/res/css/views/rooms/_ReplyPreview.scss b/res/css/views/rooms/_ReplyPreview.scss new file mode 100644 index 0000000000..5bf4adff27 --- /dev/null +++ b/res/css/views/rooms/_ReplyPreview.scss @@ -0,0 +1,52 @@ +/* +Copyright 2018 Vector Creations Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_ReplyPreview { + position: absolute; + bottom: 0; + z-index: 1000; + width: 100%; + border: 1px solid $primary-hairline-color; + background: $primary-bg-color; + border-bottom: none; + border-radius: 4px 4px 0 0; + max-height: 50vh; + overflow: auto +} + +.mx_ReplyPreview_section { + border-bottom: 1px solid $primary-hairline-color; +} + +.mx_ReplyPreview_header { + margin: 12px; + color: $primary-fg-color; + font-weight: 400; + opacity: 0.4; +} + +.mx_ReplyPreview_title { + float: left; +} + +.mx_ReplyPreview_cancel { + float: right; + cursor: pointer; +} + +.mx_ReplyPreview_clear { + clear: both; +} diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js index 860d94ea0e..dc6f4d45d0 100644 --- a/src/components/views/context_menus/MessageContextMenu.js +++ b/src/components/views/context_menus/MessageContextMenu.js @@ -18,6 +18,7 @@ limitations under the License. 'use strict'; import React from 'react'; +import PropTypes from 'prop-types'; import MatrixClientPeg from '../../../MatrixClientPeg'; import dis from '../../../dispatcher'; @@ -34,13 +35,16 @@ module.exports = React.createClass({ propTypes: { /* the MatrixEvent associated with the context menu */ - mxEvent: React.PropTypes.object.isRequired, + mxEvent: PropTypes.object.isRequired, /* an optional EventTileOps implementation that can be used to unhide preview widgets */ - eventTileOps: React.PropTypes.object, + eventTileOps: PropTypes.object, + + /* an optional function which allows to collapse reply thread */ + collapseReplyThread: PropTypes.func, /* callback called when the menu is dismissed */ - onFinished: React.PropTypes.func, + onFinished: PropTypes.func, }, getInitialState: function() { @@ -182,12 +186,17 @@ module.exports = React.createClass({ onReplyClick: function() { dis.dispatch({ - action: 'quote_event', + action: 'reply_to_event', event: this.props.mxEvent, }); this.closeMenu(); }, + onCollapseReplyThreadClick: function() { + this.props.collapseReplyThread(); + this.closeMenu(); + }, + render: function() { const eventStatus = this.props.mxEvent.status; let resendButton; @@ -200,6 +209,7 @@ module.exports = React.createClass({ let externalURLButton; let quoteButton; let replyButton; + let collapseReplyThread; if (eventStatus === 'not_sent') { resendButton = ( @@ -305,6 +315,13 @@ module.exports = React.createClass({ ); } + if (this.props.collapseReplyThread) { + collapseReplyThread = ( +