diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index 30c139d440..a83529e055 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -1063,102 +1063,5 @@ class MemberGrouper { } } -// Wrap consecutive redactions by the same user in a ListSummary, ignore if redacted -class RedactionGrouper { - static canStartGroup = function(panel, ev) { - return panel._shouldShowEvent(ev) && ev.isRedacted(); - } - - constructor(panel, ev, prevEvent, lastShownEvent) { - this.panel = panel; - this.readMarker = panel._readMarkerForEvent( - ev.getId(), - ev === lastShownEvent, - ); - this.events = [ev]; - this.prevEvent = prevEvent; - this.lastShownEvent = lastShownEvent; - } - - shouldGroup(ev) { - if (this.panel._wantsDateSeparator(this.events[0], ev.getDate())) return false; - if (ev.getType() === "m.room.redaction") return true; // for show-hidden-events users - return ev.isRedacted() && ev.sender === this.events[0].sender && - ev.getUnsigned().redacted_because.sender === this.events[0].getUnsigned().redacted_because.sender; - } - - add(ev) { - if (ev.getType() === "m.room.redaction") return; // for show-hidden-events users - this.readMarker = this.readMarker || this.panel._readMarkerForEvent( - ev.getId(), - ev === this.lastShownEvent, - ); - this.events.push(ev); - } - - getTiles() { - // If we don't have any events to group, don't even try to group them. The logic - // below assumes that we have a group of events to deal with, but we might not if - // the events we were supposed to group were redacted. - if (!this.events || !this.events.length) return []; - - const DateSeparator = sdk.getComponent('messages.DateSeparator'); - - const panel = this.panel; - const lastShownEvent = this.lastShownEvent; - const ret = []; - - if (panel._wantsDateSeparator(this.prevEvent, this.events[0].getDate())) { - const ts = this.events[0].getTs(); - ret.push( -
  • , - ); - } - - // Ensure that the key of the MemberEventListSummary does not change with new - // member events. This will prevent it from being re-created unnecessarily, and - // instead will allow new props to be provided. In turn, the shouldComponentUpdate - // method on ELS can be used to prevent unnecessary renderings. - const key = "redactioneventlistsummary-" + (this.prevEvent ? this.events[0].getId() : "initial"); - - let highlightInMels = false; - let eventTiles = this.events.map((e) => { - if (e.getId() === panel.props.highlightedEventId) { - highlightInMels = true; - } - // In order to prevent DateSeparators from appearing in the expanded form - // of MemberEventListSummary, render each member event as if the previous - // one was itself. This way, the timestamp of the previous event === the - // timestamp of the current event, and no DateSeparator is inserted. - return panel._getTilesForEvent(e, e, e === lastShownEvent); - }).reduce((a, b) => a.concat(b), []); - - if (eventTiles.length === 0) { - eventTiles = null; - } - - ret.push( - - { eventTiles } - , - ); - - if (this.readMarker) { - ret.push(this.readMarker); - } - - return ret; - } - - getNewPrevEvent() { - return this.events[0]; - } -} - // all the grouper classes that we use -const groupers = [CreationGrouper, MemberGrouper, RedactionGrouper]; +const groupers = [CreationGrouper, MemberGrouper]; diff --git a/src/components/views/elements/EventListSummary.js b/src/components/views/elements/EventListSummary.js index 79c84293c2..707b9e79b0 100644 --- a/src/components/views/elements/EventListSummary.js +++ b/src/components/views/elements/EventListSummary.js @@ -22,7 +22,8 @@ import {MatrixEvent, RoomMember} from "matrix-js-sdk"; import {useStateToggle} from "../../../hooks/useStateToggle"; import AccessibleButton from "./AccessibleButton"; -const EventListSummary = ({events, children, threshold=3, onToggle, startExpanded, summaryMembers=[], summaryText}) => { +const EventListSummary = (props) => { + const {events, children, threshold=3, onToggle, startExpanded, summaryMembers=[], summaryText, summary} = props; const [expanded, toggleExpanded] = useStateToggle(startExpanded); // Whenever expanded changes call onToggle @@ -49,6 +50,8 @@ const EventListSummary = ({events, children, threshold=3, onToggle, startExpande
     
    { children } ; + } else if (summary) { + body = summary; } else { const avatars = summaryMembers.map((m) => ); body = ( @@ -66,12 +69,12 @@ const EventListSummary = ({events, children, threshold=3, onToggle, startExpande } return ( -
    +
  • { expanded ? _t('collapse') : _t('expand') } { body } -
  • + ); }; @@ -87,10 +90,13 @@ EventListSummary.propTypes = { // Whether or not to begin with state.expanded=true startExpanded: PropTypes.bool, - // The list of room members for which to show avatars next to the summary + // The node to render as a summary when the summary is not collapsed, + // alternately summaryMembers and summaryText can be provided. + summary: PropTypes.node, + // The list of room members for which to show avatars next to the summary, ignored if summary is provided summaryMembers: PropTypes.arrayOf(PropTypes.instanceOf(RoomMember)), - // The text to show as the summary of this event list - summaryText: PropTypes.string.isRequired, + // The text to show as the summary of this event list, ignored if summary is provided + summaryText: PropTypes.string, }; export default EventListSummary; diff --git a/src/components/views/elements/RedactionEventListSummary.tsx b/src/components/views/elements/RedactionEventListSummary.tsx deleted file mode 100644 index 55538ca236..0000000000 --- a/src/components/views/elements/RedactionEventListSummary.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* -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 from "react"; -import {MatrixClient} from "matrix-js-sdk/src/client"; -import {MatrixEvent} from "matrix-js-sdk/src/models/event"; - -import { _t } from "../../../languageHandler"; -import * as sdk from "../../../index"; -import MatrixClientContext from "../../../contexts/MatrixClientContext"; - -interface IProps { - // An array of member events to summarise - events: MatrixEvent[]; - // An array of EventTiles to render when expanded - children: React.ReactChildren; - // The minimum number of events needed to trigger summarisation - threshold?: number; - // Called when the ELS expansion is toggled - onToggle: () => void; - // Whether or not to begin with state.expanded=true - startExpanded?: boolean; -} - -export default class RedactionEventListSummary extends React.Component { - static displayName = "RedactionEventListSummary"; - - static defaultProps = { - threshold: 2, - }; - - static contextType = MatrixClientContext; - - shouldComponentUpdate(nextProps) { - // Update if - // - The number of summarised events has changed - // - or if the summary is about to toggle to become collapsed - // - or if there are fewEvents, meaning the child eventTiles are shown as-is - return ( - nextProps.events.length !== this.props.events.length || - nextProps.events.length < this.props.threshold - ); - } - - render() { - const count = this.props.events.length; - const redactionSender = this.props.events[0].getUnsigned().redacted_because.sender; - - let avatarMember = this.props.events[0].sender; - let summaryText = _t("%(count)s messages deleted", { count }); - if (redactionSender !== this.context.getUserId()) { - const room = (this.context as MatrixClient).getRoom(redactionSender || this.props.events[0].getSender()); - avatarMember = room && room.getMember(redactionSender); - const name = avatarMember ? avatarMember.name : redactionSender; - summaryText = _t("%(count)s messages deleted by %(name)s", { count, name }); - } - - const EventListSummary = sdk.getComponent("views.elements.EventListSummary"); - return ; - } -}