diff --git a/res/css/_components.scss b/res/css/_components.scss index 0ba2b609e8..0344074369 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -140,10 +140,10 @@ @import "./views/messages/_ReactionsRow.scss"; @import "./views/messages/_ReactionsRowButton.scss"; @import "./views/messages/_ReactionsRowButtonTooltip.scss"; +@import "./views/messages/_RedactedBody.scss"; @import "./views/messages/_RoomAvatarEvent.scss"; @import "./views/messages/_SenderProfile.scss"; @import "./views/messages/_TextualEvent.scss"; -@import "./views/messages/_UnknownBody.scss"; @import "./views/messages/_ViewSourceEvent.scss"; @import "./views/messages/_common_CryptoEvent.scss"; @import "./views/right_panel/_EncryptionInfo.scss"; diff --git a/res/css/views/messages/_UnknownBody.scss b/res/css/views/messages/_RedactedBody.scss similarity index 51% rename from res/css/views/messages/_UnknownBody.scss rename to res/css/views/messages/_RedactedBody.scss index 9036e12bf0..9ba35d7297 100644 --- a/res/css/views/messages/_UnknownBody.scss +++ b/res/css/views/messages/_RedactedBody.scss @@ -1,5 +1,6 @@ /* -Copyright 2015, 2016 OpenMarket Ltd +Copyright 2020 The Matrix.org Foundation C.I.C. + 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 @@ -11,6 +12,25 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_UnknownBody { +.mx_RedactedBody { white-space: pre-wrap; + color: $muted-fg-color; + vertical-align: middle; + + padding-left: 20px; + position: relative; + + &::before { + height: 14px; + width: 14px; + background-color: $muted-fg-color; + mask-image: url('$(res)/img/feather-customised/trash (custom).svg'); + mask-repeat: no-repeat; + mask-position: center; + mask-size: contain; + content: ''; + position: absolute; + top: 2px; + left: 0; + } } diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss index 752cf982f6..d4e54f4473 100644 --- a/res/css/views/rooms/_EventTile.scss +++ b/res/css/views/rooms/_EventTile.scss @@ -244,34 +244,6 @@ limitations under the License. color: $event-notsent-color; } -.mx_EventTile_redacted .mx_EventTile_line .mx_UnknownBody, -.mx_EventTile_redacted .mx_EventTile_reply .mx_UnknownBody { - --lozenge-color: $event-redacted-fg-color; - --lozenge-border-color: $event-redacted-border-color; - display: block; - height: 22px; - width: 250px; - border-radius: 11px; - background: - repeating-linear-gradient( - -45deg, - var(--lozenge-color), - var(--lozenge-color) 3px, - transparent 3px, - transparent 6px - ); - box-shadow: 0px 0px 3px var(--lozenge-border-color) inset; -} - -.mx_EventTile_sending.mx_EventTile_redacted .mx_UnknownBody { - opacity: 0.4; -} - -div.mx_EventTile_notSent.mx_EventTile_redacted .mx_UnknownBody { - --lozenge-color: $event-notsent-color; - --lozenge-border-color: $event-notsent-color; -} - .mx_EventTile_contextual { opacity: 0.4; } diff --git a/res/img/feather-customised/trash (custom).svg b/res/img/feather-customised/trash (custom).svg new file mode 100644 index 0000000000..dc1985ddb2 --- /dev/null +++ b/res/img/feather-customised/trash (custom).svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 05354fa5f2..3929711406 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -1339,7 +1339,7 @@ export default class MatrixChat extends React.PureComponent { // this if we are not scrolled up in the view. To find out, delegate to // the timeline panel. If the timeline panel doesn't exist, then we assume // it is safe to reset the timeline. - if (!this.loggedInView.current || !this.loggedInView.current) { + if (!this.loggedInView.current) { return true; } return this.loggedInView.current.canResetTimelineInRoom(roomId); diff --git a/src/components/views/elements/EventListSummary.js b/src/components/views/elements/EventListSummary.js index 79c84293c2..5a4a6e4f5a 100644 --- a/src/components/views/elements/EventListSummary.js +++ b/src/components/views/elements/EventListSummary.js @@ -66,12 +66,12 @@ const EventListSummary = ({events, children, threshold=3, onToggle, startExpande } return ( -
+
  • { expanded ? _t('collapse') : _t('expand') } { body } -
  • + ); }; @@ -90,7 +90,7 @@ EventListSummary.propTypes = { // The list of room members for which to show avatars next to the summary summaryMembers: PropTypes.arrayOf(PropTypes.instanceOf(RoomMember)), // The text to show as the summary of this event list - summaryText: PropTypes.string.isRequired, + summaryText: PropTypes.string, }; export default EventListSummary; diff --git a/src/components/views/messages/EditHistoryMessage.js b/src/components/views/messages/EditHistoryMessage.js index 679a8f7471..e0ca23d244 100644 --- a/src/components/views/messages/EditHistoryMessage.js +++ b/src/components/views/messages/EditHistoryMessage.js @@ -26,6 +26,7 @@ import * as sdk from '../../../index'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import classNames from 'classnames'; +import RedactedBody from "./RedactedBody"; function getReplacedContent(event) { const originalContent = event.getOriginalContent(); @@ -132,8 +133,7 @@ export default class EditHistoryMessage extends React.PureComponent { const content = getReplacedContent(mxEvent); let contentContainer; if (mxEvent.isRedacted()) { - const UnknownBody = sdk.getComponent('messages.UnknownBody'); - contentContainer = ; + contentContainer = ; } else { let contentElements; if (this.props.previousEdit) { diff --git a/src/components/views/messages/MessageEvent.js b/src/components/views/messages/MessageEvent.js index beba986104..f8bd23cbe3 100644 --- a/src/components/views/messages/MessageEvent.js +++ b/src/components/views/messages/MessageEvent.js @@ -20,6 +20,7 @@ import createReactClass from 'create-react-class'; import * as sdk from '../../../index'; import SettingsStore from "../../../settings/SettingsStore"; import {Mjolnir} from "../../../mjolnir/Mjolnir"; +import RedactedBody from "./RedactedBody"; export default createReactClass({ displayName: 'MessageEvent', @@ -61,8 +62,6 @@ export default createReactClass({ }, render: function() { - const UnknownBody = sdk.getComponent('messages.UnknownBody'); - const bodyTypes = { 'm.text': sdk.getComponent('messages.TextualBody'), 'm.notice': sdk.getComponent('messages.TextualBody'), @@ -79,7 +78,7 @@ export default createReactClass({ const content = this.props.mxEvent.getContent(); const type = this.props.mxEvent.getType(); const msgtype = content.msgtype; - let BodyType = UnknownBody; + let BodyType = RedactedBody; if (!this.props.mxEvent.isRedacted()) { // only resolve BodyType if event is not redacted if (type && evTypes[type]) { diff --git a/src/components/views/messages/RedactedBody.tsx b/src/components/views/messages/RedactedBody.tsx new file mode 100644 index 0000000000..5dada64b52 --- /dev/null +++ b/src/components/views/messages/RedactedBody.tsx @@ -0,0 +1,46 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +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. +*/ + +import React, {useContext} from "react"; +import {MatrixClient} from "matrix-js-sdk/src/client"; +import {MatrixEvent} from "matrix-js-sdk/src/models/event"; +import { _t } from "../../../languageHandler"; +import MatrixClientContext from "../../../contexts/MatrixClientContext"; + +interface IProps { + mxEvent: MatrixEvent; +} + +const RedactedBody = React.forwardRef(({mxEvent}, ref) => { + const cli: MatrixClient = useContext(MatrixClientContext); + + let text = _t("Message deleted"); + const unsigned = mxEvent.getUnsigned(); + const redactedBecauseUserId = unsigned && unsigned.redacted_because && unsigned.redacted_because.sender; + if (redactedBecauseUserId && redactedBecauseUserId !== mxEvent.getSender()) { + const room = cli.getRoom(mxEvent.getRoomId()); + const sender = room && room.getMember(redactedBecauseUserId); + text = _t("Message deleted by %(name)s", { name: sender ? sender.name : redactedBecauseUserId }); + } + + return ( + + { text } + + ); +}); + +export default RedactedBody; diff --git a/src/components/views/messages/UnknownBody.js b/src/components/views/messages/UnknownBody.js deleted file mode 100644 index 2a19f324e8..0000000000 --- a/src/components/views/messages/UnknownBody.js +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2015, 2016 OpenMarket 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. -*/ - -import React from 'react'; -import createReactClass from 'create-react-class'; -import { _t } from '../../../languageHandler'; - -export default createReactClass({ - displayName: 'UnknownBody', - - render: function() { - let tooltip = _t("Removed or unknown message type"); - if (this.props.mxEvent.isRedacted()) { - const redactedBecauseUserId = this.props.mxEvent.getUnsigned().redacted_because.sender; - tooltip = redactedBecauseUserId ? - _t("Message removed by %(userId)s", { userId: redactedBecauseUserId }) : - _t("Message removed"); - } - - const text = this.props.mxEvent.getContent().body; - return ( - - { text } - - ); - }, -}); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a24b2bde73..27b4252f77 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1335,6 +1335,8 @@ "Reactions": "Reactions", " reacted with %(content)s": " reacted with %(content)s", "reacted with %(shortName)s": "reacted with %(shortName)s", + "Message deleted": "Message deleted", + "Message deleted by %(name)s": "Message deleted by %(name)s", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s changed the room avatar to ", @@ -1348,9 +1350,6 @@ "edited": "edited", "Can't load this message": "Can't load this message", "Submit logs": "Submit logs", - "Removed or unknown message type": "Removed or unknown message type", - "Message removed by %(userId)s": "Message removed by %(userId)s", - "Message removed": "Message removed", "Failed to load group members": "Failed to load group members", "Filter community members": "Filter community members", "Invite to this community": "Invite to this community",