Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Replies #1741

Merged
merged 77 commits into from
May 2, 2018
Merged

Replies #1741

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
1c3d8cb
initial refactor of Replies to use `B` explicit over-the-wire format
t3chguy Feb 10, 2018
a15d024
Merge branches 'develop' and 't3chguy/m.relates_to' of github.com:mat…
t3chguy Feb 10, 2018
1814546
fix Replies for e2e
t3chguy Feb 10, 2018
fbb950e
mass s/Quote/Reply
t3chguy Feb 10, 2018
23c0daa
pass onWidgetLoad to fix console err for e2e
t3chguy Feb 10, 2018
7425d01
tidy, improve error handling and improve Replies, run gen-i18n
t3chguy Feb 10, 2018
25bc9cf
make spinner size more appropriate
t3chguy Feb 10, 2018
7bf05b0
add unmounted guard
t3chguy Feb 10, 2018
aeedf48
fix weird `in` op behaviour with null
t3chguy Feb 11, 2018
2e3cbb3
Merge branches 'develop' and 't3chguy/m.relates_to' of github.com:mat…
t3chguy Feb 16, 2018
8062494
show replies in ReplyPreview
t3chguy Feb 16, 2018
cb293a8
reply and reply_preview only differ in whether they contain <Reply />
t3chguy Feb 16, 2018
f1a3592
fix 12/24h in Reply/ReplyPreview
t3chguy Feb 16, 2018
0d6fc9b
fix Composer focus after twiddling with Replies
t3chguy Feb 16, 2018
4c08c51
Reply; delay call to onWidgetLoad until after async setState completes
t3chguy Feb 16, 2018
8fa56f8
update and improve comments
t3chguy Feb 19, 2018
6510989
move unmounted init to willMount
t3chguy Feb 19, 2018
34b427d
s/quote_event/reply_to_event/
t3chguy Feb 19, 2018
7048d85
attach message_sent and replies to file uploads
t3chguy Feb 19, 2018
90f9bad
s/Reply/ReplyThread/
t3chguy Feb 20, 2018
665ddcc
restrict to m.text for now
t3chguy Feb 20, 2018
df56a67
Add reply fallback and run gen-i18n
t3chguy Mar 4, 2018
3b02766
isHtml makes no sense if there is no formatted_body
t3chguy Mar 5, 2018
ed8f087
fix access of element [0] of array even though it sometimes does not …
t3chguy Mar 6, 2018
023632e
only strip reply fallbacks if the lab is enabled
t3chguy Mar 9, 2018
14f29e4
fix the bugs Tulir found - THANKS
t3chguy Mar 9, 2018
0ed3563
clear quoting event even on send fail, as then we can click retry
t3chguy Mar 15, 2018
6610734
implement desired m.room.message->m.text fallbacks
t3chguy Mar 16, 2018
b5ed08e
Merge
t3chguy Mar 24, 2018
fac89d9
Merge branch 'develop' into t3chguy/m.relates_to
t3chguy Mar 28, 2018
a390cec
fix missing null-guard
t3chguy Mar 29, 2018
8fa4a52
Merge remote-tracking branch 'origin/t3chguy/m.relates_to' into t3chg…
t3chguy Mar 29, 2018
80fbc75
Merge branches 'develop' and 't3chguy/m.relates_to' of github.com:mat…
t3chguy Mar 31, 2018
9c2e3e2
clear reply_to_event at queue not send time
t3chguy Apr 4, 2018
2854f2b
allow BigEmoji calc to ignore replies fallback if enabled
t3chguy Apr 4, 2018
1d90835
Merge branches 'develop' and 't3chguy/m.relates_to' of github.com:mat…
t3chguy Apr 4, 2018
9df2f7d
Add warning to Upload Confirm prompt if replying, as can't reply with…
t3chguy Apr 4, 2018
4081321
run i18n prune and gen
t3chguy Apr 4, 2018
871fee2
run i18n prune and gen
t3chguy Apr 4, 2018
f765db7
only clear reply_to_event if there was one to begin with
t3chguy Apr 7, 2018
c77807b
Merge branches 'develop' and 't3chguy/m.relates_to' of github.com:mat…
t3chguy Apr 12, 2018
8b1e411
Merge branches 'develop' and 't3chguy/m.relates_to' of github.com:mat…
t3chguy Apr 13, 2018
a90bd6c
Allow collapsing ReplyThread from MessageContextMenu
t3chguy Apr 13, 2018
58cd585
start of BigMerge fixup
t3chguy Apr 20, 2018
06408f8
post BigMerge fixup - merge in stuff from riot-web PR
t3chguy Apr 20, 2018
563fc9a
fix bad copy-paste from other diff
t3chguy Apr 20, 2018
7e8288f
i18n-gen, i18n-prune
t3chguy Apr 20, 2018
941bb94
fix reply fallback blunder
t3chguy Apr 20, 2018
d680d80
Merge branch 'develop' into t3chguy/m.relates_to
t3chguy Apr 23, 2018
057815a
Reset accidental merge changes
t3chguy Apr 23, 2018
5f920f7
Reset accidental merge changes 2.0
t3chguy Apr 23, 2018
0f11bc6
undo code style change
t3chguy Apr 23, 2018
71acf87
Add comments to _EventTile.scss
t3chguy Apr 27, 2018
3de679b
Add comment to HtmlUtils.js
t3chguy Apr 27, 2018
82d1179
Remove unused import
t3chguy Apr 27, 2018
4a0a5c6
Merge remote-tracking branch 'origin/t3chguy/m.relates_to' into t3chg…
t3chguy Apr 27, 2018
97fecae
improve wording
t3chguy Apr 27, 2018
88f4891
improve comment
t3chguy Apr 27, 2018
3ba9f56
get MatrixClient from context
t3chguy Apr 27, 2018
fdf63fd
replace concat on comment from review
t3chguy Apr 27, 2018
ca766df
call onWidgetLoad on componentDidUpdate
t3chguy Apr 27, 2018
3050553
rename and change getInReplyTo
t3chguy Apr 27, 2018
68dd57f
rename two methods
t3chguy Apr 27, 2018
2e29a08
improve stripPlainReply comment and fix leading NewLine
t3chguy Apr 27, 2018
bbf4d3e
add comment
t3chguy Apr 28, 2018
5bb15b1
simplify logic
t3chguy Apr 28, 2018
407be88
add comment
t3chguy Apr 28, 2018
c00c52e
added another comment
t3chguy Apr 28, 2018
4021fc0
re-arrange method order to group statics before instance methods
t3chguy Apr 28, 2018
41af9f7
fix changed method name
t3chguy Apr 29, 2018
bbce6ee
update comment
t3chguy Apr 30, 2018
f0bd4a5
Refactor tests to understand sendMessage instead of send{Text,Html}Me…
t3chguy May 1, 2018
11ae080
re-order ReplyThread methods for readability
t3chguy May 1, 2018
db55f87
avoid `.done` and `.then` anti-pattern
t3chguy May 1, 2018
ec4ec47
clean up EventTile:onWidgetLoad optional/required mess
t3chguy May 1, 2018
f2102e2
Merge branches 'develop' and 't3chguy/m.relates_to' of github.com:mat…
t3chguy May 2, 2018
4c3f811
switch RoomView:uploadFile to async to clean up then/catch handling
t3chguy May 2, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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;
}
42 changes: 20 additions & 22 deletions res/css/views/rooms/_EventTile.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -96,7 +96,7 @@ limitations under the License.
line-height: 22px;
}

.mx_EventTile_quote {
.mx_EventTile_reply {
margin-right: 10px;
}

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -202,10 +203,10 @@ limitations under the License.
text-decoration: none;
}

.mx_EventTile_last .mx_MessageTimestamp,
.mx_EventTile:hover .mx_MessageTimestamp,
.mx_EventTile.menu .mx_MessageTimestamp
{
// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies)
.mx_EventTile_last > div > a > .mx_MessageTimestamp,
.mx_EventTile:hover > div > a > .mx_MessageTimestamp,
.mx_EventTile.menu > div > a > .mx_MessageTimestamp {
visibility: visible;
}

Expand Down Expand Up @@ -235,12 +236,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;
}

Expand Down Expand Up @@ -358,8 +354,9 @@ 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 {
// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies)
.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;
}
Expand All @@ -370,8 +367,9 @@ limitations under the License.
}
*/

.mx_EventTile:hover.mx_EventTile_verified .mx_EventTile_e2eIcon,
.mx_EventTile:hover.mx_EventTile_unverified .mx_EventTile_e2eIcon {
// Explicit relationships so that it doesn't apply to nested EventTile components (e.g in Replies)
.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;
}
Expand Down Expand Up @@ -466,7 +464,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 {
Expand All @@ -484,21 +482,21 @@ limitations under the License.
.mx_EventTile_avatar {
top: 2px;
}
.mx_EventTile_line {
.mx_EventTile_line, .mx_EventTile_reply {
padding-top: 0px;
padding-bottom: 1px;
}
}

.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;
}
Expand Down
36 changes: 0 additions & 36 deletions res/css/views/rooms/_QuotePreview.scss

This file was deleted.

52 changes: 52 additions & 0 deletions res/css/views/rooms/_ReplyPreview.scss
Original file line number Diff line number Diff line change
@@ -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;
}
22 changes: 16 additions & 6 deletions src/HtmlUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.

'use strict';

import ReplyThread from "./components/views/elements/ReplyThread";

const React = require('react');
const sanitizeHtml = require('sanitize-html');
const highlight = require('highlight.js');
Expand Down Expand Up @@ -184,6 +186,7 @@ const sanitizeHtmlParams = {
],
allowedAttributes: {
// custom ones first:
blockquote: ['data-mx-reply'], // used to allow explicit removal of a reply fallback blockquote, value ignored
font: ['color', 'data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix
span: ['data-mx-bg-color', 'data-mx-color', 'style'], // custom to matrix
a: ['href', 'name', 'target', 'rel'], // remote target: custom to matrix
Expand Down Expand Up @@ -408,12 +411,14 @@ class TextHighlighter extends BaseHighlighter {
*
* opts.highlightLink: optional href to add to highlighted words
* opts.disableBigEmoji: optional argument to disable the big emoji class.
* opts.stripReplyFallback: optional argument specifying the event is a reply and so fallback needs removing
*/
export function bodyToHtml(content, highlights, opts={}) {
let isHtml = (content.format === "org.matrix.custom.html");
let isHtml = content.format === "org.matrix.custom.html" && content.formatted_body;

let bodyHasEmoji = false;

let strippedBody;
let safeBody;
// XXX: We sanitize the HTML whilst also highlighting its text nodes, to avoid accidentally trying
// to highlight HTML tags themselves. However, this does mean that we don't highlight textnodes which
Expand All @@ -431,17 +436,22 @@ export function bodyToHtml(content, highlights, opts={}) {
};
}

bodyHasEmoji = containsEmoji(isHtml ? content.formatted_body : content.body);
let formattedBody = content.formatted_body;
if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyThread.stripHTMLReply(formattedBody);
strippedBody = opts.stripReplyFallback ? ReplyThread.stripPlainReply(content.body) : content.body;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really not sure that this should be part of sanitising. The quoted text does not threaten the security of the app.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure where better to put this, technically this method is not specific to sanitising, its just turn a matrix event body into html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you're totally right.


bodyHasEmoji = containsEmoji(isHtml ? formattedBody : content.body);


// Only generate safeBody if the message was sent as org.matrix.custom.html
if (isHtml) {
safeBody = sanitizeHtml(content.formatted_body, sanitizeHtmlParams);
safeBody = sanitizeHtml(formattedBody, sanitizeHtmlParams);
} else {
// ... or if there are emoji, which we insert as HTML alongside the
// escaped plaintext body.
if (bodyHasEmoji) {
isHtml = true;
safeBody = sanitizeHtml(escape(content.body), sanitizeHtmlParams);
safeBody = sanitizeHtml(escape(strippedBody), sanitizeHtmlParams);
}
}

Expand All @@ -458,7 +468,7 @@ export function bodyToHtml(content, highlights, opts={}) {
let emojiBody = false;
if (!opts.disableBigEmoji && bodyHasEmoji) {
EMOJI_REGEX.lastIndex = 0;
const contentBodyTrimmed = content.body !== undefined ? content.body.trim() : '';
const contentBodyTrimmed = strippedBody !== undefined ? strippedBody.trim() : '';
const match = EMOJI_REGEX.exec(contentBodyTrimmed);
emojiBody = match && match[0] && match[0].length === contentBodyTrimmed.length;
}
Expand All @@ -471,7 +481,7 @@ export function bodyToHtml(content, highlights, opts={}) {

return isHtml ?
<span className={className} dangerouslySetInnerHTML={{ __html: safeBody }} dir="auto" /> :
<span className={className} dir="auto">{ content.body }</span>;
<span className={className} dir="auto">{ strippedBody }</span>;
}

export function emojifyText(text) {
Expand Down
18 changes: 13 additions & 5 deletions src/components/structures/RoomView.js
Original file line number Diff line number Diff line change
Expand Up @@ -908,17 +908,17 @@ module.exports = React.createClass({
this.setState({ draggingFile: false });
},

uploadFile: function(file) {
uploadFile: async function(file) {
if (MatrixClientPeg.get().isGuest()) {
dis.dispatch({action: 'view_set_mxid'});
return;
}

ContentMessages.sendContentToRoom(
file, this.state.room.roomId, MatrixClientPeg.get(),
).catch((error) => {
try {
await ContentMessages.sendContentToRoom(file, this.state.room.roomId, MatrixClientPeg.get());
} catch (error) {
if (error.name === "UnknownDeviceError") {
// Let the staus bar handle this
// Let the status bar handle this
return;
}
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Expand All @@ -928,6 +928,14 @@ module.exports = React.createClass({
description: ((error && error.message)
? error.message : _t("Server may be unavailable, overloaded, or the file too big")),
});

// bail early to avoid calling the dispatch below
return;
}

// Send message_sent callback, for things like _checkIfAlone because after all a file is still a message.
dis.dispatch({
action: 'message_sent',
});
},

Expand Down
Loading