mirror of https://github.com/vector-im/riot-web
Merge remote-tracking branch 'upstream/develop' into fix/17130/draggable-pip
commit
3b1ee979fd
|
@ -3,6 +3,6 @@
|
||||||
# docker push vectorim/element-web-ci-e2etests-env:latest
|
# docker push vectorim/element-web-ci-e2etests-env:latest
|
||||||
FROM node:14-buster
|
FROM node:14-buster
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get -y install build-essential python3-dev libffi-dev python-pip python-setuptools sqlite3 libssl-dev python-virtualenv libjpeg-dev libxslt1-dev uuid-runtime
|
RUN apt-get -y install jq build-essential python3-dev libffi-dev python-pip python-setuptools sqlite3 libssl-dev python-virtualenv libjpeg-dev libxslt1-dev uuid-runtime
|
||||||
# dependencies for chrome (installed by puppeteer)
|
# dependencies for chrome (installed by puppeteer)
|
||||||
RUN apt-get -y install gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
|
RUN apt-get -y install gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
|
||||||
|
|
|
@ -263,7 +263,8 @@ export default class TextualBody extends React.Component {
|
||||||
//console.info("shouldComponentUpdate: ShowUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
|
//console.info("shouldComponentUpdate: ShowUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
|
||||||
|
|
||||||
// exploit that events are immutable :)
|
// exploit that events are immutable :)
|
||||||
return (nextProps.mxEvent.getId() !== this.props.mxEvent.getId() ||
|
return (nextProps.mxEvent !== this.props.mxEvent ||
|
||||||
|
nextProps.mxEvent.getId() !== this.props.mxEvent.getId() ||
|
||||||
nextProps.highlights !== this.props.highlights ||
|
nextProps.highlights !== this.props.highlights ||
|
||||||
nextProps.replacingEventId !== this.props.replacingEventId ||
|
nextProps.replacingEventId !== this.props.replacingEventId ||
|
||||||
nextProps.highlightLink !== this.props.highlightLink ||
|
nextProps.highlightLink !== this.props.highlightLink ||
|
||||||
|
|
|
@ -300,6 +300,9 @@ interface IState {
|
||||||
// The Relations model from the JS SDK for reactions to `mxEvent`
|
// The Relations model from the JS SDK for reactions to `mxEvent`
|
||||||
reactions: Relations;
|
reactions: Relations;
|
||||||
|
|
||||||
|
// Our snapshotted/local copy of the props.mxEvent, for local echo reasons
|
||||||
|
mxEvent: MatrixEvent;
|
||||||
|
|
||||||
hover: boolean;
|
hover: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,6 +337,8 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
// The Relations model from the JS SDK for reactions to `mxEvent`
|
// The Relations model from the JS SDK for reactions to `mxEvent`
|
||||||
reactions: this.getReactions(),
|
reactions: this.getReactions(),
|
||||||
|
|
||||||
|
mxEvent: this.mxEvent.toSnapshot(), // snapshot up front to verify it all works
|
||||||
|
|
||||||
hover: false,
|
hover: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -350,6 +355,10 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
this.ref = React.createRef();
|
this.ref = React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get mxEvent(): MatrixEvent {
|
||||||
|
return this.state?.mxEvent ?? this.props.mxEvent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When true, the tile qualifies for some sort of special read receipt. This could be a 'sending'
|
* When true, the tile qualifies for some sort of special read receipt. This could be a 'sending'
|
||||||
* or 'sent' receipt, for example.
|
* or 'sent' receipt, for example.
|
||||||
|
@ -358,16 +367,16 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
private get isEligibleForSpecialReceipt() {
|
private get isEligibleForSpecialReceipt() {
|
||||||
// First, if there are other read receipts then just short-circuit this.
|
// First, if there are other read receipts then just short-circuit this.
|
||||||
if (this.props.readReceipts && this.props.readReceipts.length > 0) return false;
|
if (this.props.readReceipts && this.props.readReceipts.length > 0) return false;
|
||||||
if (!this.props.mxEvent) return false;
|
if (!this.mxEvent) return false;
|
||||||
|
|
||||||
// Sanity check (should never happen, but we shouldn't explode if it does)
|
// Sanity check (should never happen, but we shouldn't explode if it does)
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = this.context.getRoom(this.mxEvent.getRoomId());
|
||||||
if (!room) return false;
|
if (!room) return false;
|
||||||
|
|
||||||
// Quickly check to see if the event was sent by us. If it wasn't, it won't qualify for
|
// Quickly check to see if the event was sent by us. If it wasn't, it won't qualify for
|
||||||
// special read receipts.
|
// special read receipts.
|
||||||
const myUserId = MatrixClientPeg.get().getUserId();
|
const myUserId = MatrixClientPeg.get().getUserId();
|
||||||
if (this.props.mxEvent.getSender() !== myUserId) return false;
|
if (this.mxEvent.getSender() !== myUserId) return false;
|
||||||
|
|
||||||
// Finally, determine if the type is relevant to the user. This notably excludes state
|
// Finally, determine if the type is relevant to the user. This notably excludes state
|
||||||
// events and pretty much anything that can't be sent by the composer as a message. For
|
// events and pretty much anything that can't be sent by the composer as a message. For
|
||||||
|
@ -378,7 +387,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
EventType.RoomMessage,
|
EventType.RoomMessage,
|
||||||
EventType.RoomMessageEncrypted,
|
EventType.RoomMessageEncrypted,
|
||||||
];
|
];
|
||||||
if (!simpleSendableEvents.includes(this.props.mxEvent.getType() as EventType)) return false;
|
if (!simpleSendableEvents.includes(this.mxEvent.getType() as EventType)) return false;
|
||||||
|
|
||||||
// Default case
|
// Default case
|
||||||
return true;
|
return true;
|
||||||
|
@ -420,7 +429,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
// TODO: [REACT-WARNING] Move into constructor
|
// TODO: [REACT-WARNING] Move into constructor
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
UNSAFE_componentWillMount() {
|
UNSAFE_componentWillMount() {
|
||||||
this.verifyEvent(this.props.mxEvent);
|
this.verifyEvent(this.mxEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -450,11 +459,21 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
// If the echo changed meaningfully, update.
|
||||||
|
if (!this.state.mxEvent?.isEquivalentTo(nextProps.mxEvent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (objectHasDiff(this.state, nextState)) {
|
if (objectHasDiff(this.state, nextState)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !this.propsEqual(this.props, nextProps);
|
if (!this.propsEqual(this.props, nextProps)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always assume there's no significant change.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -475,11 +494,18 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
this.context.on("Room.receipt", this.onRoomReceipt);
|
this.context.on("Room.receipt", this.onRoomReceipt);
|
||||||
this.isListeningForReceipts = true;
|
this.isListeningForReceipts = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the state again if the snapshot needs updating. Note that this will fire
|
||||||
|
// a second state update to re-render child components, which ultimately calls didUpdate
|
||||||
|
// again, so we break that loop with a reference check first (faster than comparing events).
|
||||||
|
if (this.state.mxEvent === prevState.mxEvent && !this.state?.mxEvent.isEquivalentTo(this.props.mxEvent)) {
|
||||||
|
this.setState({mxEvent: this.props.mxEvent.toSnapshot()});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onRoomReceipt = (ev, room) => {
|
private onRoomReceipt = (ev, room) => {
|
||||||
// ignore events for other rooms
|
// ignore events for other rooms
|
||||||
const tileRoom = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
|
const tileRoom = MatrixClientPeg.get().getRoom(this.mxEvent.getRoomId());
|
||||||
if (room !== tileRoom) return;
|
if (room !== tileRoom) return;
|
||||||
|
|
||||||
if (!this.shouldShowSentReceipt && !this.shouldShowSendingReceipt && !this.isListeningForReceipts) {
|
if (!this.shouldShowSentReceipt && !this.shouldShowSendingReceipt && !this.isListeningForReceipts) {
|
||||||
|
@ -503,19 +529,19 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
// we need to re-verify the sending device.
|
// we need to re-verify the sending device.
|
||||||
// (we call onHeightChanged in verifyEvent to handle the case where decryption
|
// (we call onHeightChanged in verifyEvent to handle the case where decryption
|
||||||
// has caused a change in size of the event tile)
|
// has caused a change in size of the event tile)
|
||||||
this.verifyEvent(this.props.mxEvent);
|
this.verifyEvent(this.mxEvent);
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
private onDeviceVerificationChanged = (userId, device) => {
|
private onDeviceVerificationChanged = (userId, device) => {
|
||||||
if (userId === this.props.mxEvent.getSender()) {
|
if (userId === this.mxEvent.getSender()) {
|
||||||
this.verifyEvent(this.props.mxEvent);
|
this.verifyEvent(this.mxEvent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private onUserVerificationChanged = (userId, _trustStatus) => {
|
private onUserVerificationChanged = (userId, _trustStatus) => {
|
||||||
if (userId === this.props.mxEvent.getSender()) {
|
if (userId === this.mxEvent.getSender()) {
|
||||||
this.verifyEvent(this.props.mxEvent);
|
this.verifyEvent(this.mxEvent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -622,11 +648,11 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldHighlight() {
|
shouldHighlight() {
|
||||||
const actions = this.context.getPushActionsForEvent(this.props.mxEvent.replacingEvent() || this.props.mxEvent);
|
const actions = this.context.getPushActionsForEvent(this.mxEvent.replacingEvent() || this.mxEvent);
|
||||||
if (!actions || !actions.tweaks) { return false; }
|
if (!actions || !actions.tweaks) { return false; }
|
||||||
|
|
||||||
// don't show self-highlights from another of our clients
|
// don't show self-highlights from another of our clients
|
||||||
if (this.props.mxEvent.getSender() === this.context.credentials.userId) {
|
if (this.mxEvent.getSender() === this.context.credentials.userId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +667,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
getReadAvatars() {
|
getReadAvatars() {
|
||||||
if (this.shouldShowSentReceipt || this.shouldShowSendingReceipt) {
|
if (this.shouldShowSentReceipt || this.shouldShowSendingReceipt) {
|
||||||
return <SentReceipt messageState={this.props.mxEvent.getAssociatedStatus()} />;
|
return <SentReceipt messageState={this.mxEvent.getAssociatedStatus()} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return early if there are no read receipts
|
// return early if there are no read receipts
|
||||||
|
@ -728,7 +754,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
onSenderProfileClick = event => {
|
onSenderProfileClick = event => {
|
||||||
const mxEvent = this.props.mxEvent;
|
const mxEvent = this.mxEvent;
|
||||||
dis.dispatch<ComposerInsertPayload>({
|
dis.dispatch<ComposerInsertPayload>({
|
||||||
action: Action.ComposerInsert,
|
action: Action.ComposerInsert,
|
||||||
userId: mxEvent.getSender(),
|
userId: mxEvent.getSender(),
|
||||||
|
@ -745,7 +771,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
// Cancel any outgoing key request for this event and resend it. If a response
|
// Cancel any outgoing key request for this event and resend it. If a response
|
||||||
// is received for the request with the required keys, the event could be
|
// is received for the request with the required keys, the event could be
|
||||||
// decrypted successfully.
|
// decrypted successfully.
|
||||||
this.context.cancelAndResendEventRoomKeyRequest(this.props.mxEvent);
|
this.context.cancelAndResendEventRoomKeyRequest(this.mxEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
onPermalinkClicked = e => {
|
onPermalinkClicked = e => {
|
||||||
|
@ -754,14 +780,14 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_room',
|
action: 'view_room',
|
||||||
event_id: this.props.mxEvent.getId(),
|
event_id: this.mxEvent.getId(),
|
||||||
highlighted: true,
|
highlighted: true,
|
||||||
room_id: this.props.mxEvent.getRoomId(),
|
room_id: this.mxEvent.getRoomId(),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private renderE2EPadlock() {
|
private renderE2EPadlock() {
|
||||||
const ev = this.props.mxEvent;
|
const ev = this.mxEvent;
|
||||||
|
|
||||||
// event could not be decrypted
|
// event could not be decrypted
|
||||||
if (ev.getContent().msgtype === 'm.bad.encrypted') {
|
if (ev.getContent().msgtype === 'm.bad.encrypted') {
|
||||||
|
@ -820,7 +846,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const eventId = this.props.mxEvent.getId();
|
const eventId = this.mxEvent.getId();
|
||||||
return this.props.getRelationsForEvent(eventId, "m.annotation", "m.reaction");
|
return this.props.getRelationsForEvent(eventId, "m.annotation", "m.reaction");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -839,13 +865,13 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
const SenderProfile = sdk.getComponent('messages.SenderProfile');
|
const SenderProfile = sdk.getComponent('messages.SenderProfile');
|
||||||
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||||
|
|
||||||
//console.info("EventTile showUrlPreview for %s is %s", this.props.mxEvent.getId(), this.props.showUrlPreview);
|
//console.info("EventTile showUrlPreview for %s is %s", this.mxEvent.getId(), this.props.showUrlPreview);
|
||||||
|
|
||||||
const content = this.props.mxEvent.getContent();
|
const content = this.mxEvent.getContent();
|
||||||
const msgtype = content.msgtype;
|
const msgtype = content.msgtype;
|
||||||
const eventType = this.props.mxEvent.getType();
|
const eventType = this.mxEvent.getType();
|
||||||
|
|
||||||
let tileHandler = getHandlerTile(this.props.mxEvent);
|
let tileHandler = getHandlerTile(this.mxEvent);
|
||||||
|
|
||||||
// Info messages are basically information about commands processed on a room
|
// Info messages are basically information about commands processed on a room
|
||||||
const isBubbleMessage = eventType.startsWith("m.key.verification") ||
|
const isBubbleMessage = eventType.startsWith("m.key.verification") ||
|
||||||
|
@ -862,7 +888,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
// source tile when there's no regular tile for an event and also for
|
// source tile when there's no regular tile for an event and also for
|
||||||
// replace relations (which otherwise would display as a confusing
|
// replace relations (which otherwise would display as a confusing
|
||||||
// duplicate of the thing they are replacing).
|
// duplicate of the thing they are replacing).
|
||||||
if (SettingsStore.getValue("showHiddenEventsInTimeline") && !haveTileForEvent(this.props.mxEvent)) {
|
if (SettingsStore.getValue("showHiddenEventsInTimeline") && !haveTileForEvent(this.mxEvent)) {
|
||||||
tileHandler = "messages.ViewSourceEvent";
|
tileHandler = "messages.ViewSourceEvent";
|
||||||
// Reuse info message avatar and sender profile styling
|
// Reuse info message avatar and sender profile styling
|
||||||
isInfoMessage = true;
|
isInfoMessage = true;
|
||||||
|
@ -881,8 +907,8 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
const EventTileType = sdk.getComponent(tileHandler);
|
const EventTileType = sdk.getComponent(tileHandler);
|
||||||
|
|
||||||
const isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1);
|
const isSending = (['sending', 'queued', 'encrypting'].indexOf(this.props.eventSendStatus) !== -1);
|
||||||
const isRedacted = isMessageEvent(this.props.mxEvent) && this.props.isRedacted;
|
const isRedacted = isMessageEvent(this.mxEvent) && this.props.isRedacted;
|
||||||
const isEncryptionFailure = this.props.mxEvent.isDecryptionFailure();
|
const isEncryptionFailure = this.mxEvent.isDecryptionFailure();
|
||||||
|
|
||||||
const isEditing = !!this.props.editState;
|
const isEditing = !!this.props.editState;
|
||||||
const classes = classNames({
|
const classes = classNames({
|
||||||
|
@ -912,14 +938,14 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
let permalink = "#";
|
let permalink = "#";
|
||||||
if (this.props.permalinkCreator) {
|
if (this.props.permalinkCreator) {
|
||||||
permalink = this.props.permalinkCreator.forEvent(this.props.mxEvent.getId());
|
permalink = this.props.permalinkCreator.forEvent(this.mxEvent.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can't use local echoes as scroll tokens, because their event IDs change.
|
// we can't use local echoes as scroll tokens, because their event IDs change.
|
||||||
// Local echos have a send "status".
|
// Local echos have a send "status".
|
||||||
const scrollToken = this.props.mxEvent.status
|
const scrollToken = this.mxEvent.status
|
||||||
? undefined
|
? undefined
|
||||||
: this.props.mxEvent.getId();
|
: this.mxEvent.getId();
|
||||||
|
|
||||||
let avatar;
|
let avatar;
|
||||||
let sender;
|
let sender;
|
||||||
|
@ -949,15 +975,15 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
needsSenderProfile = true;
|
needsSenderProfile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.mxEvent.sender && avatarSize) {
|
if (this.mxEvent.sender && avatarSize) {
|
||||||
let member;
|
let member;
|
||||||
// set member to receiver (target) if it is a 3PID invite
|
// set member to receiver (target) if it is a 3PID invite
|
||||||
// so that the correct avatar is shown as the text is
|
// so that the correct avatar is shown as the text is
|
||||||
// `$target accepted the invitation for $email`
|
// `$target accepted the invitation for $email`
|
||||||
if (this.props.mxEvent.getContent().third_party_invite) {
|
if (this.mxEvent.getContent().third_party_invite) {
|
||||||
member = this.props.mxEvent.target;
|
member = this.mxEvent.target;
|
||||||
} else {
|
} else {
|
||||||
member = this.props.mxEvent.sender;
|
member = this.mxEvent.sender;
|
||||||
}
|
}
|
||||||
avatar = (
|
avatar = (
|
||||||
<div className="mx_EventTile_avatar">
|
<div className="mx_EventTile_avatar">
|
||||||
|
@ -972,17 +998,17 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
if (needsSenderProfile) {
|
if (needsSenderProfile) {
|
||||||
if (!this.props.tileShape || this.props.tileShape === 'reply' || this.props.tileShape === 'reply_preview') {
|
if (!this.props.tileShape || this.props.tileShape === 'reply' || this.props.tileShape === 'reply_preview') {
|
||||||
sender = <SenderProfile onClick={this.onSenderProfileClick}
|
sender = <SenderProfile onClick={this.onSenderProfileClick}
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.mxEvent}
|
||||||
enableFlair={this.props.enableFlair}
|
enableFlair={this.props.enableFlair}
|
||||||
/>;
|
/>;
|
||||||
} else {
|
} else {
|
||||||
sender = <SenderProfile mxEvent={this.props.mxEvent} enableFlair={this.props.enableFlair} />;
|
sender = <SenderProfile mxEvent={this.mxEvent} enableFlair={this.props.enableFlair} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MessageActionBar = sdk.getComponent('messages.MessageActionBar');
|
const MessageActionBar = sdk.getComponent('messages.MessageActionBar');
|
||||||
const actionBar = !isEditing ? <MessageActionBar
|
const actionBar = !isEditing ? <MessageActionBar
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.mxEvent}
|
||||||
reactions={this.state.reactions}
|
reactions={this.state.reactions}
|
||||||
permalinkCreator={this.props.permalinkCreator}
|
permalinkCreator={this.props.permalinkCreator}
|
||||||
getTile={this.getTile}
|
getTile={this.getTile}
|
||||||
|
@ -990,10 +1016,10 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
onFocusChange={this.onActionBarFocusChange}
|
onFocusChange={this.onActionBarFocusChange}
|
||||||
/> : undefined;
|
/> : undefined;
|
||||||
|
|
||||||
const showTimestamp = this.props.mxEvent.getTs() &&
|
const showTimestamp = this.mxEvent.getTs() &&
|
||||||
(this.props.alwaysShowTimestamps || this.props.last || this.state.hover || this.state.actionBarFocused);
|
(this.props.alwaysShowTimestamps || this.props.last || this.state.hover || this.state.actionBarFocused);
|
||||||
const timestamp = showTimestamp ?
|
const timestamp = showTimestamp ?
|
||||||
<MessageTimestamp showTwelveHour={this.props.isTwelveHour} ts={this.props.mxEvent.getTs()} /> : null;
|
<MessageTimestamp showTwelveHour={this.props.isTwelveHour} ts={this.mxEvent.getTs()} /> : null;
|
||||||
|
|
||||||
const keyRequestHelpText =
|
const keyRequestHelpText =
|
||||||
<div className="mx_EventTile_keyRequestInfo_tooltip_contents">
|
<div className="mx_EventTile_keyRequestInfo_tooltip_contents">
|
||||||
|
@ -1033,7 +1059,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
if (!isRedacted) {
|
if (!isRedacted) {
|
||||||
const ReactionsRow = sdk.getComponent('messages.ReactionsRow');
|
const ReactionsRow = sdk.getComponent('messages.ReactionsRow');
|
||||||
reactionsRow = <ReactionsRow
|
reactionsRow = <ReactionsRow
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.mxEvent}
|
||||||
reactions={this.state.reactions}
|
reactions={this.state.reactions}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
@ -1041,7 +1067,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
const linkedTimestamp = <a
|
const linkedTimestamp = <a
|
||||||
href={permalink}
|
href={permalink}
|
||||||
onClick={this.onPermalinkClicked}
|
onClick={this.onPermalinkClicked}
|
||||||
aria-label={formatTime(new Date(this.props.mxEvent.getTs()), this.props.isTwelveHour)}
|
aria-label={formatTime(new Date(this.mxEvent.getTs()), this.props.isTwelveHour)}
|
||||||
>
|
>
|
||||||
{ timestamp }
|
{ timestamp }
|
||||||
</a>;
|
</a>;
|
||||||
|
@ -1060,7 +1086,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
switch (this.props.tileShape) {
|
switch (this.props.tileShape) {
|
||||||
case 'notif': {
|
case 'notif': {
|
||||||
const room = this.context.getRoom(this.props.mxEvent.getRoomId());
|
const room = this.context.getRoom(this.mxEvent.getRoomId());
|
||||||
return React.createElement(this.props.as || "li", {
|
return React.createElement(this.props.as || "li", {
|
||||||
"className": classes,
|
"className": classes,
|
||||||
"aria-live": ariaLive,
|
"aria-live": ariaLive,
|
||||||
|
@ -1082,7 +1108,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
</div>,
|
</div>,
|
||||||
<div className="mx_EventTile_line" key="mx_EventTile_line">
|
<div className="mx_EventTile_line" key="mx_EventTile_line">
|
||||||
<EventTileType ref={this.tile}
|
<EventTileType ref={this.tile}
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.mxEvent}
|
||||||
highlights={this.props.highlights}
|
highlights={this.props.highlights}
|
||||||
highlightLink={this.props.highlightLink}
|
highlightLink={this.props.highlightLink}
|
||||||
showUrlPreview={this.props.showUrlPreview}
|
showUrlPreview={this.props.showUrlPreview}
|
||||||
|
@ -1100,7 +1126,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
}, [
|
}, [
|
||||||
<div className="mx_EventTile_line" key="mx_EventTile_line">
|
<div className="mx_EventTile_line" key="mx_EventTile_line">
|
||||||
<EventTileType ref={this.tile}
|
<EventTileType ref={this.tile}
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.mxEvent}
|
||||||
highlights={this.props.highlights}
|
highlights={this.props.highlights}
|
||||||
highlightLink={this.props.highlightLink}
|
highlightLink={this.props.highlightLink}
|
||||||
showUrlPreview={this.props.showUrlPreview}
|
showUrlPreview={this.props.showUrlPreview}
|
||||||
|
@ -1127,7 +1153,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
let thread;
|
let thread;
|
||||||
if (this.props.tileShape === 'reply_preview') {
|
if (this.props.tileShape === 'reply_preview') {
|
||||||
thread = ReplyThread.makeThread(
|
thread = ReplyThread.makeThread(
|
||||||
this.props.mxEvent,
|
this.mxEvent,
|
||||||
this.props.onHeightChanged,
|
this.props.onHeightChanged,
|
||||||
this.props.permalinkCreator,
|
this.props.permalinkCreator,
|
||||||
this.replyThread,
|
this.replyThread,
|
||||||
|
@ -1150,7 +1176,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
{ groupPadlock }
|
{ groupPadlock }
|
||||||
{ thread }
|
{ thread }
|
||||||
<EventTileType ref={this.tile}
|
<EventTileType ref={this.tile}
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.mxEvent}
|
||||||
highlights={this.props.highlights}
|
highlights={this.props.highlights}
|
||||||
highlightLink={this.props.highlightLink}
|
highlightLink={this.props.highlightLink}
|
||||||
onHeightChanged={this.props.onHeightChanged}
|
onHeightChanged={this.props.onHeightChanged}
|
||||||
|
@ -1162,7 +1188,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
const thread = ReplyThread.makeThread(
|
const thread = ReplyThread.makeThread(
|
||||||
this.props.mxEvent,
|
this.mxEvent,
|
||||||
this.props.onHeightChanged,
|
this.props.onHeightChanged,
|
||||||
this.props.permalinkCreator,
|
this.props.permalinkCreator,
|
||||||
this.replyThread,
|
this.replyThread,
|
||||||
|
@ -1190,7 +1216,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
||||||
{ groupPadlock }
|
{ groupPadlock }
|
||||||
{ thread }
|
{ thread }
|
||||||
<EventTileType ref={this.tile}
|
<EventTileType ref={this.tile}
|
||||||
mxEvent={this.props.mxEvent}
|
mxEvent={this.mxEvent}
|
||||||
replacingEventId={this.props.replacingEventId}
|
replacingEventId={this.props.replacingEventId}
|
||||||
editState={this.props.editState}
|
editState={this.props.editState}
|
||||||
highlights={this.props.highlights}
|
highlights={this.props.highlights}
|
||||||
|
|
Loading…
Reference in New Issue