Conform more of the code base to strict null checking (#10147)
* Conform more of the code base to strict null checking * More strict fixes * More strict work * Fix missing optional type * Iterate
This commit is contained in:
parent
fa036a5080
commit
da7aa4055e
380 changed files with 682 additions and 694 deletions
|
@ -74,7 +74,7 @@ export default class AsyncWrapper extends React.Component<IProps, IState> {
|
||||||
this.props.onFinished(false);
|
this.props.onFinished(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (this.state.component) {
|
if (this.state.component) {
|
||||||
const Component = this.state.component;
|
const Component = this.state.component;
|
||||||
return <Component {...this.props} />;
|
return <Component {...this.props} />;
|
||||||
|
|
|
@ -138,7 +138,7 @@ export function getInitialLetter(name: string): string | undefined {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function avatarUrlForRoom(
|
export function avatarUrlForRoom(
|
||||||
room: Room,
|
room: Room | null,
|
||||||
width: number,
|
width: number,
|
||||||
height: number,
|
height: number,
|
||||||
resizeMethod?: ResizeMethod,
|
resizeMethod?: ResizeMethod,
|
||||||
|
|
|
@ -204,7 +204,7 @@ const transformTags: IExtendedSanitizeOptions["transformTags"] = {
|
||||||
attribs.style += "height: 100%;";
|
attribs.style += "height: 100%;";
|
||||||
}
|
}
|
||||||
|
|
||||||
attribs.src = mediaFromMxc(src).getThumbnailOfSourceHttp(width, height);
|
attribs.src = mediaFromMxc(src).getThumbnailOfSourceHttp(width, height)!;
|
||||||
return { tagName, attribs };
|
return { tagName, attribs };
|
||||||
},
|
},
|
||||||
"code": function (tagName: string, attribs: sanitizeHtml.Attributes) {
|
"code": function (tagName: string, attribs: sanitizeHtml.Attributes) {
|
||||||
|
@ -352,7 +352,7 @@ const topicSanitizeHtmlParams: IExtendedSanitizeOptions = {
|
||||||
};
|
};
|
||||||
|
|
||||||
abstract class BaseHighlighter<T extends React.ReactNode> {
|
abstract class BaseHighlighter<T extends React.ReactNode> {
|
||||||
public constructor(public highlightClass: string, public highlightLink: string) {}
|
public constructor(public highlightClass: string, public highlightLink?: string) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* apply the highlights to a section of text
|
* apply the highlights to a section of text
|
||||||
|
@ -504,7 +504,7 @@ function formatEmojis(message: string, isHtmlMessage: boolean): (JSX.Element | s
|
||||||
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOptsReturnString): string;
|
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOptsReturnString): string;
|
||||||
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOptsReturnNode): ReactNode;
|
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOptsReturnNode): ReactNode;
|
||||||
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOpts = {}): ReactNode | string {
|
export function bodyToHtml(content: IContent, highlights: Optional<string[]>, opts: IOpts = {}): ReactNode | string {
|
||||||
const isFormattedBody = content.format === "org.matrix.custom.html" && !!content.formatted_body;
|
const isFormattedBody = content.format === "org.matrix.custom.html" && typeof content.formatted_body === "string";
|
||||||
let bodyHasEmoji = false;
|
let bodyHasEmoji = false;
|
||||||
let isHtmlMessage = false;
|
let isHtmlMessage = false;
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
|
||||||
}
|
}
|
||||||
|
|
||||||
let strippedBody: string;
|
let strippedBody: string;
|
||||||
let safeBody: string; // safe, sanitised HTML, preferred over `strippedBody` which is fully plaintext
|
let safeBody: string | undefined; // safe, sanitised HTML, preferred over `strippedBody` which is fully plaintext
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// sanitizeHtml can hang if an unclosed HTML tag is thrown at it
|
// sanitizeHtml can hang if an unclosed HTML tag is thrown at it
|
||||||
|
@ -529,7 +529,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
|
||||||
|
|
||||||
if (opts.stripReplyFallback && formattedBody) formattedBody = stripHTMLReply(formattedBody);
|
if (opts.stripReplyFallback && formattedBody) formattedBody = stripHTMLReply(formattedBody);
|
||||||
strippedBody = opts.stripReplyFallback ? stripPlainReply(plainBody) : plainBody;
|
strippedBody = opts.stripReplyFallback ? stripPlainReply(plainBody) : plainBody;
|
||||||
bodyHasEmoji = mightContainEmoji(isFormattedBody ? formattedBody : plainBody);
|
bodyHasEmoji = mightContainEmoji(isFormattedBody ? formattedBody! : plainBody);
|
||||||
|
|
||||||
const highlighter = safeHighlights?.length
|
const highlighter = safeHighlights?.length
|
||||||
? new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink)
|
? new HtmlHighlighter("mx_EventTile_searchHighlight", opts.highlightLink)
|
||||||
|
@ -543,11 +543,11 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
|
||||||
// by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either
|
// by an attempt to search for 'foobar'. Then again, the search query probably wouldn't work either
|
||||||
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeParams structure.
|
// XXX: hacky bodge to temporarily apply a textFilter to the sanitizeParams structure.
|
||||||
sanitizeParams.textFilter = function (safeText) {
|
sanitizeParams.textFilter = function (safeText) {
|
||||||
return highlighter.applyHighlights(safeText, safeHighlights).join("");
|
return highlighter.applyHighlights(safeText, safeHighlights!).join("");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
safeBody = sanitizeHtml(formattedBody, sanitizeParams);
|
safeBody = sanitizeHtml(formattedBody!, sanitizeParams);
|
||||||
const phtml = cheerio.load(safeBody, {
|
const phtml = cheerio.load(safeBody, {
|
||||||
// @ts-ignore: The `_useHtmlParser2` internal option is the
|
// @ts-ignore: The `_useHtmlParser2` internal option is the
|
||||||
// simplest way to both parse and render using `htmlparser2`.
|
// simplest way to both parse and render using `htmlparser2`.
|
||||||
|
@ -574,7 +574,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
|
||||||
safeBody = formatEmojis(safeBody, true).join("");
|
safeBody = formatEmojis(safeBody, true).join("");
|
||||||
}
|
}
|
||||||
} else if (highlighter) {
|
} else if (highlighter) {
|
||||||
safeBody = highlighter.applyHighlights(plainBody, safeHighlights).join("");
|
safeBody = highlighter.applyHighlights(plainBody, safeHighlights!).join("");
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
delete sanitizeParams.textFilter;
|
delete sanitizeParams.textFilter;
|
||||||
|
@ -597,9 +597,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
|
||||||
|
|
||||||
const match = BIGEMOJI_REGEX.exec(contentBodyTrimmed);
|
const match = BIGEMOJI_REGEX.exec(contentBodyTrimmed);
|
||||||
emojiBody =
|
emojiBody =
|
||||||
match &&
|
match?.[0]?.length === contentBodyTrimmed.length &&
|
||||||
match[0] &&
|
|
||||||
match[0].length === contentBodyTrimmed.length &&
|
|
||||||
// Prevent user pills expanding for users with only emoji in
|
// Prevent user pills expanding for users with only emoji in
|
||||||
// their username. Permalinks (links in pills) can be any URL
|
// their username. Permalinks (links in pills) can be any URL
|
||||||
// now, so we just check for an HTTP-looking thing.
|
// now, so we just check for an HTTP-looking thing.
|
||||||
|
@ -614,7 +612,7 @@ export function bodyToHtml(content: IContent, highlights: Optional<string[]>, op
|
||||||
"markdown-body": isHtmlMessage && !emojiBody,
|
"markdown-body": isHtmlMessage && !emojiBody,
|
||||||
});
|
});
|
||||||
|
|
||||||
let emojiBodyElements: JSX.Element[];
|
let emojiBodyElements: JSX.Element[] | undefined;
|
||||||
if (!safeBody && bodyHasEmoji) {
|
if (!safeBody && bodyHasEmoji) {
|
||||||
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
|
emojiBodyElements = formatEmojis(strippedBody, false) as JSX.Element[];
|
||||||
}
|
}
|
||||||
|
@ -649,7 +647,7 @@ export function topicToHtml(
|
||||||
allowExtendedHtml = false,
|
allowExtendedHtml = false,
|
||||||
): ReactNode {
|
): ReactNode {
|
||||||
if (!SettingsStore.getValue("feature_html_topic")) {
|
if (!SettingsStore.getValue("feature_html_topic")) {
|
||||||
htmlTopic = null;
|
htmlTopic = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let isFormattedTopic = !!htmlTopic;
|
let isFormattedTopic = !!htmlTopic;
|
||||||
|
@ -657,10 +655,10 @@ export function topicToHtml(
|
||||||
let safeTopic = "";
|
let safeTopic = "";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
topicHasEmoji = mightContainEmoji(isFormattedTopic ? htmlTopic : topic);
|
topicHasEmoji = mightContainEmoji(isFormattedTopic ? htmlTopic! : topic);
|
||||||
|
|
||||||
if (isFormattedTopic) {
|
if (isFormattedTopic) {
|
||||||
safeTopic = sanitizeHtml(htmlTopic, allowExtendedHtml ? sanitizeHtmlParams : topicSanitizeHtmlParams);
|
safeTopic = sanitizeHtml(htmlTopic!, allowExtendedHtml ? sanitizeHtmlParams : topicSanitizeHtmlParams);
|
||||||
if (topicHasEmoji) {
|
if (topicHasEmoji) {
|
||||||
safeTopic = formatEmojis(safeTopic, true).join("");
|
safeTopic = formatEmojis(safeTopic, true).join("");
|
||||||
}
|
}
|
||||||
|
@ -669,7 +667,7 @@ export function topicToHtml(
|
||||||
isFormattedTopic = false; // Fall back to plain-text topic
|
isFormattedTopic = false; // Fall back to plain-text topic
|
||||||
}
|
}
|
||||||
|
|
||||||
let emojiBodyElements: ReturnType<typeof formatEmojis>;
|
let emojiBodyElements: ReturnType<typeof formatEmojis> | undefined;
|
||||||
if (!isFormattedTopic && topicHasEmoji) {
|
if (!isFormattedTopic && topicHasEmoji) {
|
||||||
emojiBodyElements = formatEmojis(topic, false);
|
emojiBodyElements = formatEmojis(topic, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ export default class Markdown {
|
||||||
*/
|
*/
|
||||||
private repairLinks(parsed: commonmark.Node): commonmark.Node {
|
private repairLinks(parsed: commonmark.Node): commonmark.Node {
|
||||||
const walker = parsed.walker();
|
const walker = parsed.walker();
|
||||||
let event: commonmark.NodeWalkingStep = null;
|
let event: commonmark.NodeWalkingStep | null = null;
|
||||||
let text = "";
|
let text = "";
|
||||||
let isInPara = false;
|
let isInPara = false;
|
||||||
let previousNode: commonmark.Node | null = null;
|
let previousNode: commonmark.Node | null = null;
|
||||||
|
@ -287,7 +287,7 @@ export default class Markdown {
|
||||||
// However, if it's a blockquote, adds a p tag anyway
|
// However, if it's a blockquote, adds a p tag anyway
|
||||||
// in order to avoid deviation to commonmark and unexpected
|
// in order to avoid deviation to commonmark and unexpected
|
||||||
// results when parsing the formatted HTML.
|
// results when parsing the formatted HTML.
|
||||||
if (node.parent.type === "block_quote" || isMultiLine(node)) {
|
if (node.parent?.type === "block_quote" || isMultiLine(node)) {
|
||||||
realParagraph.call(this, node, entering);
|
realParagraph.call(this, node, entering);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -120,7 +120,7 @@ export default class NodeAnimator extends React.Component<IProps> {
|
||||||
this.nodes[k] = node;
|
this.nodes[k] = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return <>{Object.values(this.children)}</>;
|
return <>{Object.values(this.children)}</>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ export class PosthogScreenTracker extends PureComponent<{ screenName: ScreenName
|
||||||
PosthogTrackers.instance.clearOverride(this.props.screenName);
|
PosthogTrackers.instance.clearOverride(this.props.screenName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return null; // no need to render anything, we just need to hook into the React lifecycle
|
return null; // no need to render anything, we just need to hook into the React lifecycle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,9 @@ enum State {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Presence {
|
class Presence {
|
||||||
private unavailableTimer: Timer = null;
|
private unavailableTimer: Timer | null = null;
|
||||||
private dispatcherRef: string = null;
|
private dispatcherRef: string | null = null;
|
||||||
private state: State = null;
|
private state: State | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start listening the user activity to evaluate his presence state.
|
* Start listening the user activity to evaluate his presence state.
|
||||||
|
@ -73,14 +73,14 @@ class Presence {
|
||||||
* Get the current presence state.
|
* Get the current presence state.
|
||||||
* @returns {string} the presence state (see PRESENCE enum)
|
* @returns {string} the presence state (see PRESENCE enum)
|
||||||
*/
|
*/
|
||||||
public getState(): State {
|
public getState(): State | null {
|
||||||
return this.state;
|
return this.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload): void => {
|
private onAction = (payload: ActionPayload): void => {
|
||||||
if (payload.action === "user_activity") {
|
if (payload.action === "user_activity") {
|
||||||
this.setState(State.Online);
|
this.setState(State.Online);
|
||||||
this.unavailableTimer.restart();
|
this.unavailableTimer?.restart();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ export default class Resend {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static resend(event: MatrixEvent): Promise<void> {
|
public static resend(event: MatrixEvent): Promise<void> {
|
||||||
const room = MatrixClientPeg.get().getRoom(event.getRoomId());
|
const room = MatrixClientPeg.get().getRoom(event.getRoomId())!;
|
||||||
return MatrixClientPeg.get()
|
return MatrixClientPeg.get()
|
||||||
.resendEvent(event, room)
|
.resendEvent(event, room)
|
||||||
.then(
|
.then(
|
||||||
|
|
|
@ -30,6 +30,6 @@ export function storeRoomAliasInCache(alias: string, id: string): void {
|
||||||
aliasToIDMap.set(alias, id);
|
aliasToIDMap.set(alias, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCachedRoomIDForAlias(alias: string): string {
|
export function getCachedRoomIDForAlias(alias: string): string | undefined {
|
||||||
return aliasToIDMap.get(alias);
|
return aliasToIDMap.get(alias);
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ export function inviteUsersToRoom(
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
return inviteMultipleToRoom(roomId, userIds, sendSharedHistoryKeys, progressCallback)
|
return inviteMultipleToRoom(roomId, userIds, sendSharedHistoryKeys, progressCallback)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
const room = MatrixClientPeg.get().getRoom(roomId);
|
const room = MatrixClientPeg.get().getRoom(roomId)!;
|
||||||
showAnyInviteErrors(result.states, room, result.inviter);
|
showAnyInviteErrors(result.states, room, result.inviter);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -175,14 +175,14 @@ export function showAnyInviteErrors(
|
||||||
<BaseAvatar
|
<BaseAvatar
|
||||||
url={avatarUrl ? mediaFromMxc(avatarUrl).getSquareThumbnailHttp(24) : null}
|
url={avatarUrl ? mediaFromMxc(avatarUrl).getSquareThumbnailHttp(24) : null}
|
||||||
name={name}
|
name={name}
|
||||||
idName={user.userId}
|
idName={user?.userId}
|
||||||
width={36}
|
width={36}
|
||||||
height={36}
|
height={36}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_InviteDialog_tile_nameStack">
|
<div className="mx_InviteDialog_tile_nameStack">
|
||||||
<span className="mx_InviteDialog_tile_nameStack_name">{name}</span>
|
<span className="mx_InviteDialog_tile_nameStack_name">{name}</span>
|
||||||
<span className="mx_InviteDialog_tile_nameStack_userId">{user.userId}</span>
|
<span className="mx_InviteDialog_tile_nameStack_userId">{user?.userId}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_InviteDialog_tile--inviterError_errorText">
|
<div className="mx_InviteDialog_tile--inviterError_errorText">
|
||||||
{inviter.getErrorText(addr)}
|
{inviter.getErrorText(addr)}
|
||||||
|
|
|
@ -46,7 +46,7 @@ export function getRoomNotifsState(client: MatrixClient, roomId: string): RoomNo
|
||||||
}
|
}
|
||||||
|
|
||||||
// for everything else, look at the room rule.
|
// for everything else, look at the room rule.
|
||||||
let roomRule = null;
|
let roomRule: IPushRule | undefined;
|
||||||
try {
|
try {
|
||||||
roomRule = client.getRoomPushRule("global", roomId);
|
roomRule = client.getRoomPushRule("global", roomId);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -106,7 +106,7 @@ export function getUnreadNotificationCount(room: Room, type: NotificationCountTy
|
||||||
|
|
||||||
function setRoomNotifsStateMuted(roomId: string): Promise<any> {
|
function setRoomNotifsStateMuted(roomId: string): Promise<any> {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const promises = [];
|
const promises: Promise<unknown>[] = [];
|
||||||
|
|
||||||
// delete the room rule
|
// delete the room rule
|
||||||
const roomRule = cli.getRoomPushRule("global", roomId);
|
const roomRule = cli.getRoomPushRule("global", roomId);
|
||||||
|
@ -137,7 +137,7 @@ function setRoomNotifsStateMuted(roomId: string): Promise<any> {
|
||||||
|
|
||||||
function setRoomNotifsStateUnmuted(roomId: string, newState: RoomNotifState): Promise<any> {
|
function setRoomNotifsStateUnmuted(roomId: string, newState: RoomNotifState): Promise<any> {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const promises = [];
|
const promises: Promise<unknown>[] = [];
|
||||||
|
|
||||||
const overrideMuteRule = findOverrideMuteRule(roomId);
|
const overrideMuteRule = findOverrideMuteRule(roomId);
|
||||||
if (overrideMuteRule) {
|
if (overrideMuteRule) {
|
||||||
|
|
10
src/Rooms.ts
10
src/Rooms.ts
|
@ -29,13 +29,13 @@ import AliasCustomisations from "./customisations/Alias";
|
||||||
* @param {Object} room The room object
|
* @param {Object} room The room object
|
||||||
* @returns {string} A display alias for the given room
|
* @returns {string} A display alias for the given room
|
||||||
*/
|
*/
|
||||||
export function getDisplayAliasForRoom(room: Room): string | undefined {
|
export function getDisplayAliasForRoom(room: Room): string | null {
|
||||||
return getDisplayAliasForAliasSet(room.getCanonicalAlias(), room.getAltAliases());
|
return getDisplayAliasForAliasSet(room.getCanonicalAlias(), room.getAltAliases());
|
||||||
}
|
}
|
||||||
|
|
||||||
// The various display alias getters should all feed through this one path so
|
// The various display alias getters should all feed through this one path so
|
||||||
// there's a single place to change the logic.
|
// there's a single place to change the logic.
|
||||||
export function getDisplayAliasForAliasSet(canonicalAlias: string, altAliases: string[]): string {
|
export function getDisplayAliasForAliasSet(canonicalAlias: string | null, altAliases: string[]): string | null {
|
||||||
if (AliasCustomisations.getDisplayAliasForAliasSet) {
|
if (AliasCustomisations.getDisplayAliasForAliasSet) {
|
||||||
return AliasCustomisations.getDisplayAliasForAliasSet(canonicalAlias, altAliases);
|
return AliasCustomisations.getDisplayAliasForAliasSet(canonicalAlias, altAliases);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ export function getDisplayAliasForAliasSet(canonicalAlias: string, altAliases: s
|
||||||
export function guessAndSetDMRoom(room: Room, isDirect: boolean): Promise<void> {
|
export function guessAndSetDMRoom(room: Room, isDirect: boolean): Promise<void> {
|
||||||
let newTarget;
|
let newTarget;
|
||||||
if (isDirect) {
|
if (isDirect) {
|
||||||
const guessedUserId = guessDMRoomTargetId(room, MatrixClientPeg.get().getUserId());
|
const guessedUserId = guessDMRoomTargetId(room, MatrixClientPeg.get().getUserId()!);
|
||||||
newTarget = guessedUserId;
|
newTarget = guessedUserId;
|
||||||
} else {
|
} else {
|
||||||
newTarget = null;
|
newTarget = null;
|
||||||
|
@ -118,7 +118,7 @@ function guessDMRoomTargetId(room: Room, myUserId: string): string {
|
||||||
|
|
||||||
if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) {
|
if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) {
|
||||||
oldestUser = user;
|
oldestUser = user;
|
||||||
oldestTs = user.events.member.getTs();
|
oldestTs = user.events.member?.getTs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oldestUser) return oldestUser.userId;
|
if (oldestUser) return oldestUser.userId;
|
||||||
|
@ -129,7 +129,7 @@ function guessDMRoomTargetId(room: Room, myUserId: string): string {
|
||||||
|
|
||||||
if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) {
|
if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) {
|
||||||
oldestUser = user;
|
oldestUser = user;
|
||||||
oldestTs = user.events.member.getTs();
|
oldestTs = user.events.member?.getTs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,9 +72,9 @@ export default class VoipUserMapper {
|
||||||
* Gets the ID of the virtual room for a room, or null if the room has no
|
* Gets the ID of the virtual room for a room, or null if the room has no
|
||||||
* virtual room
|
* virtual room
|
||||||
*/
|
*/
|
||||||
public async getVirtualRoomForRoom(roomId: string): Promise<Room | null> {
|
public async getVirtualRoomForRoom(roomId: string): Promise<Room | undefined> {
|
||||||
const virtualUser = await this.getVirtualUserForRoom(roomId);
|
const virtualUser = await this.getVirtualUserForRoom(roomId);
|
||||||
if (!virtualUser) return null;
|
if (!virtualUser) return undefined;
|
||||||
|
|
||||||
return findDMForUser(MatrixClientPeg.get(), virtualUser);
|
return findDMForUser(MatrixClientPeg.get(), virtualUser);
|
||||||
}
|
}
|
||||||
|
@ -145,11 +145,11 @@ export default class VoipUserMapper {
|
||||||
// (possibly we should only join if we've also joined the native room, then we'd also have
|
// (possibly we should only join if we've also joined the native room, then we'd also have
|
||||||
// to make sure we joined virtual rooms on joining a native one)
|
// to make sure we joined virtual rooms on joining a native one)
|
||||||
MatrixClientPeg.get().joinRoom(invitedRoom.roomId);
|
MatrixClientPeg.get().joinRoom(invitedRoom.roomId);
|
||||||
}
|
|
||||||
|
|
||||||
// also put this room in the virtual room ID cache so isVirtualRoom return the right answer
|
// also put this room in the virtual room ID cache so isVirtualRoom return the right answer
|
||||||
// in however long it takes for the echo of setAccountData to come down the sync
|
// in however long it takes for the echo of setAccountData to come down the sync
|
||||||
this.virtualToNativeRoomIdCache.set(invitedRoom.roomId, nativeRoom.roomId);
|
this.virtualToNativeRoomIdCache.set(invitedRoom.roomId, nativeRoom.roomId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ export default class ManageEventIndexDialog extends React.Component<IProps, ISta
|
||||||
SettingsStore.setValue("crawlerSleepTime", null, SettingLevel.DEVICE, e.target.value);
|
SettingsStore.setValue("crawlerSleepTime", null, SettingLevel.DEVICE, e.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const brand = SdkConfig.get().brand;
|
const brand = SdkConfig.get().brand;
|
||||||
|
|
||||||
let crawlerState;
|
let crawlerState;
|
||||||
|
|
|
@ -459,7 +459,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent<IProps, I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let content;
|
let content;
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
content = (
|
content = (
|
||||||
|
|
|
@ -842,7 +842,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let content;
|
let content;
|
||||||
if (this.state.error) {
|
if (this.state.error) {
|
||||||
content = (
|
content = (
|
||||||
|
|
|
@ -127,7 +127,7 @@ export default class ExportE2eKeysDialog extends React.Component<IProps, IState>
|
||||||
} as Pick<IState, AnyPassphrase>);
|
} as Pick<IState, AnyPassphrase>);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const disableForm = this.state.phase === Phase.Exporting;
|
const disableForm = this.state.phase === Phase.Exporting;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -127,7 +127,7 @@ export default class ImportE2eKeysDialog extends React.Component<IProps, IState>
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const disableForm = this.state.phase !== Phase.Edit;
|
const disableForm = this.state.phase !== Phase.Edit;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -48,13 +48,13 @@ export default class NewRecoveryMethodDialog extends React.PureComponent<IProps>
|
||||||
{
|
{
|
||||||
onFinished: this.props.onFinished,
|
onFinished: this.props.onFinished,
|
||||||
},
|
},
|
||||||
null,
|
undefined,
|
||||||
/* priority = */ false,
|
/* priority = */ false,
|
||||||
/* static = */ true,
|
/* static = */ true,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const title = <span className="mx_KeyBackupFailedDialog_title">{_t("New Recovery Method")}</span>;
|
const title = <span className="mx_KeyBackupFailedDialog_title">{_t("New Recovery Method")}</span>;
|
||||||
|
|
||||||
const newMethodDetected = <p>{_t("A new Security Phrase and key for Secure Messages have been detected.")}</p>;
|
const newMethodDetected = <p>{_t("A new Security Phrase and key for Secure Messages have been detected.")}</p>;
|
||||||
|
|
|
@ -37,14 +37,14 @@ export default class RecoveryMethodRemovedDialog extends React.PureComponent<IPr
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
Modal.createDialogAsync(
|
Modal.createDialogAsync(
|
||||||
import("./CreateKeyBackupDialog") as unknown as Promise<ComponentType<{}>>,
|
import("./CreateKeyBackupDialog") as unknown as Promise<ComponentType<{}>>,
|
||||||
null,
|
undefined,
|
||||||
null,
|
null,
|
||||||
/* priority = */ false,
|
/* priority = */ false,
|
||||||
/* static = */ true,
|
/* static = */ true,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const title = <span className="mx_KeyBackupFailedDialog_title">{_t("Recovery Method Removed")}</span>;
|
const title = <span className="mx_KeyBackupFailedDialog_title">{_t("Recovery Method Removed")}</span>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -91,7 +91,7 @@ export class PlaybackQueue {
|
||||||
|
|
||||||
public unsortedEnqueue(mxEvent: MatrixEvent, playback: Playback): void {
|
public unsortedEnqueue(mxEvent: MatrixEvent, playback: Playback): void {
|
||||||
// We don't ever detach our listeners: we expect the Playback to clean up for us
|
// We don't ever detach our listeners: we expect the Playback to clean up for us
|
||||||
this.playbacks.set(mxEvent.getId(), playback);
|
this.playbacks.set(mxEvent.getId()!, playback);
|
||||||
playback.on(UPDATE_EVENT, (state) => this.onPlaybackStateChange(playback, mxEvent, state));
|
playback.on(UPDATE_EVENT, (state) => this.onPlaybackStateChange(playback, mxEvent, state));
|
||||||
playback.clockInfo.liveData.onUpdate((clock) => this.onPlaybackClock(playback, mxEvent, clock));
|
playback.clockInfo.liveData.onUpdate((clock) => this.onPlaybackClock(playback, mxEvent, clock));
|
||||||
}
|
}
|
||||||
|
@ -99,12 +99,12 @@ export class PlaybackQueue {
|
||||||
private onPlaybackStateChange(playback: Playback, mxEvent: MatrixEvent, newState: PlaybackState): void {
|
private onPlaybackStateChange(playback: Playback, mxEvent: MatrixEvent, newState: PlaybackState): void {
|
||||||
// Remember where the user got to in playback
|
// Remember where the user got to in playback
|
||||||
const wasLastPlaying = this.currentPlaybackId === mxEvent.getId();
|
const wasLastPlaying = this.currentPlaybackId === mxEvent.getId();
|
||||||
if (newState === PlaybackState.Stopped && this.clockStates.has(mxEvent.getId()) && !wasLastPlaying) {
|
if (newState === PlaybackState.Stopped && this.clockStates.has(mxEvent.getId()!) && !wasLastPlaying) {
|
||||||
// noinspection JSIgnoredPromiseFromCall
|
// noinspection JSIgnoredPromiseFromCall
|
||||||
playback.skipTo(this.clockStates.get(mxEvent.getId())!);
|
playback.skipTo(this.clockStates.get(mxEvent.getId()!)!);
|
||||||
} else if (newState === PlaybackState.Stopped) {
|
} else if (newState === PlaybackState.Stopped) {
|
||||||
// Remove the now-useless clock for some space savings
|
// Remove the now-useless clock for some space savings
|
||||||
this.clockStates.delete(mxEvent.getId());
|
this.clockStates.delete(mxEvent.getId()!);
|
||||||
|
|
||||||
if (wasLastPlaying) {
|
if (wasLastPlaying) {
|
||||||
this.recentFullPlays.add(this.currentPlaybackId);
|
this.recentFullPlays.add(this.currentPlaybackId);
|
||||||
|
@ -133,7 +133,7 @@ export class PlaybackQueue {
|
||||||
// timeline is already most recent last, so we can iterate down that.
|
// timeline is already most recent last, so we can iterate down that.
|
||||||
const timeline = arrayFastClone(this.room.getLiveTimeline().getEvents());
|
const timeline = arrayFastClone(this.room.getLiveTimeline().getEvents());
|
||||||
let scanForVoiceMessage = false;
|
let scanForVoiceMessage = false;
|
||||||
let nextEv: MatrixEvent;
|
let nextEv: MatrixEvent | undefined;
|
||||||
for (const event of timeline) {
|
for (const event of timeline) {
|
||||||
if (event.getId() === mxEvent.getId()) {
|
if (event.getId() === mxEvent.getId()) {
|
||||||
scanForVoiceMessage = true;
|
scanForVoiceMessage = true;
|
||||||
|
@ -149,8 +149,8 @@ export class PlaybackQueue {
|
||||||
break; // Stop automatic playback: next useful event is not a voice message
|
break; // Stop automatic playback: next useful event is not a voice message
|
||||||
}
|
}
|
||||||
|
|
||||||
const havePlayback = this.playbacks.has(event.getId());
|
const havePlayback = this.playbacks.has(event.getId()!);
|
||||||
const isRecentlyCompleted = this.recentFullPlays.has(event.getId());
|
const isRecentlyCompleted = this.recentFullPlays.has(event.getId()!);
|
||||||
if (havePlayback && !isRecentlyCompleted) {
|
if (havePlayback && !isRecentlyCompleted) {
|
||||||
nextEv = event;
|
nextEv = event;
|
||||||
break;
|
break;
|
||||||
|
@ -164,7 +164,7 @@ export class PlaybackQueue {
|
||||||
} else {
|
} else {
|
||||||
this.playbackIdOrder = orderClone;
|
this.playbackIdOrder = orderClone;
|
||||||
|
|
||||||
const instance = this.playbacks.get(nextEv.getId());
|
const instance = this.playbacks.get(nextEv.getId()!);
|
||||||
PlaybackManager.instance.pauseAllExcept(instance);
|
PlaybackManager.instance.pauseAllExcept(instance);
|
||||||
|
|
||||||
// This should cause a Play event, which will re-populate our playback order
|
// This should cause a Play event, which will re-populate our playback order
|
||||||
|
@ -196,7 +196,7 @@ export class PlaybackQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentPlaybackId = mxEvent.getId();
|
this.currentPlaybackId = mxEvent.getId()!;
|
||||||
if (order.length === 0 || order[order.length - 1] !== this.currentPlaybackId) {
|
if (order.length === 0 || order[order.length - 1] !== this.currentPlaybackId) {
|
||||||
order.push(this.currentPlaybackId);
|
order.push(this.currentPlaybackId);
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ export class PlaybackQueue {
|
||||||
if (playback.currentState === PlaybackState.Decoding) return; // ignore pre-ready values
|
if (playback.currentState === PlaybackState.Decoding) return; // ignore pre-ready values
|
||||||
|
|
||||||
if (playback.currentState !== PlaybackState.Stopped) {
|
if (playback.currentState !== PlaybackState.Stopped) {
|
||||||
this.clockStates.set(mxEvent.getId(), clocks[0]); // [0] is the current seek position
|
this.clockStates.set(mxEvent.getId()!, clocks[0]); // [0] is the current seek position
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
||||||
private targetMaxLength: number | null = TARGET_MAX_LENGTH;
|
private targetMaxLength: number | null = TARGET_MAX_LENGTH;
|
||||||
public amplitudes: number[] = []; // at each second mark, generated
|
public amplitudes: number[] = []; // at each second mark, generated
|
||||||
private liveWaveform = new FixedRollingArray(RECORDING_PLAYBACK_SAMPLES, 0);
|
private liveWaveform = new FixedRollingArray(RECORDING_PLAYBACK_SAMPLES, 0);
|
||||||
public onDataAvailable: (data: ArrayBuffer) => void;
|
public onDataAvailable?: (data: ArrayBuffer) => void;
|
||||||
|
|
||||||
public get contentType(): string {
|
public get contentType(): string {
|
||||||
return "audio/ogg";
|
return "audio/ogg";
|
||||||
|
@ -181,7 +181,7 @@ export class VoiceRecording extends EventEmitter implements IDestroyable {
|
||||||
});
|
});
|
||||||
|
|
||||||
// not using EventEmitter here because it leads to detached bufferes
|
// not using EventEmitter here because it leads to detached bufferes
|
||||||
this.recorder.ondataavailable = (data: ArrayBuffer) => this?.onDataAvailable(data);
|
this.recorder.ondataavailable = (data: ArrayBuffer) => this.onDataAvailable?.(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error("Error starting recording: ", e);
|
logger.error("Error starting recording: ", e);
|
||||||
if (e instanceof DOMException) {
|
if (e instanceof DOMException) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ export default abstract class AutocompleteProvider {
|
||||||
* @param {boolean} force True if the user is forcing completion
|
* @param {boolean} force True if the user is forcing completion
|
||||||
* @return {object} { command, range } where both objects fields are null if no match
|
* @return {object} { command, range } where both objects fields are null if no match
|
||||||
*/
|
*/
|
||||||
public getCurrentCommand(query: string, selection: ISelectionRange, force = false): ICommand | null {
|
public getCurrentCommand(query: string, selection: ISelectionRange, force = false): Partial<ICommand> {
|
||||||
let commandRegex = this.commandRegex;
|
let commandRegex = this.commandRegex;
|
||||||
|
|
||||||
if (force && this.shouldForceComplete()) {
|
if (force && this.shouldForceComplete()) {
|
||||||
|
@ -78,7 +78,7 @@ export default abstract class AutocompleteProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!commandRegex) {
|
if (!commandRegex) {
|
||||||
return null;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
commandRegex.lastIndex = 0;
|
commandRegex.lastIndex = 0;
|
||||||
|
|
|
@ -95,7 +95,7 @@ export default class CommandProvider extends AutocompleteProvider {
|
||||||
description={_t(result.description)}
|
description={_t(result.description)}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
range,
|
range: range!,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ export default class EmojiProvider extends AutocompleteProvider {
|
||||||
shouldMatchWordsOnly: true,
|
shouldMatchWordsOnly: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.recentlyUsed = Array.from(new Set(recent.get().map(getEmojiFromUnicode).filter(Boolean)));
|
this.recentlyUsed = Array.from(new Set(recent.get().map(getEmojiFromUnicode).filter(Boolean))) as IEmoji[];
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getCompletions(
|
public async getCompletions(
|
||||||
|
@ -152,7 +152,7 @@ export default class EmojiProvider extends AutocompleteProvider {
|
||||||
<span>{c.emoji.unicode}</span>
|
<span>{c.emoji.unicode}</span>
|
||||||
</PillCompletion>
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range: range!,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
|
|
|
@ -40,12 +40,13 @@ export default class NotifProvider extends AutocompleteProvider {
|
||||||
): Promise<ICompletion[]> {
|
): Promise<ICompletion[]> {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
|
|
||||||
if (!this.room.currentState.mayTriggerNotifOfType("room", client.credentials.userId)) return [];
|
if (!this.room.currentState.mayTriggerNotifOfType("room", client.credentials.userId!)) return [];
|
||||||
|
|
||||||
const { command, range } = this.getCurrentCommand(query, selection, force);
|
const { command, range } = this.getCurrentCommand(query, selection, force);
|
||||||
if (
|
if (
|
||||||
command?.[0].length > 1 &&
|
command?.[0] &&
|
||||||
["@room", "@channel", "@everyone", "@here"].some((c) => c.startsWith(command[0]))
|
command[0].length > 1 &&
|
||||||
|
["@room", "@channel", "@everyone", "@here"].some((c) => c.startsWith(command![0]))
|
||||||
) {
|
) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
@ -58,7 +59,7 @@ export default class NotifProvider extends AutocompleteProvider {
|
||||||
<RoomAvatar width={24} height={24} room={this.room} />
|
<RoomAvatar width={24} height={24} room={this.room} />
|
||||||
</PillCompletion>
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range: range!,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ export default class QueryMatcher<T extends {}> {
|
||||||
if (!this._items.has(key)) {
|
if (!this._items.has(key)) {
|
||||||
this._items.set(key, []);
|
this._items.set(key, []);
|
||||||
}
|
}
|
||||||
this._items.get(key).push({
|
this._items.get(key)!.push({
|
||||||
keyWeight: Number(index),
|
keyWeight: Number(index),
|
||||||
object,
|
object,
|
||||||
});
|
});
|
||||||
|
@ -104,7 +104,11 @@ export default class QueryMatcher<T extends {}> {
|
||||||
if (query.length === 0) {
|
if (query.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const matches = [];
|
const matches: {
|
||||||
|
index: number;
|
||||||
|
object: T;
|
||||||
|
keyWeight: number;
|
||||||
|
}[] = [];
|
||||||
// Iterate through the map & check each key.
|
// Iterate through the map & check each key.
|
||||||
// ES6 Map iteration order is defined to be insertion order, so results
|
// ES6 Map iteration order is defined to be insertion order, so results
|
||||||
// here will come out in the order they were put in.
|
// here will come out in the order they were put in.
|
||||||
|
|
|
@ -39,12 +39,12 @@ function canonicalScore(displayedAlias: string, room: Room): number {
|
||||||
|
|
||||||
function matcherObject(
|
function matcherObject(
|
||||||
room: Room,
|
room: Room,
|
||||||
displayedAlias: string | null,
|
displayedAlias: string,
|
||||||
matchName = "",
|
matchName = "",
|
||||||
): {
|
): {
|
||||||
room: Room;
|
room: Room;
|
||||||
matchName: string;
|
matchName: string;
|
||||||
displayedAlias: string | null;
|
displayedAlias: string;
|
||||||
} {
|
} {
|
||||||
return {
|
return {
|
||||||
room,
|
room,
|
||||||
|
@ -81,7 +81,7 @@ export default class RoomProvider extends AutocompleteProvider {
|
||||||
// the only reason we need to do this is because Fuse only matches on properties
|
// the only reason we need to do this is because Fuse only matches on properties
|
||||||
let matcherObjects = this.getRooms().reduce<ReturnType<typeof matcherObject>[]>((aliases, room) => {
|
let matcherObjects = this.getRooms().reduce<ReturnType<typeof matcherObject>[]>((aliases, room) => {
|
||||||
if (room.getCanonicalAlias()) {
|
if (room.getCanonicalAlias()) {
|
||||||
aliases = aliases.concat(matcherObject(room, room.getCanonicalAlias(), room.name));
|
aliases = aliases.concat(matcherObject(room, room.getCanonicalAlias()!, room.name));
|
||||||
}
|
}
|
||||||
if (room.getAltAliases().length) {
|
if (room.getAltAliases().length) {
|
||||||
const altAliases = room.getAltAliases().map((alias) => matcherObject(room, alias));
|
const altAliases = room.getAltAliases().map((alias) => matcherObject(room, alias));
|
||||||
|
@ -122,7 +122,7 @@ export default class RoomProvider extends AutocompleteProvider {
|
||||||
<RoomAvatar width={24} height={24} room={room.room} />
|
<RoomAvatar width={24} height={24} room={room.room} />
|
||||||
</PillCompletion>
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range: range!,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.filter((completion) => !!completion.completion && completion.completion.length > 0);
|
.filter((completion) => !!completion.completion && completion.completion.length > 0);
|
||||||
|
|
|
@ -44,7 +44,7 @@ const FORCED_USER_REGEX = /[^/,:; \t\n]\S*/g;
|
||||||
|
|
||||||
export default class UserProvider extends AutocompleteProvider {
|
export default class UserProvider extends AutocompleteProvider {
|
||||||
public matcher: QueryMatcher<RoomMember>;
|
public matcher: QueryMatcher<RoomMember>;
|
||||||
public users: RoomMember[];
|
public users: RoomMember[] | null;
|
||||||
public room: Room;
|
public room: Room;
|
||||||
|
|
||||||
public constructor(room: Room, renderingType?: TimelineRenderingType) {
|
public constructor(room: Room, renderingType?: TimelineRenderingType) {
|
||||||
|
@ -54,7 +54,7 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
renderingType,
|
renderingType,
|
||||||
});
|
});
|
||||||
this.room = room;
|
this.room = room;
|
||||||
this.matcher = new QueryMatcher([], {
|
this.matcher = new QueryMatcher<RoomMember>([], {
|
||||||
keys: ["name"],
|
keys: ["name"],
|
||||||
funcs: [(obj) => obj.userId.slice(1)], // index by user id minus the leading '@'
|
funcs: [(obj) => obj.userId.slice(1)], // index by user id minus the leading '@'
|
||||||
shouldMatchWordsOnly: false,
|
shouldMatchWordsOnly: false,
|
||||||
|
@ -73,7 +73,7 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
|
|
||||||
private onRoomTimeline = (
|
private onRoomTimeline = (
|
||||||
ev: MatrixEvent,
|
ev: MatrixEvent,
|
||||||
room: Room | null,
|
room: Room | undefined,
|
||||||
toStartOfTimeline: boolean,
|
toStartOfTimeline: boolean,
|
||||||
removed: boolean,
|
removed: boolean,
|
||||||
data: IRoomTimelineData,
|
data: IRoomTimelineData,
|
||||||
|
@ -118,7 +118,7 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
// Don't include the '@' in our search query - it's only used as a way to trigger completion
|
// Don't include the '@' in our search query - it's only used as a way to trigger completion
|
||||||
const query = fullMatch.startsWith("@") ? fullMatch.substring(1) : fullMatch;
|
const query = fullMatch.startsWith("@") ? fullMatch.substring(1) : fullMatch;
|
||||||
return this.matcher.match(query, limit).map((user) => {
|
return this.matcher.match(query, limit).map((user) => {
|
||||||
const description = UserIdentifierCustomisations.getDisplayUserIdentifier(user.userId, {
|
const description = UserIdentifierCustomisations.getDisplayUserIdentifier?.(user.userId, {
|
||||||
roomId: this.room.roomId,
|
roomId: this.room.roomId,
|
||||||
withDisplayName: true,
|
withDisplayName: true,
|
||||||
});
|
});
|
||||||
|
@ -129,14 +129,14 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
completion: user.rawDisplayName,
|
completion: user.rawDisplayName,
|
||||||
completionId: user.userId,
|
completionId: user.userId,
|
||||||
type: "user",
|
type: "user",
|
||||||
suffix: selection.beginning && range.start === 0 ? ": " : " ",
|
suffix: selection.beginning && range!.start === 0 ? ": " : " ",
|
||||||
href: makeUserPermalink(user.userId),
|
href: makeUserPermalink(user.userId),
|
||||||
component: (
|
component: (
|
||||||
<PillCompletion title={displayName} description={description}>
|
<PillCompletion title={displayName} description={description}>
|
||||||
<MemberAvatar member={user} width={24} height={24} />
|
<MemberAvatar member={user} width={24} height={24} />
|
||||||
</PillCompletion>
|
</PillCompletion>
|
||||||
),
|
),
|
||||||
range,
|
range: range!,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
const lastSpoken: Record<string, number> = {};
|
const lastSpoken: Record<string, number> = {};
|
||||||
|
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
lastSpoken[event.getSender()] = event.getTs();
|
lastSpoken[event.getSender()!] = event.getTs();
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentUserId = MatrixClientPeg.get().credentials.userId;
|
const currentUserId = MatrixClientPeg.get().credentials.userId;
|
||||||
|
@ -164,7 +164,7 @@ export default class UserProvider extends AutocompleteProvider {
|
||||||
this.matcher.setObjects(this.users);
|
this.matcher.setObjects(this.users);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onUserSpoke(user: RoomMember): void {
|
public onUserSpoke(user: RoomMember | null): void {
|
||||||
if (!this.users) return;
|
if (!this.users) return;
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
if (user.userId === MatrixClientPeg.get().credentials.userId) return;
|
if (user.userId === MatrixClientPeg.get().credentials.userId) return;
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default class AutoHideScrollbar<T extends keyof JSX.IntrinsicElements> ex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { element, className, onScroll, tabIndex, wrappedRef, children, ...otherProps } = this.props;
|
const { element, className, onScroll, tabIndex, wrappedRef, children, ...otherProps } = this.props;
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ export default class EmbeddedPage extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
// HACK: Workaround for the context's MatrixClient not updating.
|
// HACK: Workaround for the context's MatrixClient not updating.
|
||||||
const client = this.context || MatrixClientPeg.get();
|
const client = this.context || MatrixClientPeg.get();
|
||||||
const isGuest = client ? client.isGuest() : true;
|
const isGuest = client ? client.isGuest() : true;
|
||||||
|
|
|
@ -223,7 +223,7 @@ class FilePanel extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
return (
|
return (
|
||||||
<BaseCard className="mx_FilePanel mx_RoomView_messageListWrapper" onClose={this.props.onClose}>
|
<BaseCard className="mx_FilePanel mx_RoomView_messageListWrapper" onClose={this.props.onClose}>
|
||||||
|
|
|
@ -22,7 +22,7 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class GenericErrorPage extends React.PureComponent<IProps> {
|
export default class GenericErrorPage extends React.PureComponent<IProps> {
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="mx_GenericErrorPage">
|
<div className="mx_GenericErrorPage">
|
||||||
<div className="mx_GenericErrorPage_box">
|
<div className="mx_GenericErrorPage_box">
|
||||||
|
|
|
@ -177,7 +177,7 @@ export default class IndicatorScrollbar<T extends keyof JSX.IntrinsicElements> e
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { children, trackHorizontalOverflow, verticalScrollsHorizontally, ...otherProps } = this.props;
|
const { children, trackHorizontalOverflow, verticalScrollsHorizontally, ...otherProps } = this.props;
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ export default class InteractiveAuthComponent extends React.Component<IProps, IS
|
||||||
this.authLogic.setEmailSid(sid);
|
this.authLogic.setEmailSid(sid);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const stage = this.state.authStage;
|
const stage = this.state.authStage;
|
||||||
if (!stage) {
|
if (!stage) {
|
||||||
if (this.state.busy) {
|
if (this.state.busy) {
|
||||||
|
|
|
@ -619,7 +619,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
this._roomView.current?.handleScrollKey(ev);
|
this._roomView.current?.handleScrollKey(ev);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let pageElement;
|
let pageElement;
|
||||||
|
|
||||||
switch (this.props.page_type) {
|
switch (this.props.page_type) {
|
||||||
|
|
|
@ -47,7 +47,7 @@ export default class MainSplit extends React.Component<IProps> {
|
||||||
};
|
};
|
||||||
|
|
||||||
private loadSidePanelSize(): { height: string | number; width: number } {
|
private loadSidePanelSize(): { height: string | number; width: number } {
|
||||||
let rhsSize = parseInt(window.localStorage.getItem("mx_rhs_size"), 10);
|
let rhsSize = parseInt(window.localStorage.getItem("mx_rhs_size")!, 10);
|
||||||
|
|
||||||
if (isNaN(rhsSize)) {
|
if (isNaN(rhsSize)) {
|
||||||
rhsSize = 350;
|
rhsSize = 350;
|
||||||
|
@ -59,7 +59,7 @@ export default class MainSplit extends React.Component<IProps> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const bodyView = React.Children.only(this.props.children);
|
const bodyView = React.Children.only(this.props.children);
|
||||||
const panelView = this.props.panel;
|
const panelView = this.props.panel;
|
||||||
|
|
||||||
|
|
|
@ -2021,7 +2021,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
return fragmentAfterLogin;
|
return fragmentAfterLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const fragmentAfterLogin = this.getFragmentAfterLogin();
|
const fragmentAfterLogin = this.getFragmentAfterLogin();
|
||||||
let view = null;
|
let view = null;
|
||||||
|
|
||||||
|
|
|
@ -982,7 +982,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let topSpinner;
|
let topSpinner;
|
||||||
let bottomSpinner;
|
let bottomSpinner;
|
||||||
if (this.props.backPaginating) {
|
if (this.props.backPaginating) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ export default class NonUrgentToastContainer extends React.PureComponent<IProps,
|
||||||
this.setState({ toasts: NonUrgentToastStore.instance.components });
|
this.setState({ toasts: NonUrgentToastStore.instance.components });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const toasts = this.state.toasts.map((t, i) => {
|
const toasts = this.state.toasts.map((t, i) => {
|
||||||
return (
|
return (
|
||||||
<div className="mx_NonUrgentToastContainer_toast" key={`toast-${i}`}>
|
<div className="mx_NonUrgentToastContainer_toast" key={`toast-${i}`}>
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default class NotificationPanel extends React.PureComponent<IProps, IStat
|
||||||
this.setState({ narrow });
|
this.setState({ narrow });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const emptyState = (
|
const emptyState = (
|
||||||
<div className="mx_RightPanel_empty mx_NotificationPanel_empty">
|
<div className="mx_RightPanel_empty mx_NotificationPanel_empty">
|
||||||
<h2>{_t("You're all caught up")}</h2>
|
<h2>{_t("You're all caught up")}</h2>
|
||||||
|
|
|
@ -245,7 +245,7 @@ export default class PictureInPictureDragger extends React.Component<IProps> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const style = {
|
const style = {
|
||||||
transform: `translateX(${this.translationX}px) translateY(${this.translationY}px)`,
|
transform: `translateX(${this.translationX}px) translateY(${this.translationY}px)`,
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { MutableRefObject, useContext, useRef } from "react";
|
import React, { MutableRefObject, ReactNode, useContext, useRef } from "react";
|
||||||
import { CallEvent, CallState, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
import { CallEvent, CallState, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { Optional } from "matrix-events-sdk";
|
import { Optional } from "matrix-events-sdk";
|
||||||
|
@ -288,7 +288,7 @@ class PipContainerInner extends React.Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): ReactNode {
|
||||||
const pipMode = true;
|
const pipMode = true;
|
||||||
let pipContent: Array<CreatePipChildren> = [];
|
let pipContent: Array<CreatePipChildren> = [];
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ export default class RightPanel extends React.Component<IProps, IState> {
|
||||||
this.setState({ searchQuery });
|
this.setState({ searchQuery });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let card = <div />;
|
let card = <div />;
|
||||||
const roomId = this.props.room?.roomId;
|
const roomId = this.props.room?.roomId;
|
||||||
const phase = this.props.overwriteCard?.phase ?? this.state.phase;
|
const phase = this.props.overwriteCard?.phase ?? this.state.phase;
|
||||||
|
|
|
@ -111,11 +111,11 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(
|
||||||
);
|
);
|
||||||
if (!bundledRelationship || event.getThread()) continue;
|
if (!bundledRelationship || event.getThread()) continue;
|
||||||
const room = client.getRoom(event.getRoomId());
|
const room = client.getRoom(event.getRoomId());
|
||||||
const thread = room.findThreadForEvent(event);
|
const thread = room?.findThreadForEvent(event);
|
||||||
if (thread) {
|
if (thread) {
|
||||||
event.setThread(thread);
|
event.setThread(thread);
|
||||||
} else {
|
} else {
|
||||||
room.createThread(event.getId(), event, [], true);
|
room?.createThread(event.getId()!, event, [], true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(
|
||||||
scrollPanel?.checkScroll();
|
scrollPanel?.checkScroll();
|
||||||
};
|
};
|
||||||
|
|
||||||
let lastRoomId: string;
|
let lastRoomId: string | undefined;
|
||||||
let mergedTimeline: MatrixEvent[] = [];
|
let mergedTimeline: MatrixEvent[] = [];
|
||||||
let ourEventsIndexes: number[] = [];
|
let ourEventsIndexes: number[] = [];
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,7 @@ export default class RoomStatusBar extends React.PureComponent<IProps, IState> {
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
consentLink: (sub) => (
|
consentLink: (sub) => (
|
||||||
<a href={consentError.data && consentError.data.consent_uri} target="_blank">
|
<a href={consentError!.data?.consent_uri} target="_blank">
|
||||||
{sub}
|
{sub}
|
||||||
</a>
|
</a>
|
||||||
),
|
),
|
||||||
|
@ -272,7 +272,7 @@ export default class RoomStatusBar extends React.PureComponent<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (this.shouldShowConnectionError()) {
|
if (this.shouldShowConnectionError()) {
|
||||||
return (
|
return (
|
||||||
<div className="mx_RoomStatusBar">
|
<div className="mx_RoomStatusBar">
|
||||||
|
|
|
@ -1879,7 +1879,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (this.state.room instanceof LocalRoom) {
|
if (this.state.room instanceof LocalRoom) {
|
||||||
if (this.state.room.state === LocalRoomState.CREATING) {
|
if (this.state.room.state === LocalRoomState.CREATING) {
|
||||||
return this.renderLocalRoomCreateLoader();
|
return this.renderLocalRoomCreateLoader();
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { getKeyBindingsManager } from "../../KeyBindingsManager";
|
||||||
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
|
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
|
||||||
|
|
||||||
interface IProps extends HTMLProps<HTMLInputElement> {
|
interface IProps extends HTMLProps<HTMLInputElement> {
|
||||||
onSearch?: (query: string) => void;
|
onSearch: (query: string) => void;
|
||||||
onCleared?: (source?: string) => void;
|
onCleared?: (source?: string) => void;
|
||||||
onKeyDown?: (ev: React.KeyboardEvent) => void;
|
onKeyDown?: (ev: React.KeyboardEvent) => void;
|
||||||
onFocus?: (ev: React.FocusEvent) => void;
|
onFocus?: (ev: React.FocusEvent) => void;
|
||||||
|
@ -62,7 +62,7 @@ export default class SearchBox extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
private onSearch = throttle(
|
private onSearch = throttle(
|
||||||
(): void => {
|
(): void => {
|
||||||
this.props.onSearch(this.search.current.value);
|
this.props.onSearch(this.search.current?.value);
|
||||||
},
|
},
|
||||||
200,
|
200,
|
||||||
{ trailing: true, leading: true },
|
{ trailing: true, leading: true },
|
||||||
|
@ -101,7 +101,7 @@ export default class SearchBox extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
|
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
|
||||||
const {
|
const {
|
||||||
onSearch,
|
onSearch,
|
||||||
|
|
|
@ -814,7 +814,7 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const rightPanel =
|
const rightPanel =
|
||||||
this.state.showRightPanel && this.state.phase === Phase.Landing ? (
|
this.state.showRightPanel && this.state.phase === Phase.Landing ? (
|
||||||
<RightPanel room={this.props.space} resizeNotifier={this.props.resizeNotifier} />
|
<RightPanel room={this.props.space} resizeNotifier={this.props.resizeNotifier} />
|
||||||
|
|
|
@ -343,7 +343,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const highlightedEventId = this.props.isInitialEventHighlighted ? this.props.initialEvent?.getId() : null;
|
const highlightedEventId = this.props.isInitialEventHighlighted ? this.props.initialEvent?.getId() : null;
|
||||||
|
|
||||||
const threadRelation = this.threadRelation;
|
const threadRelation = this.threadRelation;
|
||||||
|
|
|
@ -1886,7 +1886,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
|
||||||
this.callEventGroupers = buildLegacyCallEventGroupers(this.callEventGroupers, events);
|
this.callEventGroupers = buildLegacyCallEventGroupers(this.callEventGroupers, events);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
// just show a spinner while the timeline loads.
|
// just show a spinner while the timeline loads.
|
||||||
//
|
//
|
||||||
// put it in a div of the right class (mx_RoomView_messagePanel) so
|
// put it in a div of the right class (mx_RoomView_messagePanel) so
|
||||||
|
|
|
@ -50,7 +50,7 @@ export default class ToastContainer extends React.Component<{}, IState> {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const totalCount = this.state.toasts.length;
|
const totalCount = this.state.toasts.length;
|
||||||
const isStacked = totalCount > 1;
|
const isStacked = totalCount > 1;
|
||||||
let toast;
|
let toast;
|
||||||
|
|
|
@ -103,7 +103,7 @@ export default class UploadBar extends React.PureComponent<IProps, IState> {
|
||||||
ContentMessages.sharedInstance().cancelUpload(this.state.currentUpload!);
|
ContentMessages.sharedInstance().cancelUpload(this.state.currentUpload!);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (!this.state.currentFile) {
|
if (!this.state.currentFile) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,7 +429,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const avatarSize = 32; // should match border-radius of the avatar
|
const avatarSize = 32; // should match border-radius of the avatar
|
||||||
|
|
||||||
const userId = MatrixClientPeg.get().getUserId();
|
const userId = MatrixClientPeg.get().getUserId();
|
||||||
|
|
|
@ -18,6 +18,7 @@ limitations under the License.
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||||
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
|
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||||
import Modal from "../../Modal";
|
import Modal from "../../Modal";
|
||||||
|
@ -31,7 +32,7 @@ import { RightPanelPhases } from "../../stores/right-panel/RightPanelStorePhases
|
||||||
import { UserOnboardingPage } from "../views/user-onboarding/UserOnboardingPage";
|
import { UserOnboardingPage } from "../views/user-onboarding/UserOnboardingPage";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
userId?: string;
|
userId: string;
|
||||||
resizeNotifier: ResizeNotifier;
|
resizeNotifier: ResizeNotifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ export default class UserView extends React.Component<IProps, IState> {
|
||||||
private async loadProfileInfo(): Promise<void> {
|
private async loadProfileInfo(): Promise<void> {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
let profileInfo;
|
let profileInfo: Awaited<ReturnType<MatrixClient["getProfileInfo"]>>;
|
||||||
try {
|
try {
|
||||||
profileInfo = await cli.getProfileInfo(this.props.userId);
|
profileInfo = await cli.getProfileInfo(this.props.userId);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -83,7 +84,7 @@ export default class UserView extends React.Component<IProps, IState> {
|
||||||
this.setState({ member, loading: false });
|
this.setState({ member, loading: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (this.state.loading) {
|
if (this.state.loading) {
|
||||||
return <Spinner />;
|
return <Spinner />;
|
||||||
} else if (this.state.member) {
|
} else if (this.state.member) {
|
||||||
|
|
|
@ -142,7 +142,7 @@ export default class ViewSource extends React.Component<IProps, IState> {
|
||||||
return room.currentState.mayClientSendStateEvent(mxEvent.getType(), cli);
|
return room.currentState.mayClientSendStateEvent(mxEvent.getType(), cli);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const mxEvent = this.props.mxEvent.replacingEvent() || this.props.mxEvent; // show the replacing event, not the original, if it is an edit
|
const mxEvent = this.props.mxEvent.replacingEvent() || this.props.mxEvent; // show the replacing event, not the original, if it is an edit
|
||||||
|
|
||||||
const isEditing = this.state.isEditing;
|
const isEditing = this.state.isEditing;
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default class CompleteSecurity extends React.Component<IProps, IState> {
|
||||||
store.stop();
|
store.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const { phase, lostKeys } = this.state;
|
const { phase, lostKeys } = this.state;
|
||||||
let icon;
|
let icon;
|
||||||
let title;
|
let title;
|
||||||
|
|
|
@ -27,7 +27,7 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class E2eSetup extends React.Component<IProps> {
|
export default class E2eSetup extends React.Component<IProps> {
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<AuthPage>
|
<AuthPage>
|
||||||
<CompleteSecurityBody>
|
<CompleteSecurityBody>
|
||||||
|
|
|
@ -487,7 +487,7 @@ export default class ForgotPassword extends React.Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let resetPasswordJsx: JSX.Element;
|
let resetPasswordJsx: JSX.Element;
|
||||||
|
|
||||||
switch (this.state.phase) {
|
switch (this.state.phase) {
|
||||||
|
|
|
@ -563,7 +563,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const loader =
|
const loader =
|
||||||
this.isBusy() && !this.state.busyLoggingIn ? (
|
this.isBusy() && !this.state.busyLoggingIn ? (
|
||||||
<div className="mx_Login_loader">
|
<div className="mx_Login_loader">
|
||||||
|
|
|
@ -573,7 +573,7 @@ export default class Registration extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let errorText;
|
let errorText;
|
||||||
const err = this.state.errorText;
|
const err = this.state.errorText;
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
|
@ -141,7 +141,7 @@ export default class SetupEncryptionBody extends React.Component<IProps, IState>
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const { phase, lostKeys } = this.state;
|
const { phase, lostKeys } = this.state;
|
||||||
|
|
||||||
if (this.state.verificationRequest) {
|
if (this.state.verificationRequest) {
|
||||||
|
|
|
@ -326,7 +326,7 @@ export default class SoftLogout extends React.Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<AuthPage>
|
<AuthPage>
|
||||||
<AuthHeader />
|
<AuthHeader />
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default class Clock extends React.Component<Props> {
|
||||||
return currentFloor !== nextFloor;
|
return currentFloor !== nextFloor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<span aria-live={this.props["aria-live"]} role={this.props.role} className="mx_Clock">
|
<span aria-live={this.props["aria-live"]} role={this.props.role} className="mx_Clock">
|
||||||
{this.props.formatFn(this.props.seconds)}
|
{this.props.formatFn(this.props.seconds)}
|
||||||
|
|
|
@ -48,7 +48,7 @@ export default class DurationClock extends React.PureComponent<IProps, IState> {
|
||||||
this.setState({ durationSeconds: time[1] });
|
this.setState({ durationSeconds: time[1] });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return <Clock seconds={this.state.durationSeconds} />;
|
return <Clock seconds={this.state.durationSeconds} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ export default class LiveRecordingClock extends React.PureComponent<IProps, ISta
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return <Clock seconds={this.state.seconds} aria-live="off" />;
|
return <Clock seconds={this.state.seconds} aria-live="off" />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ export default class LiveRecordingWaveform extends React.PureComponent<IProps, I
|
||||||
this.setState({ waveform: this.waveform });
|
this.setState({ waveform: this.waveform });
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return <Waveform relHeights={this.state.waveform} />;
|
return <Waveform relHeights={this.state.waveform} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ export default class PlaybackClock extends React.PureComponent<IProps, IState> {
|
||||||
this.setState({ seconds: time[0], durationSeconds: time[1] });
|
this.setState({ seconds: time[0], durationSeconds: time[1] });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let seconds = this.state.seconds;
|
let seconds = this.state.seconds;
|
||||||
if (this.state.playbackPhase === PlaybackState.Stopped) {
|
if (this.state.playbackPhase === PlaybackState.Stopped) {
|
||||||
if (Number.isFinite(this.props.defaultDisplaySeconds)) {
|
if (Number.isFinite(this.props.defaultDisplaySeconds)) {
|
||||||
|
|
|
@ -61,7 +61,7 @@ export default class PlaybackWaveform extends React.PureComponent<IProps, IState
|
||||||
this.setState({ progress });
|
this.setState({ progress });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return <Waveform relHeights={this.state.heights} progress={this.state.progress} />;
|
return <Waveform relHeights={this.state.heights} progress={this.state.progress} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default class Waveform extends React.PureComponent<IProps, IState> {
|
||||||
progress: 1,
|
progress: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="mx_Waveform">
|
<div className="mx_Waveform">
|
||||||
{this.props.relHeights.map((h, i) => {
|
{this.props.relHeights.map((h, i) => {
|
||||||
|
|
|
@ -122,7 +122,7 @@ export default class CaptchaForm extends React.Component<ICaptchaFormProps, ICap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let error = null;
|
let error = null;
|
||||||
if (this.state.errorText) {
|
if (this.state.errorText) {
|
||||||
error = <div className="error">{this.state.errorText}</div>;
|
error = <div className="error">{this.state.errorText}</div>;
|
||||||
|
|
|
@ -74,7 +74,7 @@ class EmailField extends PureComponent<IProps> {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<Field
|
<Field
|
||||||
id={this.props.id}
|
id={this.props.id}
|
||||||
|
|
|
@ -136,7 +136,7 @@ export class PasswordAuthEntry extends React.Component<IAuthEntryProps, IPasswor
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const passwordBoxClass = classNames({
|
const passwordBoxClass = classNames({
|
||||||
error: this.props.errorText,
|
error: this.props.errorText,
|
||||||
});
|
});
|
||||||
|
@ -207,7 +207,7 @@ export class RecaptchaAuthEntry extends React.Component<IRecaptchaAuthEntryProps
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (this.props.busy) {
|
if (this.props.busy) {
|
||||||
return <Spinner />;
|
return <Spinner />;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,7 @@ export class TermsAuthEntry extends React.Component<ITermsAuthEntryProps, ITerms
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (this.props.busy) {
|
if (this.props.busy) {
|
||||||
return <Spinner />;
|
return <Spinner />;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +442,7 @@ export class EmailIdentityAuthEntry extends React.Component<
|
||||||
this.props.onPhaseChange(DEFAULT_PHASE);
|
this.props.onPhaseChange(DEFAULT_PHASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let errorSection;
|
let errorSection;
|
||||||
// ignore the error when errcode is M_UNAUTHORIZED as we expect that error until the link is clicked.
|
// ignore the error when errcode is M_UNAUTHORIZED as we expect that error until the link is clicked.
|
||||||
if (this.props.errorText && this.props.errorCode !== "M_UNAUTHORIZED") {
|
if (this.props.errorText && this.props.errorCode !== "M_UNAUTHORIZED") {
|
||||||
|
@ -650,7 +650,7 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (this.state.requestingToken) {
|
if (this.state.requestingToken) {
|
||||||
return <Spinner />;
|
return <Spinner />;
|
||||||
} else {
|
} else {
|
||||||
|
@ -733,7 +733,7 @@ export class RegistrationTokenAuthEntry extends React.Component<IAuthEntryProps,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const registrationTokenBoxClass = classNames({
|
const registrationTokenBoxClass = classNames({
|
||||||
error: this.props.errorText,
|
error: this.props.errorText,
|
||||||
});
|
});
|
||||||
|
@ -857,7 +857,7 @@ export class SSOAuthEntry extends React.Component<ISSOAuthEntryProps, ISSOAuthEn
|
||||||
this.props.submitAuthDict({});
|
this.props.submitAuthDict({});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let continueButton = null;
|
let continueButton = null;
|
||||||
const cancelButton = (
|
const cancelButton = (
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
|
@ -952,7 +952,7 @@ export class FallbackAuthEntry extends React.Component<IAuthEntryProps> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let errorSection;
|
let errorSection;
|
||||||
if (this.props.errorText) {
|
if (this.props.errorText) {
|
||||||
errorSection = (
|
errorSection = (
|
||||||
|
|
|
@ -229,7 +229,7 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<LoginWithQRFlow
|
<LoginWithQRFlow
|
||||||
onClick={this.onClick}
|
onClick={this.onClick}
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default class LoginWithQRFlow extends React.Component<IProps> {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let title = "";
|
let title = "";
|
||||||
let titleIcon: JSX.Element | undefined;
|
let titleIcon: JSX.Element | undefined;
|
||||||
let main: JSX.Element | undefined;
|
let main: JSX.Element | undefined;
|
||||||
|
|
|
@ -65,7 +65,7 @@ class PassphraseConfirmField extends PureComponent<IProps> {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<Field
|
<Field
|
||||||
id={this.props.id}
|
id={this.props.id}
|
||||||
|
|
|
@ -102,7 +102,7 @@ class PassphraseField extends PureComponent<IProps> {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<Field
|
<Field
|
||||||
id={this.props.id}
|
id={this.props.id}
|
||||||
|
|
|
@ -367,7 +367,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let forgotPasswordJsx;
|
let forgotPasswordJsx;
|
||||||
|
|
||||||
if (this.props.onForgotPasswordClick) {
|
if (this.props.onForgotPasswordClick) {
|
||||||
|
|
|
@ -534,7 +534,7 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const registerButton = (
|
const registerButton = (
|
||||||
<input className="mx_Login_submit" type="submit" value={_t("Register")} disabled={!this.props.canSubmit} />
|
<input className="mx_Login_submit" type="submit" value={_t("Register")} disabled={!this.props.canSubmit} />
|
||||||
);
|
);
|
||||||
|
|
|
@ -109,7 +109,7 @@ export default function MemberAvatar({
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LegacyMemberAvatar extends React.Component<IProps> {
|
export class LegacyMemberAvatar extends React.Component<IProps> {
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return <MemberAvatar {...this.props}>{this.props.children}</MemberAvatar>;
|
return <MemberAvatar {...this.props}>{this.props.children}</MemberAvatar>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ export default class RoomAvatar extends React.Component<IProps, IState> {
|
||||||
return this.props.room?.roomId || this.props.oobData?.roomId;
|
return this.props.room?.roomId || this.props.oobData?.roomId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const { room, oobData, viewAvatarOnClick, onClick, className, ...otherProps } = this.props;
|
const { room, oobData, viewAvatarOnClick, onClick, className, ...otherProps } = this.props;
|
||||||
const roomName = room?.name ?? oobData.name;
|
const roomName = room?.name ?? oobData.name;
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ const BetaCard: React.FC<IProps> = ({ title: titleOverride, featureId }) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let refreshWarning: string;
|
let refreshWarning: string | undefined;
|
||||||
if (requiresRefresh) {
|
if (requiresRefresh) {
|
||||||
const brand = SdkConfig.get().brand;
|
const brand = SdkConfig.get().brand;
|
||||||
refreshWarning = value
|
refreshWarning = value
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default class DialpadContextMenu extends React.Component<IProps, IState>
|
||||||
this.setState({ value: ev.target.value });
|
this.setState({ value: ev.target.value });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<ContextMenu {...this.props}>
|
<ContextMenu {...this.props}>
|
||||||
<div className="mx_DialPadContextMenuWrapper">
|
<div className="mx_DialPadContextMenuWrapper">
|
||||||
|
|
|
@ -47,7 +47,7 @@ export default class GenericElementContextMenu extends React.Component<IProps> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return <div>{this.props.element}</div>;
|
return <div>{this.props.element}</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class GenericTextContextMenu extends React.Component<IProps> {
|
export default class GenericTextContextMenu extends React.Component<IProps> {
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<div className="mx_Tooltip mx_Tooltip_visible" style={{ display: "block" }}>
|
<div className="mx_Tooltip mx_Tooltip_visible" style={{ display: "block" }}>
|
||||||
{this.props.message}
|
{this.props.message}
|
||||||
|
|
|
@ -46,7 +46,7 @@ export default class LegacyCallContextMenu extends React.Component<IProps> {
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const holdUnholdCaption = this.props.call.isRemoteOnHold() ? _t("Resume") : _t("Hold");
|
const holdUnholdCaption = this.props.call.isRemoteOnHold() ? _t("Resume") : _t("Hold");
|
||||||
const handler = this.props.call.isRemoteOnHold() ? this.onUnholdClick : this.onHoldClick;
|
const handler = this.props.call.isRemoteOnHold() ? this.onUnholdClick : this.onHoldClick;
|
||||||
|
|
||||||
|
|
|
@ -376,7 +376,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
|
||||||
this.closeMenu();
|
this.closeMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const me = cli.getUserId();
|
const me = cli.getUserId();
|
||||||
const { mxEvent, rightClick, link, eventTileOps, reactions, collapseReplyChain, ...other } = this.props;
|
const { mxEvent, rightClick, link, eventTileOps, reactions, collapseReplyChain, ...other } = this.props;
|
||||||
|
|
|
@ -48,7 +48,7 @@ export default class AskInviteAnywayDialog extends React.Component<IProps> {
|
||||||
this.props.onFinished(false);
|
this.props.onFinished(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const errorList = this.props.unknownProfileUsers.map((address) => (
|
const errorList = this.props.unknownProfileUsers.map((address) => (
|
||||||
<li key={address.userId}>
|
<li key={address.userId}>
|
||||||
{address.userId}: {address.errorText}
|
{address.userId}: {address.errorText}
|
||||||
|
|
|
@ -115,7 +115,7 @@ export default class BaseDialog extends React.Component<IProps> {
|
||||||
this.props.onFinished(false);
|
this.props.onFinished(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let cancelButton;
|
let cancelButton;
|
||||||
if (this.props.hasCancel) {
|
if (this.props.hasCancel) {
|
||||||
cancelButton = (
|
cancelButton = (
|
||||||
|
|
|
@ -180,7 +180,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
|
||||||
this.setState({ downloadProgress });
|
this.setState({ downloadProgress });
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let error = null;
|
let error = null;
|
||||||
if (this.state.err) {
|
if (this.state.err) {
|
||||||
error = <div className="error">{this.state.err}</div>;
|
error = <div className="error">{this.state.err}</div>;
|
||||||
|
|
|
@ -86,7 +86,7 @@ export default class ChangelogDialog extends React.Component<IProps, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const logs = REPOS.map((repo) => {
|
const logs = REPOS.map((repo) => {
|
||||||
let content;
|
let content;
|
||||||
if (this.state[repo] == null) {
|
if (this.state[repo] == null) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IPro
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
if (this.state.isRedacting) {
|
if (this.state.isRedacting) {
|
||||||
if (this.state.redactionErrorCode) {
|
if (this.state.redactionErrorCode) {
|
||||||
const code = this.state.redactionErrorCode;
|
const code = this.state.redactionErrorCode;
|
||||||
|
|
|
@ -33,7 +33,7 @@ interface IProps {
|
||||||
* A dialog for confirming a redaction.
|
* A dialog for confirming a redaction.
|
||||||
*/
|
*/
|
||||||
export default class ConfirmRedactDialog extends React.Component<IProps> {
|
export default class ConfirmRedactDialog extends React.Component<IProps> {
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<TextInputDialog
|
<TextInputDialog
|
||||||
onFinished={this.props.onFinished}
|
onFinished={this.props.onFinished}
|
||||||
|
|
|
@ -83,7 +83,7 @@ export default class ConfirmUserActionDialog extends React.Component<IProps, ISt
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const confirmButtonClass = this.props.danger ? "danger" : "";
|
const confirmButtonClass = this.props.danger ? "danger" : "";
|
||||||
|
|
||||||
let reasonBox;
|
let reasonBox;
|
||||||
|
|
|
@ -33,7 +33,7 @@ export default class ConfirmWipeDeviceDialog extends React.Component<IProps> {
|
||||||
this.props.onFinished(false);
|
this.props.onFinished(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<BaseDialog
|
<BaseDialog
|
||||||
className="mx_ConfirmWipeDeviceDialog"
|
className="mx_ConfirmWipeDeviceDialog"
|
||||||
|
|
|
@ -216,7 +216,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
const isVideoRoom = this.props.type === RoomType.ElementVideo;
|
const isVideoRoom = this.props.type === RoomType.ElementVideo;
|
||||||
|
|
||||||
let aliasField: JSX.Element;
|
let aliasField: JSX.Element;
|
||||||
|
|
|
@ -182,7 +182,7 @@ export default class DeactivateAccountDialog extends React.Component<IProps, ISt
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
let error = null;
|
let error = null;
|
||||||
if (this.state.errStr) {
|
if (this.state.errStr) {
|
||||||
error = <div className="error">{this.state.errStr}</div>;
|
error = <div className="error">{this.state.errStr}</div>;
|
||||||
|
|
|
@ -67,7 +67,7 @@ export default class EndPollDialog extends React.Component<IProps> {
|
||||||
this.props.onFinished(endPoll);
|
this.props.onFinished(endPoll);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<QuestionDialog
|
<QuestionDialog
|
||||||
title={_t("End Poll")}
|
title={_t("End Poll")}
|
||||||
|
|
|
@ -52,7 +52,7 @@ export default class ErrorDialog extends React.Component<IProps, IState> {
|
||||||
this.props.onFinished(true);
|
this.props.onFinished(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): JSX.Element {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<BaseDialog
|
<BaseDialog
|
||||||
className="mx_ErrorDialog"
|
className="mx_ErrorDialog"
|
||||||
|
|
|
@ -97,7 +97,7 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let bugReports = null;
|
let bugReports: JSX.Element | null = null;
|
||||||
if (rageshakeUrl) {
|
if (rageshakeUrl) {
|
||||||
bugReports = (
|
bugReports = (
|
||||||
<p className="mx_FeedbackDialog_section_microcopy">
|
<p className="mx_FeedbackDialog_section_microcopy">
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue