Merge remote-tracking branch 'origin/develop' into travis/voice-messages/download
This commit is contained in:
commit
5994111e5d
325 changed files with 5224 additions and 4075 deletions
|
@ -179,9 +179,9 @@ export default class AuxPanel extends React.Component<IProps, IState> {
|
|||
<span
|
||||
className="m_RoomView_auxPanel_stateViews_span"
|
||||
data-severity={severity}
|
||||
key={ "x-" + stateKey }
|
||||
key={"x-" + stateKey}
|
||||
>
|
||||
{span}
|
||||
{ span }
|
||||
</span>
|
||||
);
|
||||
|
||||
|
|
|
@ -129,23 +129,23 @@ export default class EntityTile extends React.PureComponent<IProps, IState> {
|
|||
presenceState={this.props.presenceState} />;
|
||||
}
|
||||
if (this.props.subtextLabel) {
|
||||
presenceLabel = <span className="mx_EntityTile_subtext">{this.props.subtextLabel}</span>;
|
||||
presenceLabel = <span className="mx_EntityTile_subtext">{ this.props.subtextLabel }</span>;
|
||||
}
|
||||
nameEl = (
|
||||
<div className="mx_EntityTile_details">
|
||||
<div className="mx_EntityTile_name" dir="auto">
|
||||
{ name }
|
||||
</div>
|
||||
{presenceLabel}
|
||||
{ presenceLabel }
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.subtextLabel) {
|
||||
nameEl = (
|
||||
<div className="mx_EntityTile_details">
|
||||
<div className="mx_EntityTile_name" dir="auto">
|
||||
{name}
|
||||
{ name }
|
||||
</div>
|
||||
<span className="mx_EntityTile_subtext">{this.props.subtextLabel}</span>
|
||||
<span className="mx_EntityTile_subtext">{ this.props.subtextLabel }</span>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
|
@ -167,7 +167,7 @@ export default class EntityTile extends React.PureComponent<IProps, IState> {
|
|||
const powerStatus = this.props.powerStatus;
|
||||
if (powerStatus) {
|
||||
const powerText = PowerLabel[powerStatus];
|
||||
powerLabel = <div className="mx_EntityTile_power">{powerText}</div>;
|
||||
powerLabel = <div className="mx_EntityTile_power">{ powerText }</div>;
|
||||
}
|
||||
|
||||
let e2eIcon;
|
||||
|
|
|
@ -44,6 +44,7 @@ import EditorStateTransfer from "../../../utils/EditorStateTransfer";
|
|||
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
|
||||
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
|
||||
import NotificationBadge from "./NotificationBadge";
|
||||
import CallEventGrouper from "../../structures/CallEventGrouper";
|
||||
import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload";
|
||||
import { Action } from '../../../dispatcher/actions';
|
||||
import MemberAvatar from '../avatars/MemberAvatar';
|
||||
|
@ -60,10 +61,7 @@ const eventTileTypes = {
|
|||
[EventType.Sticker]: 'messages.MessageEvent',
|
||||
[EventType.KeyVerificationCancel]: 'messages.MKeyVerificationConclusion',
|
||||
[EventType.KeyVerificationDone]: 'messages.MKeyVerificationConclusion',
|
||||
[EventType.CallInvite]: 'messages.TextualEvent',
|
||||
[EventType.CallAnswer]: 'messages.TextualEvent',
|
||||
[EventType.CallHangup]: 'messages.TextualEvent',
|
||||
[EventType.CallReject]: 'messages.TextualEvent',
|
||||
[EventType.CallInvite]: 'messages.CallEvent',
|
||||
};
|
||||
|
||||
const stateEventTileTypes = {
|
||||
|
@ -170,8 +168,6 @@ export function getHandlerTile(ev) {
|
|||
return eventTileTypes[type];
|
||||
}
|
||||
|
||||
const MAX_READ_AVATARS = 5;
|
||||
|
||||
// Our component structure for EventTiles on the timeline is:
|
||||
//
|
||||
// .-EventTile------------------------------------------------.
|
||||
|
@ -292,11 +288,17 @@ interface IProps {
|
|||
// Helper to build permalinks for the room
|
||||
permalinkCreator?: RoomPermalinkCreator;
|
||||
|
||||
// CallEventGrouper for this event
|
||||
callEventGrouper?: CallEventGrouper;
|
||||
|
||||
// Symbol of the root node
|
||||
as?: string;
|
||||
|
||||
// whether or not to always show timestamps
|
||||
alwaysShowTimestamps?: boolean;
|
||||
|
||||
// whether or not to display the sender
|
||||
hideSender?: boolean;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
@ -320,7 +322,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
private suppressReadReceiptAnimation: boolean;
|
||||
private isListeningForReceipts: boolean;
|
||||
private tile = React.createRef();
|
||||
private replyThread = React.createRef();
|
||||
private replyThread = React.createRef<ReplyThread>();
|
||||
|
||||
public readonly ref = createRef<HTMLElement>();
|
||||
|
||||
|
@ -430,7 +432,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
// TODO: [REACT-WARNING] Move into constructor
|
||||
// eslint-disable-next-line camelcase
|
||||
// eslint-disable-next-line
|
||||
UNSAFE_componentWillMount() {
|
||||
this.verifyEvent(this.props.mxEvent);
|
||||
}
|
||||
|
@ -452,7 +454,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
|
||||
// eslint-disable-next-line camelcase
|
||||
// eslint-disable-next-line
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
// re-check the sender verification as outgoing events progress through
|
||||
// the send process.
|
||||
|
@ -656,6 +658,10 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
return <SentReceipt messageState={this.props.mxEvent.getAssociatedStatus()} />;
|
||||
}
|
||||
|
||||
const MAX_READ_AVATARS = this.props.layout == Layout.Bubble
|
||||
? 2
|
||||
: 5;
|
||||
|
||||
// return early if there are no read receipts
|
||||
if (!this.props.readReceipts || this.props.readReceipts.length === 0) {
|
||||
// We currently must include `mx_EventTile_readAvatars` in the DOM
|
||||
|
@ -951,7 +957,7 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
if (needsSenderProfile) {
|
||||
if (needsSenderProfile && this.props.hideSender !== true) {
|
||||
if (!this.props.tileShape) {
|
||||
sender = <SenderProfile onClick={this.onSenderProfileClick}
|
||||
mxEvent={this.props.mxEvent}
|
||||
|
@ -971,8 +977,12 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
onFocusChange={this.onActionBarFocusChange}
|
||||
/> : undefined;
|
||||
|
||||
const showTimestamp = this.props.mxEvent.getTs() &&
|
||||
(this.props.alwaysShowTimestamps || this.props.last || this.state.hover || this.state.actionBarFocused);
|
||||
const showTimestamp = this.props.mxEvent.getTs()
|
||||
&& (this.props.alwaysShowTimestamps
|
||||
|| this.props.last
|
||||
|| this.state.hover
|
||||
|| this.state.actionBarFocused);
|
||||
|
||||
const timestamp = showTimestamp ?
|
||||
<MessageTimestamp showTwelveHour={this.props.isTwelveHour} ts={this.props.mxEvent.getTs()} /> : null;
|
||||
|
||||
|
@ -1112,6 +1122,8 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
this.props.alwaysShowTimestamps || this.state.hover,
|
||||
);
|
||||
|
||||
const isOwnEvent = this.props.mxEvent?.sender?.userId === MatrixClientPeg.get().getUserId();
|
||||
|
||||
// tab-index=-1 to allow it to be focusable but do not add tab stop for it, primarily for screen readers
|
||||
return (
|
||||
React.createElement(this.props.as || "li", {
|
||||
|
@ -1121,6 +1133,9 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
"aria-live": ariaLive,
|
||||
"aria-atomic": "true",
|
||||
"data-scroll-tokens": scrollToken,
|
||||
"data-layout": this.props.layout,
|
||||
"data-self": isOwnEvent,
|
||||
"data-has-reply": !!thread,
|
||||
"onMouseEnter": () => this.setState({ hover: true }),
|
||||
"onMouseLeave": () => this.setState({ hover: false }),
|
||||
}, <>
|
||||
|
@ -1140,11 +1155,12 @@ export default class EventTile extends React.Component<IProps, IState> {
|
|||
showUrlPreview={this.props.showUrlPreview}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
onHeightChanged={this.props.onHeightChanged}
|
||||
callEventGrouper={this.props.callEventGrouper}
|
||||
/>
|
||||
{ keyRequestInfo }
|
||||
{ reactionsRow }
|
||||
{ actionBar }
|
||||
</div>
|
||||
{ reactionsRow }
|
||||
{ msgOption }
|
||||
{ avatar }
|
||||
</>)
|
||||
|
@ -1160,7 +1176,7 @@ function isMessageEvent(ev) {
|
|||
return (messageTypes.includes(ev.getType()));
|
||||
}
|
||||
|
||||
export function haveTileForEvent(e) {
|
||||
export function haveTileForEvent(e: MatrixEvent, showHiddenEvents?: boolean) {
|
||||
// Only messages have a tile (black-rectangle) if redacted
|
||||
if (e.isRedacted() && !isMessageEvent(e)) return false;
|
||||
|
||||
|
@ -1170,7 +1186,7 @@ export function haveTileForEvent(e) {
|
|||
const handler = getHandlerTile(e);
|
||||
if (handler === undefined) return false;
|
||||
if (handler === 'messages.TextualEvent') {
|
||||
return hasText(e);
|
||||
return hasText(e, showHiddenEvents);
|
||||
} else if (handler === 'messages.RoomCreate') {
|
||||
return Boolean(e.getContent()['predecessor']);
|
||||
} else {
|
||||
|
@ -1250,7 +1266,7 @@ class E2ePadlock extends React.Component<IE2ePadlockProps, IE2ePadlockState> {
|
|||
className={classes}
|
||||
onMouseEnter={this.onHoverStart}
|
||||
onMouseLeave={this.onHoverEnd}
|
||||
>{tooltip}</div>
|
||||
>{ tooltip }</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1314,8 +1330,8 @@ class SentReceipt extends React.PureComponent<ISentReceiptProps, ISentReceiptSta
|
|||
<div className="mx_EventTile_msgOption">
|
||||
<span className="mx_EventTile_readAvatars">
|
||||
<span className={receiptClasses} onMouseEnter={this.onHoverStart} onMouseLeave={this.onHoverEnd}>
|
||||
{nonCssBadge}
|
||||
{tooltip}
|
||||
{ nonCssBadge }
|
||||
{ tooltip }
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -84,7 +84,7 @@ export default class ExtraTile extends React.Component<IProps, IState> {
|
|||
let nameContainer = (
|
||||
<div className="mx_RoomTile_nameContainer">
|
||||
<div title={name} className={nameClasses} tabIndex={-1} dir="auto">
|
||||
{name}
|
||||
{ name }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -106,11 +106,11 @@ export default class ExtraTile extends React.Component<IProps, IState> {
|
|||
title={this.props.isMinimized ? name : undefined}
|
||||
>
|
||||
<div className="mx_RoomTile_avatarContainer">
|
||||
{this.props.avatar}
|
||||
{ this.props.avatar }
|
||||
</div>
|
||||
{nameContainer}
|
||||
{ nameContainer }
|
||||
<div className="mx_RoomTile_badgeContainer">
|
||||
{badge}
|
||||
{ badge }
|
||||
</div>
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -25,7 +25,7 @@ export default (props) => {
|
|||
});
|
||||
let badge;
|
||||
if (props.numUnreadMessages) {
|
||||
badge = (<div className="mx_JumpToBottomButton_badge">{props.numUnreadMessages}</div>);
|
||||
badge = (<div className="mx_JumpToBottomButton_badge">{ props.numUnreadMessages }</div>);
|
||||
}
|
||||
return (<div className={className}>
|
||||
<AccessibleButton className="mx_JumpToBottomButton_scrollDown"
|
||||
|
|
|
@ -93,7 +93,7 @@ export default class MemberList extends React.Component<IProps, IState> {
|
|||
this.showPresence = enablePresenceByHsUrl?.[hsUrl] ?? true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
// eslint-disable-next-line
|
||||
UNSAFE_componentWillMount() {
|
||||
const cli = MatrixClientPeg.get();
|
||||
this.mounted = true;
|
||||
|
@ -543,8 +543,8 @@ export default class MemberList extends React.Component<IProps, IState> {
|
|||
const footer = (
|
||||
<SearchBox
|
||||
className="mx_MemberList_query mx_textinput_icon mx_textinput_search"
|
||||
placeholder={ _t('Filter room members') }
|
||||
onSearch={ this.onSearchQueryChanged } />
|
||||
placeholder={_t('Filter room members')}
|
||||
onSearch={this.onSearchQueryChanged} />
|
||||
);
|
||||
|
||||
let previousPhase = RightPanelPhases.RoomSummary;
|
||||
|
|
|
@ -411,7 +411,7 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
className="mx_MessageComposer_roomReplaced_link"
|
||||
onClick={this.onTombstoneClick}
|
||||
>
|
||||
{_t("The conversation continues here.")}
|
||||
{ _t("The conversation continues here.") }
|
||||
</a>
|
||||
) : '';
|
||||
|
||||
|
@ -421,7 +421,7 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
src={require("../../../../res/img/room_replaced.svg")}
|
||||
/>
|
||||
<span className="mx_MessageComposer_roomReplaced_header">
|
||||
{_t("This room has been replaced and is no longer active.")}
|
||||
{ _t("This room has been replaced and is no longer active.") }
|
||||
</span><br />
|
||||
{ continuesLink }
|
||||
</div>
|
||||
|
@ -445,7 +445,7 @@ export default class MessageComposer extends React.Component<IProps, IState> {
|
|||
|
||||
return (
|
||||
<div className="mx_MessageComposer mx_GroupLayout">
|
||||
{recordingTooltip}
|
||||
{ recordingTooltip }
|
||||
<div className="mx_MessageComposer_wrapper">
|
||||
<ReplyPreview permalinkCreator={this.props.permalinkCreator} />
|
||||
<div className="mx_MessageComposer_row">
|
||||
|
|
|
@ -68,9 +68,9 @@ const NewRoomIntro = () => {
|
|||
|
||||
<h2>{ room.name }</h2>
|
||||
|
||||
<p>{_t("This is the beginning of your direct message history with <displayName/>.", {}, {
|
||||
<p>{ _t("This is the beginning of your direct message history with <displayName/>.", {}, {
|
||||
displayName: () => <b>{ displayName }</b>,
|
||||
})}</p>
|
||||
}) }</p>
|
||||
{ caption && <p>{ caption }</p> }
|
||||
</React.Fragment>;
|
||||
} else {
|
||||
|
@ -132,7 +132,7 @@ const NewRoomIntro = () => {
|
|||
showSpaceInvite(parentSpace);
|
||||
}}
|
||||
>
|
||||
{_t("Invite to %(spaceName)s", { spaceName: parentSpace.name })}
|
||||
{ _t("Invite to %(spaceName)s", { spaceName: parentSpace.name }) }
|
||||
</AccessibleButton>
|
||||
{ room.canInvite(cli.getUserId()) && <AccessibleButton
|
||||
className="mx_NewRoomIntro_inviteButton"
|
||||
|
@ -141,7 +141,7 @@ const NewRoomIntro = () => {
|
|||
dis.dispatch({ action: "view_invite", roomId });
|
||||
}}
|
||||
>
|
||||
{_t("Invite to just this room")}
|
||||
{ _t("Invite to just this room") }
|
||||
</AccessibleButton> }
|
||||
</div>;
|
||||
} else if (room.canInvite(cli.getUserId())) {
|
||||
|
@ -153,7 +153,7 @@ const NewRoomIntro = () => {
|
|||
dis.dispatch({ action: "view_invite", roomId });
|
||||
}}
|
||||
>
|
||||
{_t("Invite to this room")}
|
||||
{ _t("Invite to this room") }
|
||||
</AccessibleButton>
|
||||
</div>;
|
||||
}
|
||||
|
@ -170,10 +170,10 @@ const NewRoomIntro = () => {
|
|||
|
||||
<h2>{ room.name }</h2>
|
||||
|
||||
<p>{createdText} {_t("This is the start of <roomName/>.", {}, {
|
||||
<p>{ createdText } { _t("This is the start of <roomName/>.", {}, {
|
||||
roomName: () => <b>{ room.name }</b>,
|
||||
})}</p>
|
||||
<p>{topicText}</p>
|
||||
}) }</p>
|
||||
<p>{ topicText }</p>
|
||||
{ buttons }
|
||||
</React.Fragment>;
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ const NewRoomIntro = () => {
|
|||
"Your private messages are normally encrypted, but this room isn't. "+
|
||||
"Usually this is due to an unsupported device or method being used, " +
|
||||
"like email invites. <a>Enable encryption in settings.</a>", {},
|
||||
{ a: sub => <a onClick={openRoomSettings} href="#">{sub}</a> },
|
||||
{ a: sub => <a onClick={openRoomSettings} href="#">{ sub }</a> },
|
||||
);
|
||||
|
||||
return <div className="mx_NewRoomIntro">
|
||||
|
@ -201,7 +201,7 @@ const NewRoomIntro = () => {
|
|||
title={_t("End-to-end encryption isn't enabled")}
|
||||
subtitle={sub2}
|
||||
/>
|
||||
)}
|
||||
) }
|
||||
|
||||
{ body }
|
||||
</div>;
|
||||
|
|
|
@ -126,14 +126,14 @@ export default class NotificationBadge extends React.PureComponent<XOR<IProps, I
|
|||
if (onClick) {
|
||||
return (
|
||||
<AccessibleButton {...props} className={classes} onClick={onClick}>
|
||||
<span className="mx_NotificationBadge_count">{symbol}</span>
|
||||
<span className="mx_NotificationBadge_count">{ symbol }</span>
|
||||
</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
<span className="mx_NotificationBadge_count">{symbol}</span>
|
||||
<span className="mx_NotificationBadge_count">{ symbol }</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,10 +18,11 @@ import React from 'react';
|
|||
import dis from '../../../dispatcher/dispatcher';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import RoomViewStore from '../../../stores/RoomViewStore';
|
||||
import PropTypes from "prop-types";
|
||||
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import ReplyTile from './ReplyTile';
|
||||
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||
import { EventSubscription } from 'fbemitter';
|
||||
|
||||
function cancelQuoting() {
|
||||
dis.dispatch({
|
||||
|
@ -30,41 +31,46 @@ function cancelQuoting() {
|
|||
});
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
permalinkCreator: RoomPermalinkCreator;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
event: MatrixEvent;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.rooms.ReplyPreview")
|
||||
export default class ReplyPreview extends React.Component {
|
||||
static propTypes = {
|
||||
permalinkCreator: PropTypes.instanceOf(RoomPermalinkCreator).isRequired,
|
||||
};
|
||||
export default class ReplyPreview extends React.Component<IProps, IState> {
|
||||
private unmounted = false;
|
||||
private readonly roomStoreToken: EventSubscription;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.unmounted = false;
|
||||
|
||||
this.state = {
|
||||
event: RoomViewStore.getQuotingEvent(),
|
||||
};
|
||||
|
||||
this._onRoomViewStoreUpdate = this._onRoomViewStoreUpdate.bind(this);
|
||||
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
|
||||
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unmounted = true;
|
||||
|
||||
// Remove RoomStore listener
|
||||
if (this._roomStoreToken) {
|
||||
this._roomStoreToken.remove();
|
||||
if (this.roomStoreToken) {
|
||||
this.roomStoreToken.remove();
|
||||
}
|
||||
}
|
||||
|
||||
_onRoomViewStoreUpdate() {
|
||||
private onRoomViewStoreUpdate = (): void => {
|
||||
if (this.unmounted) return;
|
||||
|
||||
const event = RoomViewStore.getQuotingEvent();
|
||||
if (this.state.event !== event) {
|
||||
this.setState({ event });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.state.event) return null;
|
|
@ -109,7 +109,7 @@ export default class RoomBreadcrumbs extends React.PureComponent<IProps, IState>
|
|||
classNames='mx_RoomBreadcrumbs'
|
||||
>
|
||||
<Toolbar className='mx_RoomBreadcrumbs' aria-label={_t("Recently visited rooms")}>
|
||||
{tiles.slice(this.state.skipFirst ? 1 : 0)}
|
||||
{ tiles.slice(this.state.skipFirst ? 1 : 0) }
|
||||
</Toolbar>
|
||||
</CSSTransition>
|
||||
);
|
||||
|
@ -117,7 +117,7 @@ export default class RoomBreadcrumbs extends React.PureComponent<IProps, IState>
|
|||
return (
|
||||
<div className='mx_RoomBreadcrumbs'>
|
||||
<div className="mx_RoomBreadcrumbs_placeholder">
|
||||
{_t("No recently visited rooms")}
|
||||
{ _t("No recently visited rooms") }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -121,18 +121,18 @@ export default class RoomHeader extends React.Component<IProps> {
|
|||
const name =
|
||||
<div className="mx_RoomHeader_name" onClick={this.props.onSettingsClick}>
|
||||
<RoomName room={this.props.room}>
|
||||
{(name) => {
|
||||
{ (name) => {
|
||||
const roomName = name || oobName;
|
||||
return <div dir="auto" className={textClasses} title={roomName}>{ roomName }</div>;
|
||||
}}
|
||||
} }
|
||||
</RoomName>
|
||||
{ searchStatus }
|
||||
</div>;
|
||||
|
||||
const topicElement = <RoomTopic room={this.props.room}>
|
||||
{(topic, ref) => <div className="mx_RoomHeader_topic" ref={ref} title={topic} dir="auto">
|
||||
{ (topic, ref) => <div className="mx_RoomHeader_topic" ref={ref} title={topic} dir="auto">
|
||||
{ topic }
|
||||
</div>}
|
||||
</div> }
|
||||
</RoomTopic>;
|
||||
|
||||
let roomAvatar;
|
||||
|
|
|
@ -507,13 +507,13 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
if (!this.props.isMinimized) {
|
||||
if (this.state.isNameFiltering) {
|
||||
explorePrompt = <div className="mx_RoomList_explorePrompt">
|
||||
<div>{_t("Can't see what you’re looking for?")}</div>
|
||||
<div>{ _t("Can't see what you’re looking for?") }</div>
|
||||
<AccessibleButton
|
||||
className="mx_RoomList_explorePrompt_startChat"
|
||||
kind="link"
|
||||
onClick={this.onStartChat}
|
||||
>
|
||||
{_t("Start a new chat")}
|
||||
{ _t("Start a new chat") }
|
||||
</AccessibleButton>
|
||||
<AccessibleButton
|
||||
className="mx_RoomList_explorePrompt_explore"
|
||||
|
@ -532,13 +532,13 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
className="mx_RoomList_explorePrompt_spaceInvite"
|
||||
onClick={this.onSpaceInviteClick}
|
||||
>
|
||||
{_t("Invite people")}
|
||||
{ _t("Invite people") }
|
||||
</AccessibleButton> }
|
||||
{ this.props.activeSpace.getMyMembership() === "join" && <AccessibleButton
|
||||
className="mx_RoomList_explorePrompt_spaceExplore"
|
||||
onClick={this.onExplore}
|
||||
>
|
||||
{_t("Explore rooms")}
|
||||
{ _t("Explore rooms") }
|
||||
</AccessibleButton> }
|
||||
</div>;
|
||||
} else if (Object.values(this.state.sublists).some(list => list.length > 0)) {
|
||||
|
@ -549,20 +549,20 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
// show a prompt to join/create rooms if the user is in 0 rooms and no historical
|
||||
if (unfilteredRooms.length < 1 && unfilteredHistorical < 1 && unfilteredFavourite < 1) {
|
||||
explorePrompt = <div className="mx_RoomList_explorePrompt">
|
||||
<div>{_t("Use the + to make a new room or explore existing ones below")}</div>
|
||||
<div>{ _t("Use the + to make a new room or explore existing ones below") }</div>
|
||||
<AccessibleButton
|
||||
className="mx_RoomList_explorePrompt_startChat"
|
||||
kind="link"
|
||||
onClick={this.onStartChat}
|
||||
>
|
||||
{_t("Start a new chat")}
|
||||
{ _t("Start a new chat") }
|
||||
</AccessibleButton>
|
||||
<AccessibleButton
|
||||
className="mx_RoomList_explorePrompt_explore"
|
||||
kind="link"
|
||||
onClick={this.onExplore}
|
||||
>
|
||||
{_t("Explore all public rooms")}
|
||||
{ _t("Explore all public rooms") }
|
||||
</AccessibleButton>
|
||||
</div>;
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
const sublists = this.renderSublists();
|
||||
return (
|
||||
<RovingTabIndexProvider handleHomeEnd={true} onKeyDown={this.props.onKeyDown}>
|
||||
{({ onKeyDownHandler }) => (
|
||||
{ ({ onKeyDownHandler }) => (
|
||||
<div
|
||||
onFocus={this.props.onFocus}
|
||||
onBlur={this.props.onBlur}
|
||||
|
@ -581,10 +581,10 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
|||
role="tree"
|
||||
aria-label={_t("Rooms")}
|
||||
>
|
||||
{sublists}
|
||||
{explorePrompt}
|
||||
{ sublists }
|
||||
{ explorePrompt }
|
||||
</div>
|
||||
)}
|
||||
) }
|
||||
</RovingTabIndexProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -340,7 +340,7 @@ export default class RoomPreviewBar extends React.Component {
|
|||
footer = (
|
||||
<div>
|
||||
<Spinner w={20} h={20} />
|
||||
{_t("Loading room preview")}
|
||||
{ _t("Loading room preview") }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -465,11 +465,11 @@ export default class RoomPreviewBar extends React.Component {
|
|||
if (inviteMember) {
|
||||
inviterElement = <span>
|
||||
<span className="mx_RoomPreviewBar_inviter">
|
||||
{inviteMember.rawDisplayName}
|
||||
</span> ({inviteMember.userId})
|
||||
{ inviteMember.rawDisplayName }
|
||||
</span> ({ inviteMember.userId })
|
||||
</span>;
|
||||
} else {
|
||||
inviterElement = (<span className="mx_RoomPreviewBar_inviter">{this.props.inviterName}</span>);
|
||||
inviterElement = (<span className="mx_RoomPreviewBar_inviter">{ this.props.inviterName }</span>);
|
||||
}
|
||||
|
||||
const isDM = this._isDMInvite();
|
||||
|
@ -549,7 +549,7 @@ export default class RoomPreviewBar extends React.Component {
|
|||
if (!Array.isArray(subTitle)) {
|
||||
subTitle = [subTitle];
|
||||
}
|
||||
subTitleElements = subTitle.map((t, i) => <p key={`subTitle${i}`}>{t}</p>);
|
||||
subTitleElements = subTitle.map((t, i) => <p key={`subTitle${i}`}>{ t }</p>);
|
||||
}
|
||||
|
||||
let titleElement;
|
||||
|
|
|
@ -574,20 +574,20 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
<React.Fragment>
|
||||
<hr />
|
||||
<div>
|
||||
<div className='mx_RoomSublist_contextMenu_title'>{_t("Appearance")}</div>
|
||||
<div className='mx_RoomSublist_contextMenu_title'>{ _t("Appearance") }</div>
|
||||
<StyledMenuItemCheckbox
|
||||
onClose={this.onCloseMenu}
|
||||
onChange={this.onUnreadFirstChanged}
|
||||
checked={isUnreadFirst}
|
||||
>
|
||||
{_t("Show rooms with unread messages first")}
|
||||
{ _t("Show rooms with unread messages first") }
|
||||
</StyledMenuItemCheckbox>
|
||||
<StyledMenuItemCheckbox
|
||||
onClose={this.onCloseMenu}
|
||||
onChange={this.onMessagePreviewChanged}
|
||||
checked={this.layout.showPreviews}
|
||||
>
|
||||
{_t("Show previews of messages")}
|
||||
{ _t("Show previews of messages") }
|
||||
</StyledMenuItemCheckbox>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
@ -603,14 +603,14 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
>
|
||||
<div className="mx_RoomSublist_contextMenu">
|
||||
<div>
|
||||
<div className='mx_RoomSublist_contextMenu_title'>{_t("Sort by")}</div>
|
||||
<div className='mx_RoomSublist_contextMenu_title'>{ _t("Sort by") }</div>
|
||||
<StyledMenuItemRadio
|
||||
onClose={this.onCloseMenu}
|
||||
onChange={() => this.onTagSortChanged(SortAlgorithm.Recent)}
|
||||
checked={!isAlphabetical}
|
||||
name={`mx_${this.props.tagId}_sortBy`}
|
||||
>
|
||||
{_t("Activity")}
|
||||
{ _t("Activity") }
|
||||
</StyledMenuItemRadio>
|
||||
<StyledMenuItemRadio
|
||||
onClose={this.onCloseMenu}
|
||||
|
@ -618,10 +618,10 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
checked={isAlphabetical}
|
||||
name={`mx_${this.props.tagId}_sortBy`}
|
||||
>
|
||||
{_t("A-Z")}
|
||||
{ _t("A-Z") }
|
||||
</StyledMenuItemRadio>
|
||||
</div>
|
||||
{otherSections}
|
||||
{ otherSections }
|
||||
</div>
|
||||
</ContextMenu>
|
||||
);
|
||||
|
@ -634,7 +634,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
onFinished={this.onCloseAddRoomMenu}
|
||||
compact
|
||||
>
|
||||
{this.props.addRoomContextMenu(this.onCloseAddRoomMenu)}
|
||||
{ this.props.addRoomContextMenu(this.onCloseAddRoomMenu) }
|
||||
</IconizedContextMenu>
|
||||
);
|
||||
}
|
||||
|
@ -647,7 +647,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
title={_t("List options")}
|
||||
isExpanded={!!this.state.contextMenuPosition}
|
||||
/>
|
||||
{contextMenu}
|
||||
{ contextMenu }
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -655,7 +655,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
private renderHeader(): React.ReactElement {
|
||||
return (
|
||||
<RovingTabIndexWrapper inputRef={this.headerButton}>
|
||||
{({ onFocus, isActive, ref }) => {
|
||||
{ ({ onFocus, isActive, ref }) => {
|
||||
const tabIndex = isActive ? 0 : -1;
|
||||
|
||||
let ariaLabel = _t("Jump to first unread room.");
|
||||
|
@ -711,7 +711,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
|
||||
const badgeContainer = (
|
||||
<div className="mx_RoomSublist_badgeContainer">
|
||||
{badge}
|
||||
{ badge }
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -746,17 +746,17 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
title={this.props.isMinimized ? this.props.label : undefined}
|
||||
>
|
||||
<span className={collapseClasses} />
|
||||
<span>{this.props.label}</span>
|
||||
<span>{ this.props.label }</span>
|
||||
</Button>
|
||||
{this.renderMenu()}
|
||||
{this.props.isMinimized ? null : badgeContainer}
|
||||
{this.props.isMinimized ? null : addRoomButton}
|
||||
{ this.renderMenu() }
|
||||
{ this.props.isMinimized ? null : badgeContainer }
|
||||
{ this.props.isMinimized ? null : addRoomButton }
|
||||
</div>
|
||||
{this.props.isMinimized ? badgeContainer : null}
|
||||
{this.props.isMinimized ? addRoomButton : null}
|
||||
{ this.props.isMinimized ? badgeContainer : null }
|
||||
{ this.props.isMinimized ? addRoomButton : null }
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
} }
|
||||
</RovingTabIndexWrapper>
|
||||
);
|
||||
}
|
||||
|
@ -804,7 +804,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
const label = _t("Show %(count)s more", { count: numMissing });
|
||||
let showMoreText = (
|
||||
<span className='mx_RoomSublist_showNButtonText'>
|
||||
{label}
|
||||
{ label }
|
||||
</span>
|
||||
);
|
||||
if (this.props.isMinimized) showMoreText = null;
|
||||
|
@ -816,9 +816,9 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
aria-label={label}
|
||||
>
|
||||
<span className='mx_RoomSublist_showMoreButtonChevron mx_RoomSublist_showNButtonChevron'>
|
||||
{/* set by CSS masking */}
|
||||
{ /* set by CSS masking */ }
|
||||
</span>
|
||||
{showMoreText}
|
||||
{ showMoreText }
|
||||
</RovingAccessibleButton>
|
||||
);
|
||||
} else if (this.numTiles > this.layout.defaultVisibleTiles) {
|
||||
|
@ -826,7 +826,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
const label = _t("Show less");
|
||||
let showLessText = (
|
||||
<span className='mx_RoomSublist_showNButtonText'>
|
||||
{label}
|
||||
{ label }
|
||||
</span>
|
||||
);
|
||||
if (this.props.isMinimized) showLessText = null;
|
||||
|
@ -838,9 +838,9 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
aria-label={label}
|
||||
>
|
||||
<span className='mx_RoomSublist_showLessButtonChevron mx_RoomSublist_showNButtonChevron'>
|
||||
{/* set by CSS masking */}
|
||||
{ /* set by CSS masking */ }
|
||||
</span>
|
||||
{showLessText}
|
||||
{ showLessText }
|
||||
</RovingAccessibleButton>
|
||||
);
|
||||
}
|
||||
|
@ -891,9 +891,9 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
enable={handles}
|
||||
>
|
||||
<div className="mx_RoomSublist_tiles" ref={this.tilesRef}>
|
||||
{visibleTiles}
|
||||
{ visibleTiles }
|
||||
</div>
|
||||
{showNButton}
|
||||
{ showNButton }
|
||||
</Resizable>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
@ -909,8 +909,8 @@ export default class RoomSublist extends React.Component<IProps, IState> {
|
|||
aria-label={this.props.label}
|
||||
onKeyDown={this.onKeyDown}
|
||||
>
|
||||
{this.renderHeader()}
|
||||
{content}
|
||||
{ this.renderHeader() }
|
||||
{ content }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -419,7 +419,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
>
|
||||
<IconizedContextMenuOptionList first>
|
||||
<IconizedContextMenuRadio
|
||||
label={_t("Use default")}
|
||||
label={_t("Global")}
|
||||
active={state === ALL_MESSAGES}
|
||||
iconClassName="mx_RoomTile_iconBell"
|
||||
onClick={this.onClickAllNotifs}
|
||||
|
@ -467,7 +467,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
isExpanded={!!this.state.notificationsMenuPosition}
|
||||
tabIndex={isActive ? 0 : -1}
|
||||
/>
|
||||
{contextMenu}
|
||||
{ contextMenu }
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -521,16 +521,16 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
label={lowPriorityLabel}
|
||||
iconClassName="mx_RoomTile_iconArrowDown"
|
||||
/>
|
||||
{canInvite ? (
|
||||
{ canInvite ? (
|
||||
<IconizedContextMenuOption
|
||||
onClick={this.onInviteClick}
|
||||
label={_t("Invite People")}
|
||||
iconClassName="mx_RoomTile_iconInvite"
|
||||
/>
|
||||
) : null}
|
||||
) : null }
|
||||
<IconizedContextMenuOption
|
||||
onClick={this.onCopyRoomClick}
|
||||
label={_t("Copy Link")}
|
||||
label={_t("Copy Room Link")}
|
||||
iconClassName="mx_RoomTile_iconCopyLink"
|
||||
/>
|
||||
<IconizedContextMenuOption
|
||||
|
@ -557,7 +557,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
title={_t("Room options")}
|
||||
isExpanded={!!this.state.generalMenuPosition}
|
||||
/>
|
||||
{contextMenu}
|
||||
{ contextMenu }
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -621,7 +621,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
id={messagePreviewId(this.props.room.roomId)}
|
||||
title={this.state.messagePreview}
|
||||
>
|
||||
{this.state.messagePreview}
|
||||
{ this.state.messagePreview }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -635,9 +635,9 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
let nameContainer = (
|
||||
<div className="mx_RoomTile_nameContainer">
|
||||
<div title={name} className={nameClasses} tabIndex={-1} dir="auto">
|
||||
{name}
|
||||
{ name }
|
||||
</div>
|
||||
{messagePreview}
|
||||
{ messagePreview }
|
||||
</div>
|
||||
);
|
||||
if (this.props.isMinimized) nameContainer = null;
|
||||
|
@ -675,7 +675,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
return (
|
||||
<React.Fragment>
|
||||
<RovingTabIndexWrapper inputRef={this.roomTileRef}>
|
||||
{({ onFocus, isActive, ref }) =>
|
||||
{ ({ onFocus, isActive, ref }) =>
|
||||
<Button
|
||||
{...props}
|
||||
onFocus={onFocus}
|
||||
|
@ -689,11 +689,11 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
|
|||
aria-selected={this.state.selected}
|
||||
aria-describedby={ariaDescribedBy}
|
||||
>
|
||||
{roomAvatar}
|
||||
{nameContainer}
|
||||
{badge}
|
||||
{this.renderGeneralMenu()}
|
||||
{this.renderNotificationsMenu(isActive)}
|
||||
{ roomAvatar }
|
||||
{ nameContainer }
|
||||
{ badge }
|
||||
{ this.renderGeneralMenu() }
|
||||
{ this.renderNotificationsMenu(isActive) }
|
||||
</Button>
|
||||
}
|
||||
</RovingTabIndexWrapper>
|
||||
|
|
|
@ -72,26 +72,26 @@ export default class RoomUpgradeWarningBar extends React.PureComponent {
|
|||
<div>
|
||||
<div className="mx_RoomUpgradeWarningBar_body">
|
||||
<p>
|
||||
{_t(
|
||||
{ _t(
|
||||
"Upgrading this room will shut down the current instance of the room and create " +
|
||||
"an upgraded room with the same name.",
|
||||
)}
|
||||
) }
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
{ _t(
|
||||
"<b>Warning</b>: Upgrading a room will <i>not automatically migrate room members " +
|
||||
"to the new version of the room.</i> We'll post a link to the new room in the old " +
|
||||
"version of the room - room members will have to click this link to join the new room.",
|
||||
{}, {
|
||||
"b": (sub) => <b>{sub}</b>,
|
||||
"i": (sub) => <i>{sub}</i>,
|
||||
"b": (sub) => <b>{ sub }</b>,
|
||||
"i": (sub) => <i>{ sub }</i>,
|
||||
},
|
||||
)}
|
||||
) }
|
||||
</p>
|
||||
</div>
|
||||
<p className="mx_RoomUpgradeWarningBar_upgradelink">
|
||||
<AccessibleButton onClick={this.onUpgradeClick}>
|
||||
{_t("Upgrade this room to the recommended room version")}
|
||||
{ _t("Upgrade this room to the recommended room version") }
|
||||
</AccessibleButton>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -101,7 +101,7 @@ export default class RoomUpgradeWarningBar extends React.PureComponent {
|
|||
doUpgradeWarnings = (
|
||||
<div className="mx_RoomUpgradeWarningBar_body">
|
||||
<p>
|
||||
{_t("This room has already been upgraded.")}
|
||||
{ _t("This room has already been upgraded.") }
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
@ -111,19 +111,19 @@ export default class RoomUpgradeWarningBar extends React.PureComponent {
|
|||
<div className="mx_RoomUpgradeWarningBar">
|
||||
<div className="mx_RoomUpgradeWarningBar_wrapped">
|
||||
<div className="mx_RoomUpgradeWarningBar_header">
|
||||
{_t(
|
||||
{ _t(
|
||||
"This room is running room version <roomVersion />, which this homeserver has " +
|
||||
"marked as <i>unstable</i>.",
|
||||
{},
|
||||
{
|
||||
"roomVersion": () => <code>{this.props.room.getVersion()}</code>,
|
||||
"i": (sub) => <i>{sub}</i>,
|
||||
"roomVersion": () => <code>{ this.props.room.getVersion() }</code>,
|
||||
"i": (sub) => <i>{ sub }</i>,
|
||||
},
|
||||
)}
|
||||
) }
|
||||
</div>
|
||||
{doUpgradeWarnings}
|
||||
{ doUpgradeWarnings }
|
||||
<div className="mx_RoomUpgradeWarningBar_small">
|
||||
{_t("Only room administrators will see this warning")}
|
||||
{ _t("Only room administrators will see this warning") }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -100,7 +100,7 @@ export default class SearchBar extends React.Component<IProps, IState> {
|
|||
aria-checked={this.state.scope === SearchScope.Room}
|
||||
role="radio"
|
||||
>
|
||||
{_t("This Room")}
|
||||
{ _t("This Room") }
|
||||
</AccessibleButton>
|
||||
<AccessibleButton
|
||||
className={allRoomsClasses}
|
||||
|
@ -108,7 +108,7 @@ export default class SearchBar extends React.Component<IProps, IState> {
|
|||
aria-checked={this.state.scope === SearchScope.All}
|
||||
role="radio"
|
||||
>
|
||||
{_t("All Rooms")}
|
||||
{ _t("All Rooms") }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
<div className="mx_SearchBar_input mx_textinput">
|
||||
|
@ -119,7 +119,7 @@ export default class SearchBar extends React.Component<IProps, IState> {
|
|||
placeholder={_t("Search…")}
|
||||
onKeyDown={this.onSearchChange}
|
||||
/>
|
||||
<AccessibleButton className={ searchButtonClasses } onClick={this.onSearch} />
|
||||
<AccessibleButton className={searchButtonClasses} onClick={this.onSearch} />
|
||||
</div>
|
||||
<AccessibleButton className="mx_SearchBar_cancel" onClick={this.props.onCancelClick} />
|
||||
</div>
|
||||
|
|
|
@ -15,14 +15,15 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
import { SearchResult } from "matrix-js-sdk/src/models/search-result";
|
||||
import EventTile, { haveTileForEvent } from "./EventTile";
|
||||
import DateSeparator from '../messages/DateSeparator';
|
||||
import RoomContext from "../../../contexts/RoomContext";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { UIFeature } from "../../../settings/UIFeature";
|
||||
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
import DateSeparator from "../messages/DateSeparator";
|
||||
import EventTile, { haveTileForEvent } from "./EventTile";
|
||||
|
||||
interface IProps {
|
||||
// a matrix-js-sdk SearchResult containing the details of this result
|
||||
|
@ -37,6 +38,8 @@ interface IProps {
|
|||
|
||||
@replaceableComponent("views.rooms.SearchResultTile")
|
||||
export default class SearchResultTile extends React.Component<IProps> {
|
||||
static contextType = RoomContext;
|
||||
|
||||
public render() {
|
||||
const result = this.props.searchResult;
|
||||
const mxEv = result.context.getEvent();
|
||||
|
@ -44,7 +47,10 @@ export default class SearchResultTile extends React.Component<IProps> {
|
|||
|
||||
const ts1 = mxEv.getTs();
|
||||
const ret = [<DateSeparator key={ts1 + "-search"} ts={ts1} />];
|
||||
const layout = SettingsStore.getValue("layout");
|
||||
const isTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps");
|
||||
const alwaysShowTimestamps = SettingsStore.getValue("alwaysShowTimestamps");
|
||||
const enableFlair = SettingsStore.getValue(UIFeature.Flair);
|
||||
|
||||
const timeline = result.context.getTimeline();
|
||||
for (let j = 0; j < timeline.length; j++) {
|
||||
|
@ -54,26 +60,25 @@ export default class SearchResultTile extends React.Component<IProps> {
|
|||
if (!contextual) {
|
||||
highlights = this.props.searchHighlights;
|
||||
}
|
||||
if (haveTileForEvent(ev)) {
|
||||
ret.push((
|
||||
if (haveTileForEvent(ev, this.context?.showHiddenEventsInTimeline)) {
|
||||
ret.push(
|
||||
<EventTile
|
||||
key={`${eventId}+${j}`}
|
||||
mxEvent={ev}
|
||||
layout={layout}
|
||||
contextual={contextual}
|
||||
highlights={highlights}
|
||||
permalinkCreator={this.props.permalinkCreator}
|
||||
highlightLink={this.props.resultLink}
|
||||
onHeightChanged={this.props.onHeightChanged}
|
||||
isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")}
|
||||
isTwelveHour={isTwelveHour}
|
||||
alwaysShowTimestamps={alwaysShowTimestamps}
|
||||
enableFlair={SettingsStore.getValue(UIFeature.Flair)}
|
||||
/>
|
||||
));
|
||||
enableFlair={enableFlair}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<li data-scroll-tokens={eventId}>
|
||||
{ ret }
|
||||
</li>);
|
||||
|
||||
return <li data-scroll-tokens={eventId}>{ ret }</li>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -441,7 +441,7 @@ export default class SendMessageComposer extends React.Component<IProps> {
|
|||
}
|
||||
|
||||
// TODO: [REACT-WARNING] Move this to constructor
|
||||
UNSAFE_componentWillMount() { // eslint-disable-line camelcase
|
||||
UNSAFE_componentWillMount() { // eslint-disable-line
|
||||
const partCreator = new CommandPartCreator(this.props.room, this.context);
|
||||
const parts = this.restoreStoredEditorState(partCreator) || [];
|
||||
this.model = new EditorModel(parts, partCreator);
|
||||
|
|
|
@ -123,10 +123,10 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
|
|||
if (this.state.canKick && this.state.invited) {
|
||||
adminTools = (
|
||||
<div className="mx_MemberInfo_container">
|
||||
<h3>{_t("Admin Tools")}</h3>
|
||||
<h3>{ _t("Admin Tools") }</h3>
|
||||
<div className="mx_MemberInfo_buttons">
|
||||
<AccessibleButton className="mx_MemberInfo_field" onClick={this.onKickClick}>
|
||||
{_t("Revoke invite")}
|
||||
{ _t("Revoke invite") }
|
||||
</AccessibleButton>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -150,16 +150,16 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
|
|||
onClick={this.onCancel}
|
||||
title={_t('Close')}
|
||||
/>
|
||||
<h2>{this.state.displayName}</h2>
|
||||
<h2>{ this.state.displayName }</h2>
|
||||
</div>
|
||||
<div className="mx_MemberInfo_container">
|
||||
<div className="mx_MemberInfo_profile">
|
||||
<div className="mx_MemberInfo_profileField">
|
||||
{_t("Invited by %(sender)s", { sender: this.state.senderName })}
|
||||
{ _t("Invited by %(sender)s", { sender: this.state.senderName }) }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{adminTools}
|
||||
{ adminTools }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -124,9 +124,9 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
|
|||
Modal.createTrackedDialog('Microphone Access Error', '', ErrorDialog, {
|
||||
title: _t("Unable to access your microphone"),
|
||||
description: <>
|
||||
<p>{_t(
|
||||
<p>{ _t(
|
||||
"We were unable to access your microphone. Please check your browser settings and try again.",
|
||||
)}</p>
|
||||
) }</p>
|
||||
</>,
|
||||
});
|
||||
};
|
||||
|
@ -139,9 +139,9 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
|
|||
Modal.createTrackedDialog('No Microphone Error', '', ErrorDialog, {
|
||||
title: _t("No microphone found"),
|
||||
description: <>
|
||||
<p>{_t(
|
||||
<p>{ _t(
|
||||
"We didn't find a microphone on your device. Please check your settings and try again.",
|
||||
)}</p>
|
||||
) }</p>
|
||||
</>,
|
||||
});
|
||||
return;
|
||||
|
@ -224,9 +224,9 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
|
|||
}
|
||||
|
||||
return (<>
|
||||
{deleteButton}
|
||||
{this.renderWaveformArea()}
|
||||
{recordingInfo}
|
||||
{ deleteButton }
|
||||
{ this.renderWaveformArea() }
|
||||
{ recordingInfo }
|
||||
</>);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,8 +64,8 @@ export default class WhoIsTypingTile extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
componentDidUpdate(_, prevState) {
|
||||
const wasVisible = this._isVisible(prevState);
|
||||
const isVisible = this._isVisible(this.state);
|
||||
const wasVisible = WhoIsTypingTile.isVisible(prevState);
|
||||
const isVisible = WhoIsTypingTile.isVisible(this.state);
|
||||
if (this.props.onShown && !wasVisible && isVisible) {
|
||||
this.props.onShown();
|
||||
} else if (this.props.onHidden && wasVisible && !isVisible) {
|
||||
|
@ -83,12 +83,12 @@ export default class WhoIsTypingTile extends React.Component<IProps, IState> {
|
|||
Object.values(this.state.delayedStopTypingTimers).forEach((t) => (t as Timer).abort());
|
||||
}
|
||||
|
||||
private _isVisible(state: IState): boolean {
|
||||
private static isVisible(state: IState): boolean {
|
||||
return state.usersTyping.length !== 0 || Object.keys(state.delayedStopTypingTimers).length !== 0;
|
||||
}
|
||||
|
||||
public isVisible = (): boolean => {
|
||||
return this._isVisible(this.state);
|
||||
return WhoIsTypingTile.isVisible(this.state);
|
||||
};
|
||||
|
||||
private onRoomTimeline = (event: MatrixEvent, room: Room): void => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue