Fix edge cases around event list summaries with hidden events and redactions (#7797)
This commit is contained in:
parent
76fb2abae1
commit
0cf15d27dc
3 changed files with 38 additions and 28 deletions
|
@ -681,15 +681,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
for (const Grouper of groupers) {
|
for (const Grouper of groupers) {
|
||||||
if (Grouper.canStartGroup(this, mxEv) && !this.props.disableGrouping) {
|
if (Grouper.canStartGroup(this, mxEv) && !this.props.disableGrouping) {
|
||||||
grouper = new Grouper(
|
grouper = new Grouper(this, mxEv, prevEvent, lastShownEvent, nextEvent, nextTile);
|
||||||
this,
|
|
||||||
mxEv,
|
|
||||||
prevEvent,
|
|
||||||
lastShownEvent,
|
|
||||||
this.props.layout,
|
|
||||||
nextEvent,
|
|
||||||
nextTile,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!grouper) {
|
if (!grouper) {
|
||||||
|
@ -1056,7 +1048,6 @@ abstract class BaseGrouper {
|
||||||
public readonly event: MatrixEvent,
|
public readonly event: MatrixEvent,
|
||||||
public readonly prevEvent: MatrixEvent,
|
public readonly prevEvent: MatrixEvent,
|
||||||
public readonly lastShownEvent: MatrixEvent,
|
public readonly lastShownEvent: MatrixEvent,
|
||||||
protected readonly layout: Layout,
|
|
||||||
public readonly nextEvent?: MatrixEvent,
|
public readonly nextEvent?: MatrixEvent,
|
||||||
public readonly nextEventTile?: MatrixEvent,
|
public readonly nextEventTile?: MatrixEvent,
|
||||||
) {
|
) {
|
||||||
|
@ -1183,7 +1174,7 @@ class CreationGrouper extends BaseGrouper {
|
||||||
onToggle={panel.onHeightChanged} // Update scroll state
|
onToggle={panel.onHeightChanged} // Update scroll state
|
||||||
summaryMembers={[ev.sender]}
|
summaryMembers={[ev.sender]}
|
||||||
summaryText={summaryText}
|
summaryText={summaryText}
|
||||||
layout={this.layout}
|
layout={this.panel.props.layout}
|
||||||
>
|
>
|
||||||
{ eventTiles }
|
{ eventTiles }
|
||||||
</GenericEventListSummary>,
|
</GenericEventListSummary>,
|
||||||
|
@ -1226,11 +1217,10 @@ class MainGrouper extends BaseGrouper {
|
||||||
public readonly event: MatrixEvent,
|
public readonly event: MatrixEvent,
|
||||||
public readonly prevEvent: MatrixEvent,
|
public readonly prevEvent: MatrixEvent,
|
||||||
public readonly lastShownEvent: MatrixEvent,
|
public readonly lastShownEvent: MatrixEvent,
|
||||||
protected readonly layout: Layout,
|
|
||||||
nextEvent: MatrixEvent,
|
nextEvent: MatrixEvent,
|
||||||
nextEventTile: MatrixEvent,
|
nextEventTile: MatrixEvent,
|
||||||
) {
|
) {
|
||||||
super(panel, event, prevEvent, lastShownEvent, layout, nextEvent, nextEventTile);
|
super(panel, event, prevEvent, lastShownEvent, nextEvent, nextEventTile);
|
||||||
this.events = [event];
|
this.events = [event];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1296,15 +1286,18 @@ class MainGrouper extends BaseGrouper {
|
||||||
const key = "eventlistsummary-" + (this.prevEvent ? this.events[0].getId() : "initial");
|
const key = "eventlistsummary-" + (this.prevEvent ? this.events[0].getId() : "initial");
|
||||||
|
|
||||||
let highlightInSummary = false;
|
let highlightInSummary = false;
|
||||||
let eventTiles = this.events.map((e) => {
|
let eventTiles = this.events.map((e, i) => {
|
||||||
if (e.getId() === panel.props.highlightedEventId) {
|
if (e.getId() === panel.props.highlightedEventId) {
|
||||||
highlightInSummary = true;
|
highlightInSummary = true;
|
||||||
}
|
}
|
||||||
// In order to prevent DateSeparators from appearing in the expanded form
|
return panel.getTilesForEvent(
|
||||||
// of EventListSummary, render each member event as if the previous
|
i === 0 ? this.prevEvent : this.events[i - 1],
|
||||||
// one was itself. This way, the timestamp of the previous event === the
|
e,
|
||||||
// timestamp of the current event, and no DateSeparator is inserted.
|
e === lastShownEvent,
|
||||||
return panel.getTilesForEvent(e, e, e === lastShownEvent, isGrouped, this.nextEvent, this.nextEventTile);
|
isGrouped,
|
||||||
|
this.nextEvent,
|
||||||
|
this.nextEventTile,
|
||||||
|
);
|
||||||
}).reduce((a, b) => a.concat(b), []);
|
}).reduce((a, b) => a.concat(b), []);
|
||||||
|
|
||||||
if (eventTiles.length === 0) {
|
if (eventTiles.length === 0) {
|
||||||
|
@ -1323,7 +1316,7 @@ class MainGrouper extends BaseGrouper {
|
||||||
events={this.events}
|
events={this.events}
|
||||||
onToggle={panel.onHeightChanged} // Update scroll state
|
onToggle={panel.onHeightChanged} // Update scroll state
|
||||||
startExpanded={highlightInSummary}
|
startExpanded={highlightInSummary}
|
||||||
layout={this.layout}
|
layout={this.panel.props.layout}
|
||||||
>
|
>
|
||||||
{ eventTiles }
|
{ eventTiles }
|
||||||
</EventListSummary>,
|
</EventListSummary>,
|
||||||
|
@ -1337,7 +1330,7 @@ class MainGrouper extends BaseGrouper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getNewPrevEvent(): MatrixEvent {
|
public getNewPrevEvent(): MatrixEvent {
|
||||||
return this.events[0];
|
return this.events[this.events.length - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import { jsxJoin } from '../../../utils/ReactUtils';
|
||||||
import { Layout } from '../../../settings/enums/Layout';
|
import { Layout } from '../../../settings/enums/Layout';
|
||||||
import RightPanelStore from '../../../stores/right-panel/RightPanelStore';
|
import RightPanelStore from '../../../stores/right-panel/RightPanelStore';
|
||||||
import AccessibleButton from './AccessibleButton';
|
import AccessibleButton from './AccessibleButton';
|
||||||
|
import RoomContext from "../../../contexts/RoomContext";
|
||||||
|
|
||||||
const onPinnedMessagesClick = (): void => {
|
const onPinnedMessagesClick = (): void => {
|
||||||
RightPanelStore.instance.setCard({ phase: RightPanelPhases.PinnedMessages }, false);
|
RightPanelStore.instance.setCard({ phase: RightPanelPhases.PinnedMessages }, false);
|
||||||
|
@ -80,6 +81,9 @@ const SEP = ",";
|
||||||
|
|
||||||
@replaceableComponent("views.elements.EventListSummary")
|
@replaceableComponent("views.elements.EventListSummary")
|
||||||
export default class EventListSummary extends React.Component<IProps> {
|
export default class EventListSummary extends React.Component<IProps> {
|
||||||
|
static contextType = RoomContext;
|
||||||
|
public context!: React.ContextType<typeof RoomContext>;
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
summaryLength: 1,
|
summaryLength: 1,
|
||||||
threshold: 3,
|
threshold: 3,
|
||||||
|
@ -477,25 +481,37 @@ export default class EventListSummary extends React.Component<IProps> {
|
||||||
const userEvents: Record<string, IUserEvents[]> = {};
|
const userEvents: Record<string, IUserEvents[]> = {};
|
||||||
eventsToRender.forEach((e, index) => {
|
eventsToRender.forEach((e, index) => {
|
||||||
const type = e.getType();
|
const type = e.getType();
|
||||||
const userId = type === EventType.RoomServerAcl ? e.getSender() : e.getStateKey();
|
|
||||||
|
let userId = e.getSender();
|
||||||
|
if (type === EventType.RoomMember) {
|
||||||
|
userId = e.getStateKey();
|
||||||
|
} else if (e.isRedacted()) {
|
||||||
|
userId = e.getUnsigned()?.redacted_because?.sender;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialise a user's events
|
// Initialise a user's events
|
||||||
if (!userEvents[userId]) {
|
if (!userEvents[userId]) {
|
||||||
userEvents[userId] = [];
|
userEvents[userId] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.target && TARGET_AS_DISPLAY_NAME_EVENTS.includes(type as EventType)) {
|
|
||||||
latestUserAvatarMember.set(userId, e.target);
|
|
||||||
} else if (e.sender) {
|
|
||||||
latestUserAvatarMember.set(userId, e.sender);
|
|
||||||
}
|
|
||||||
|
|
||||||
let displayName = userId;
|
let displayName = userId;
|
||||||
if (type === EventType.RoomThirdPartyInvite) {
|
if (type === EventType.RoomThirdPartyInvite) {
|
||||||
displayName = e.getContent().display_name;
|
displayName = e.getContent().display_name;
|
||||||
|
if (e.sender) {
|
||||||
|
latestUserAvatarMember.set(userId, e.sender);
|
||||||
|
}
|
||||||
|
} else if (e.isRedacted()) {
|
||||||
|
const sender = this.context?.room.getMember(userId);
|
||||||
|
if (sender) {
|
||||||
|
displayName = sender.name;
|
||||||
|
latestUserAvatarMember.set(userId, sender);
|
||||||
|
}
|
||||||
} else if (e.target && TARGET_AS_DISPLAY_NAME_EVENTS.includes(type as EventType)) {
|
} else if (e.target && TARGET_AS_DISPLAY_NAME_EVENTS.includes(type as EventType)) {
|
||||||
displayName = e.target.name;
|
displayName = e.target.name;
|
||||||
|
latestUserAvatarMember.set(userId, e.target);
|
||||||
} else if (e.sender) {
|
} else if (e.sender) {
|
||||||
displayName = e.sender.name;
|
displayName = e.sender.name;
|
||||||
|
latestUserAvatarMember.set(userId, e.sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
userEvents[userId].push({
|
userEvents[userId].push({
|
||||||
|
|
|
@ -226,6 +226,7 @@ export function getEventDisplayInfo(mxEvent: MatrixEvent, hideEvent?: boolean):
|
||||||
!isBubbleMessage &&
|
!isBubbleMessage &&
|
||||||
!isLeftAlignedBubbleMessage &&
|
!isLeftAlignedBubbleMessage &&
|
||||||
eventType !== EventType.RoomMessage &&
|
eventType !== EventType.RoomMessage &&
|
||||||
|
eventType !== EventType.RoomMessageEncrypted &&
|
||||||
eventType !== EventType.Sticker &&
|
eventType !== EventType.Sticker &&
|
||||||
eventType !== EventType.RoomCreate &&
|
eventType !== EventType.RoomCreate &&
|
||||||
!M_POLL_START.matches(eventType)
|
!M_POLL_START.matches(eventType)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue