Apply strictNullChecks
around the codebase (#10302
* Apply `strictNullChecks` around the codebase * Iterate PR
This commit is contained in:
parent
7c2bb966d0
commit
4b8bada24b
26 changed files with 112 additions and 77 deletions
|
@ -152,7 +152,7 @@ async function infoForImageFile(
|
||||||
// For lesser supported image types, always include the thumbnail even if it is larger
|
// For lesser supported image types, always include the thumbnail even if it is larger
|
||||||
if (!ALWAYS_INCLUDE_THUMBNAIL.includes(imageFile.type)) {
|
if (!ALWAYS_INCLUDE_THUMBNAIL.includes(imageFile.type)) {
|
||||||
// we do all sizing checks here because we still rely on thumbnail generation for making a blurhash from.
|
// we do all sizing checks here because we still rely on thumbnail generation for making a blurhash from.
|
||||||
const sizeDifference = imageFile.size - imageInfo.thumbnail_info.size;
|
const sizeDifference = imageFile.size - imageInfo.thumbnail_info!.size;
|
||||||
if (
|
if (
|
||||||
// image is small enough already
|
// image is small enough already
|
||||||
imageFile.size <= IMAGE_SIZE_THRESHOLD_THUMBNAIL ||
|
imageFile.size <= IMAGE_SIZE_THRESHOLD_THUMBNAIL ||
|
||||||
|
|
|
@ -227,7 +227,11 @@ export default class DeviceListener {
|
||||||
// & cache the result
|
// & cache the result
|
||||||
private async getKeyBackupInfo(): Promise<IKeyBackupInfo | null> {
|
private async getKeyBackupInfo(): Promise<IKeyBackupInfo | null> {
|
||||||
const now = new Date().getTime();
|
const now = new Date().getTime();
|
||||||
if (!this.keyBackupInfo || this.keyBackupFetchedAt < now - KEY_BACKUP_POLL_INTERVAL) {
|
if (
|
||||||
|
!this.keyBackupInfo ||
|
||||||
|
!this.keyBackupFetchedAt ||
|
||||||
|
this.keyBackupFetchedAt < now - KEY_BACKUP_POLL_INTERVAL
|
||||||
|
) {
|
||||||
this.keyBackupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
|
this.keyBackupInfo = await MatrixClientPeg.get().getKeyBackupVersion();
|
||||||
this.keyBackupFetchedAt = now;
|
this.keyBackupFetchedAt = now;
|
||||||
}
|
}
|
||||||
|
@ -392,7 +396,7 @@ export default class DeviceListener {
|
||||||
private updateClientInformation = async (): Promise<void> => {
|
private updateClientInformation = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
if (this.shouldRecordClientInformation) {
|
if (this.shouldRecordClientInformation) {
|
||||||
await recordClientInformation(MatrixClientPeg.get(), SdkConfig.get(), PlatformPeg.get());
|
await recordClientInformation(MatrixClientPeg.get(), SdkConfig.get(), PlatformPeg.get() ?? undefined);
|
||||||
} else {
|
} else {
|
||||||
await removeClientInformation(MatrixClientPeg.get());
|
await removeClientInformation(MatrixClientPeg.get());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { CATEGORIES, CategoryName, KeyBindingAction } from "./accessibility/Keyb
|
||||||
import { getKeyboardShortcuts } from "./accessibility/KeyboardShortcutUtils";
|
import { getKeyboardShortcuts } from "./accessibility/KeyboardShortcutUtils";
|
||||||
|
|
||||||
export const getBindingsByCategory = (category: CategoryName): KeyBinding[] => {
|
export const getBindingsByCategory = (category: CategoryName): KeyBinding[] => {
|
||||||
return CATEGORIES[category].settingNames.reduce((bindings, action) => {
|
return CATEGORIES[category].settingNames.reduce<KeyBinding[]>((bindings, action) => {
|
||||||
const keyCombo = getKeyboardShortcuts()[action]?.default;
|
const keyCombo = getKeyboardShortcuts()[action]?.default;
|
||||||
if (keyCombo) {
|
if (keyCombo) {
|
||||||
bindings.push({ action, keyCombo });
|
bindings.push({ action, keyCombo });
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { ReactInstance } from "react";
|
import React, { Key, ReactElement, ReactInstance } from "react";
|
||||||
import ReactDom from "react-dom";
|
import ReactDom from "react-dom";
|
||||||
|
|
||||||
interface IChildProps {
|
interface IChildProps {
|
||||||
|
@ -42,7 +42,7 @@ interface IProps {
|
||||||
*/
|
*/
|
||||||
export default class NodeAnimator extends React.Component<IProps> {
|
export default class NodeAnimator extends React.Component<IProps> {
|
||||||
private nodes: Record<string, ReactInstance> = {};
|
private nodes: Record<string, ReactInstance> = {};
|
||||||
private children: { [key: string]: React.DetailedReactHTMLElement<any, HTMLElement> };
|
private children: { [key: string]: ReactElement };
|
||||||
public static defaultProps: Partial<IProps> = {
|
public static defaultProps: Partial<IProps> = {
|
||||||
startStyles: [],
|
startStyles: [],
|
||||||
};
|
};
|
||||||
|
@ -72,17 +72,17 @@ export default class NodeAnimator extends React.Component<IProps> {
|
||||||
private updateChildren(newChildren: React.ReactNode): void {
|
private updateChildren(newChildren: React.ReactNode): void {
|
||||||
const oldChildren = this.children || {};
|
const oldChildren = this.children || {};
|
||||||
this.children = {};
|
this.children = {};
|
||||||
React.Children.toArray(newChildren).forEach((c: any) => {
|
React.Children.toArray(newChildren).forEach((c: ReactElement) => {
|
||||||
if (oldChildren[c.key]) {
|
if (oldChildren[c.key!]) {
|
||||||
const old = oldChildren[c.key];
|
const old = oldChildren[c.key!];
|
||||||
const oldNode = ReactDom.findDOMNode(this.nodes[old.key]);
|
const oldNode = ReactDom.findDOMNode(this.nodes[old.key!]);
|
||||||
|
|
||||||
if (oldNode && (oldNode as HTMLElement).style.left !== c.props.style.left) {
|
if (oldNode && (oldNode as HTMLElement).style.left !== c.props.style.left) {
|
||||||
this.applyStyles(oldNode as HTMLElement, { left: c.props.style.left });
|
this.applyStyles(oldNode as HTMLElement, { left: c.props.style.left });
|
||||||
}
|
}
|
||||||
// clone the old element with the props (and children) of the new element
|
// clone the old element with the props (and children) of the new element
|
||||||
// so prop updates are still received by the children.
|
// so prop updates are still received by the children.
|
||||||
this.children[c.key] = React.cloneElement(old, c.props, c.props.children);
|
this.children[c.key!] = React.cloneElement(old, c.props, c.props.children);
|
||||||
} else {
|
} else {
|
||||||
// new element. If we have a startStyle, use that as the style and go through
|
// new element. If we have a startStyle, use that as the style and go through
|
||||||
// the enter animations
|
// the enter animations
|
||||||
|
@ -95,14 +95,14 @@ export default class NodeAnimator extends React.Component<IProps> {
|
||||||
newProps.style = startStyle;
|
newProps.style = startStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
newProps.ref = (n) => this.collectNode(c.key, n, restingStyle);
|
newProps.ref = (n) => this.collectNode(c.key!, n, restingStyle);
|
||||||
|
|
||||||
this.children[c.key] = React.cloneElement(c, newProps);
|
this.children[c.key!] = React.cloneElement(c, newProps);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private collectNode(k: string, node: React.ReactInstance, restingStyle: React.CSSProperties): void {
|
private collectNode(k: Key, node: React.ReactInstance, restingStyle: React.CSSProperties): void {
|
||||||
if (node && this.nodes[k] === undefined && this.props.startStyles.length > 0) {
|
if (node && this.nodes[k] === undefined && this.props.startStyles.length > 0) {
|
||||||
const startStyles = this.props.startStyles;
|
const startStyles = this.props.startStyles;
|
||||||
const domNode = ReactDom.findDOMNode(node);
|
const domNode = ReactDom.findDOMNode(node);
|
||||||
|
|
|
@ -106,9 +106,10 @@ class NotifierClass {
|
||||||
private toolbarHidden?: boolean;
|
private toolbarHidden?: boolean;
|
||||||
private isSyncing?: boolean;
|
private isSyncing?: boolean;
|
||||||
|
|
||||||
public notificationMessageForEvent(ev: MatrixEvent): string {
|
public notificationMessageForEvent(ev: MatrixEvent): string | null {
|
||||||
if (msgTypeHandlers.hasOwnProperty(ev.getContent().msgtype)) {
|
const msgType = ev.getContent().msgtype;
|
||||||
return msgTypeHandlers[ev.getContent().msgtype](ev);
|
if (msgType && msgTypeHandlers.hasOwnProperty(msgType)) {
|
||||||
|
return msgTypeHandlers[msgType](ev);
|
||||||
}
|
}
|
||||||
return TextForEvent.textForEvent(ev);
|
return TextForEvent.textForEvent(ev);
|
||||||
}
|
}
|
||||||
|
@ -134,9 +135,9 @@ class NotifierClass {
|
||||||
let title;
|
let title;
|
||||||
if (!ev.sender || room.name === ev.sender.name) {
|
if (!ev.sender || room.name === ev.sender.name) {
|
||||||
title = room.name;
|
title = room.name;
|
||||||
// notificationMessageForEvent includes sender,
|
// notificationMessageForEvent includes sender, but we already have the sender here
|
||||||
// but we already have the sender here
|
const msgType = ev.getContent().msgtype;
|
||||||
if (ev.getContent().body && !msgTypeHandlers.hasOwnProperty(ev.getContent().msgtype)) {
|
if (ev.getContent().body && (!msgType || !msgTypeHandlers.hasOwnProperty(msgType))) {
|
||||||
msg = ev.getContent().body;
|
msg = ev.getContent().body;
|
||||||
}
|
}
|
||||||
} else if (ev.getType() === "m.room.member") {
|
} else if (ev.getType() === "m.room.member") {
|
||||||
|
@ -145,9 +146,9 @@ class NotifierClass {
|
||||||
title = room.name;
|
title = room.name;
|
||||||
} else if (ev.sender) {
|
} else if (ev.sender) {
|
||||||
title = ev.sender.name + " (" + room.name + ")";
|
title = ev.sender.name + " (" + room.name + ")";
|
||||||
// notificationMessageForEvent includes sender,
|
// notificationMessageForEvent includes sender, but we've just out sender in the title
|
||||||
// but we've just out sender in the title
|
const msgType = ev.getContent().msgtype;
|
||||||
if (ev.getContent().body && !msgTypeHandlers.hasOwnProperty(ev.getContent().msgtype)) {
|
if (ev.getContent().body && (!msgType || !msgTypeHandlers.hasOwnProperty(msgType))) {
|
||||||
msg = ev.getContent().body;
|
msg = ev.getContent().body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +162,7 @@ class NotifierClass {
|
||||||
avatarUrl = Avatar.avatarUrlForMember(ev.sender, 40, 40, "crop");
|
avatarUrl = Avatar.avatarUrlForMember(ev.sender, 40, 40, "crop");
|
||||||
}
|
}
|
||||||
|
|
||||||
const notif = plaf.displayNotification(title, msg, avatarUrl, room, ev);
|
const notif = plaf.displayNotification(title, msg!, avatarUrl, room, ev);
|
||||||
|
|
||||||
// if displayNotification returns non-null, the platform supports
|
// if displayNotification returns non-null, the platform supports
|
||||||
// clearing notifications later, so keep track of this.
|
// clearing notifications later, so keep track of this.
|
||||||
|
|
|
@ -16,6 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||||
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
||||||
|
|
||||||
import { MatrixClientPeg } from "./MatrixClientPeg";
|
import { MatrixClientPeg } from "./MatrixClientPeg";
|
||||||
import AliasCustomisations from "./customisations/Alias";
|
import AliasCustomisations from "./customisations/Alias";
|
||||||
|
@ -109,8 +110,8 @@ export async function setDMRoom(roomId: string, userId: string | null): Promise<
|
||||||
* @returns {string} User ID of the user that the room is probably a DM with
|
* @returns {string} User ID of the user that the room is probably a DM with
|
||||||
*/
|
*/
|
||||||
function guessDMRoomTargetId(room: Room, myUserId: string): string {
|
function guessDMRoomTargetId(room: Room, myUserId: string): string {
|
||||||
let oldestTs;
|
let oldestTs: number | undefined;
|
||||||
let oldestUser;
|
let oldestUser: RoomMember | undefined;
|
||||||
|
|
||||||
// Pick the joined user who's been here longest (and isn't us),
|
// Pick the joined user who's been here longest (and isn't us),
|
||||||
for (const user of room.getJoinedMembers()) {
|
for (const user of room.getJoinedMembers()) {
|
||||||
|
|
|
@ -858,8 +858,7 @@ async function readEvents(
|
||||||
|
|
||||||
const onMessage = function (event: MessageEvent<any>): void {
|
const onMessage = function (event: MessageEvent<any>): void {
|
||||||
if (!event.origin) {
|
if (!event.origin) {
|
||||||
// stupid chrome
|
// @ts-ignore - stupid chrome
|
||||||
// @ts-ignore
|
|
||||||
event.origin = event.originalEvent.origin;
|
event.origin = event.originalEvent.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,10 +866,10 @@ const onMessage = function (event: MessageEvent<any>): void {
|
||||||
// This means the URL could contain a path (like /develop) and still be used
|
// This means the URL could contain a path (like /develop) and still be used
|
||||||
// to validate event origins, which do not specify paths.
|
// to validate event origins, which do not specify paths.
|
||||||
// (See https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)
|
// (See https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)
|
||||||
let configUrl;
|
let configUrl: URL | undefined;
|
||||||
try {
|
try {
|
||||||
if (!openManagerUrl) openManagerUrl = IntegrationManagers.sharedInstance().getPrimaryManager().uiUrl;
|
if (!openManagerUrl) openManagerUrl = IntegrationManagers.sharedInstance().getPrimaryManager()?.uiUrl;
|
||||||
configUrl = new URL(openManagerUrl);
|
configUrl = new URL(openManagerUrl!);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// No integrations UI URL, ignore silently.
|
// No integrations UI URL, ignore silently.
|
||||||
return;
|
return;
|
||||||
|
@ -987,7 +986,7 @@ const onMessage = function (event: MessageEvent<any>): void {
|
||||||
};
|
};
|
||||||
|
|
||||||
let listenerCount = 0;
|
let listenerCount = 0;
|
||||||
let openManagerUrl: string | null = null;
|
let openManagerUrl: string | undefined;
|
||||||
|
|
||||||
export function startListening(): void {
|
export function startListening(): void {
|
||||||
if (listenerCount === 0) {
|
if (listenerCount === 0) {
|
||||||
|
|
|
@ -87,9 +87,10 @@ function makeInputToKey(keyInfo: ISecretStorageKeyInfo): (keyParams: KeyParams)
|
||||||
return async ({ passphrase, recoveryKey }): Promise<Uint8Array> => {
|
return async ({ passphrase, recoveryKey }): Promise<Uint8Array> => {
|
||||||
if (passphrase) {
|
if (passphrase) {
|
||||||
return deriveKey(passphrase, keyInfo.passphrase.salt, keyInfo.passphrase.iterations);
|
return deriveKey(passphrase, keyInfo.passphrase.salt, keyInfo.passphrase.iterations);
|
||||||
} else {
|
} else if (recoveryKey) {
|
||||||
return decodeRecoveryKey(recoveryKey);
|
return decodeRecoveryKey(recoveryKey);
|
||||||
}
|
}
|
||||||
|
throw new Error("Invalid input, passphrase or recoveryKey need to be provided");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,10 @@ function successSync(value: any): RunResult {
|
||||||
|
|
||||||
const isCurrentLocalRoom = (): boolean => {
|
const isCurrentLocalRoom = (): boolean => {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const room = cli.getRoom(SdkContextClass.instance.roomViewStore.getRoomId());
|
const roomId = SdkContextClass.instance.roomViewStore.getRoomId();
|
||||||
|
if (!roomId) return false;
|
||||||
|
const room = cli.getRoom(roomId);
|
||||||
|
if (!room) return false;
|
||||||
return isLocalRoom(room);
|
return isLocalRoom(room);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -873,7 +876,9 @@ export const Commands = [
|
||||||
description: _td("Define the power level of a user"),
|
description: _td("Define the power level of a user"),
|
||||||
isEnabled(): boolean {
|
isEnabled(): boolean {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const room = cli.getRoom(SdkContextClass.instance.roomViewStore.getRoomId());
|
const roomId = SdkContextClass.instance.roomViewStore.getRoomId();
|
||||||
|
if (!roomId) return false;
|
||||||
|
const room = cli.getRoom(roomId);
|
||||||
return (
|
return (
|
||||||
!!room?.currentState.maySendStateEvent(EventType.RoomPowerLevels, cli.getUserId()!) &&
|
!!room?.currentState.maySendStateEvent(EventType.RoomPowerLevels, cli.getUserId()!) &&
|
||||||
!isLocalRoom(room)
|
!isLocalRoom(room)
|
||||||
|
@ -897,7 +902,10 @@ export const Commands = [
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const member = room.getMember(userId);
|
const member = room.getMember(userId);
|
||||||
if (!member || getEffectiveMembership(member.membership) === EffectiveMembership.Leave) {
|
if (
|
||||||
|
!member?.membership ||
|
||||||
|
getEffectiveMembership(member.membership) === EffectiveMembership.Leave
|
||||||
|
) {
|
||||||
return reject(newTranslatableError("Could not find user in room"));
|
return reject(newTranslatableError("Could not find user in room"));
|
||||||
}
|
}
|
||||||
const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", "");
|
const powerLevelEvent = room.currentState.getStateEvents("m.room.power_levels", "");
|
||||||
|
@ -916,7 +924,9 @@ export const Commands = [
|
||||||
description: _td("Deops user with given id"),
|
description: _td("Deops user with given id"),
|
||||||
isEnabled(): boolean {
|
isEnabled(): boolean {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const room = cli.getRoom(SdkContextClass.instance.roomViewStore.getRoomId());
|
const roomId = SdkContextClass.instance.roomViewStore.getRoomId();
|
||||||
|
if (!roomId) return false;
|
||||||
|
const room = cli.getRoom(roomId);
|
||||||
return (
|
return (
|
||||||
!!room?.currentState.maySendStateEvent(EventType.RoomPowerLevels, cli.getUserId()!) &&
|
!!room?.currentState.maySendStateEvent(EventType.RoomPowerLevels, cli.getUserId()!) &&
|
||||||
!isLocalRoom(room)
|
!isLocalRoom(room)
|
||||||
|
@ -973,11 +983,12 @@ export const Commands = [
|
||||||
// We use parse5, which doesn't render/create a DOM node. It instead runs
|
// We use parse5, which doesn't render/create a DOM node. It instead runs
|
||||||
// some superfast regex over the text so we don't have to.
|
// some superfast regex over the text so we don't have to.
|
||||||
const embed = parseHtml(widgetUrl);
|
const embed = parseHtml(widgetUrl);
|
||||||
if (embed && embed.childNodes && embed.childNodes.length === 1) {
|
if (embed?.childNodes?.length === 1) {
|
||||||
const iframe = embed.childNodes[0] as ChildElement;
|
const iframe = embed.childNodes[0] as ChildElement;
|
||||||
if (iframe.tagName.toLowerCase() === "iframe" && iframe.attrs) {
|
if (iframe.tagName.toLowerCase() === "iframe" && iframe.attrs) {
|
||||||
const srcAttr = iframe.attrs.find((a) => a.name === "src");
|
const srcAttr = iframe.attrs.find((a) => a.name === "src");
|
||||||
logger.log("Pulling URL out of iframe (embed code)");
|
logger.log("Pulling URL out of iframe (embed code)");
|
||||||
|
if (!srcAttr) return reject(newTranslatableError("iframe has no src attribute"));
|
||||||
widgetUrl = srcAttr.value;
|
widgetUrl = srcAttr.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1240,6 +1251,7 @@ export const Commands = [
|
||||||
}
|
}
|
||||||
|
|
||||||
const roomId = await ensureDMExists(MatrixClientPeg.get(), userId);
|
const roomId = await ensureDMExists(MatrixClientPeg.get(), userId);
|
||||||
|
if (!roomId) throw new Error("Failed to ensure DM exists");
|
||||||
|
|
||||||
dis.dispatch<ViewRoomPayload>({
|
dis.dispatch<ViewRoomPayload>({
|
||||||
action: Action.ViewRoom,
|
action: Action.ViewRoom,
|
||||||
|
@ -1267,6 +1279,8 @@ export const Commands = [
|
||||||
(async (): Promise<void> => {
|
(async (): Promise<void> => {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const roomId = await ensureDMExists(cli, userId);
|
const roomId = await ensureDMExists(cli, userId);
|
||||||
|
if (!roomId) throw new Error("Failed to ensure DM exists");
|
||||||
|
|
||||||
dis.dispatch<ViewRoomPayload>({
|
dis.dispatch<ViewRoomPayload>({
|
||||||
action: Action.ViewRoom,
|
action: Action.ViewRoom,
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
|
@ -1323,6 +1337,7 @@ export const Commands = [
|
||||||
isEnabled: () => !isCurrentLocalRoom(),
|
isEnabled: () => !isCurrentLocalRoom(),
|
||||||
runFn: function (roomId, args) {
|
runFn: function (roomId, args) {
|
||||||
const room = MatrixClientPeg.get().getRoom(roomId);
|
const room = MatrixClientPeg.get().getRoom(roomId);
|
||||||
|
if (!room) return reject(newTranslatableError("Could not find room"));
|
||||||
return success(guessAndSetDMRoom(room, true));
|
return success(guessAndSetDMRoom(room, true));
|
||||||
},
|
},
|
||||||
renderingTypes: [TimelineRenderingType.Room],
|
renderingTypes: [TimelineRenderingType.Room],
|
||||||
|
@ -1334,6 +1349,7 @@ export const Commands = [
|
||||||
isEnabled: () => !isCurrentLocalRoom(),
|
isEnabled: () => !isCurrentLocalRoom(),
|
||||||
runFn: function (roomId, args) {
|
runFn: function (roomId, args) {
|
||||||
const room = MatrixClientPeg.get().getRoom(roomId);
|
const room = MatrixClientPeg.get().getRoom(roomId);
|
||||||
|
if (!room) return reject(newTranslatableError("Could not find room"));
|
||||||
return success(guessAndSetDMRoom(room, false));
|
return success(guessAndSetDMRoom(room, false));
|
||||||
},
|
},
|
||||||
renderingTypes: [TimelineRenderingType.Room],
|
renderingTypes: [TimelineRenderingType.Room],
|
||||||
|
|
|
@ -201,7 +201,7 @@ export async function dialogTermsInteractionCallback(
|
||||||
);
|
);
|
||||||
|
|
||||||
const [done, _agreedUrls] = await finished;
|
const [done, _agreedUrls] = await finished;
|
||||||
if (!done) {
|
if (!done || !_agreedUrls) {
|
||||||
throw new TermsNotSignedError();
|
throw new TermsNotSignedError();
|
||||||
}
|
}
|
||||||
return _agreedUrls;
|
return _agreedUrls;
|
||||||
|
|
|
@ -170,7 +170,7 @@ export class PlaybackQueue {
|
||||||
// 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
|
||||||
// and update our current playback ID.
|
// and update our current playback ID.
|
||||||
// noinspection JSIgnoredPromiseFromCall
|
// noinspection JSIgnoredPromiseFromCall
|
||||||
instance.play();
|
instance?.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -452,6 +452,7 @@ export async function ensureDMExists(client: MatrixClient, userId: string): Prom
|
||||||
}
|
}
|
||||||
|
|
||||||
roomId = await createRoom({ encryption, dmUserId: userId, spinner: false, andView: false });
|
roomId = await createRoom({ encryption, dmUserId: userId, spinner: false, andView: false });
|
||||||
|
if (!roomId) return null;
|
||||||
await waitForMember(client, roomId, userId);
|
await waitForMember(client, roomId, userId);
|
||||||
}
|
}
|
||||||
return roomId;
|
return roomId;
|
||||||
|
|
|
@ -143,8 +143,9 @@ export const usePublicRoomDirectory = (): {
|
||||||
|
|
||||||
let roomServer: string = myHomeserver;
|
let roomServer: string = myHomeserver;
|
||||||
if (
|
if (
|
||||||
SdkConfig.getObject("room_directory")?.get("servers")?.includes(lsRoomServer) ||
|
lsRoomServer &&
|
||||||
SettingsStore.getValue("room_directory_servers")?.includes(lsRoomServer)
|
(SdkConfig.getObject("room_directory")?.get("servers")?.includes(lsRoomServer) ||
|
||||||
|
SettingsStore.getValue("room_directory_servers")?.includes(lsRoomServer))
|
||||||
) {
|
) {
|
||||||
roomServer = lsRoomServer!;
|
roomServer = lsRoomServer!;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ import { normalize } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||||
|
|
||||||
export const useSpaceResults = (space?: Room, query?: string): [IHierarchyRoom[], boolean] => {
|
export const useSpaceResults = (space: Room | undefined, query: string): [IHierarchyRoom[], boolean] => {
|
||||||
const [rooms, setRooms] = useState<IHierarchyRoom[]>([]);
|
const [rooms, setRooms] = useState<IHierarchyRoom[]>([]);
|
||||||
const [hierarchy, setHierarchy] = useState<RoomHierarchy>();
|
const [hierarchy, setHierarchy] = useState<RoomHierarchy>();
|
||||||
|
|
||||||
const resetHierarchy = useCallback(() => {
|
const resetHierarchy = useCallback(() => {
|
||||||
setHierarchy(space ? new RoomHierarchy(space, 50) : null);
|
setHierarchy(space ? new RoomHierarchy(space, 50) : undefined);
|
||||||
}, [space]);
|
}, [space]);
|
||||||
useEffect(resetHierarchy, [resetHierarchy]);
|
useEffect(resetHierarchy, [resetHierarchy]);
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ export const useSpaceResults = (space?: Room, query?: string): [IHierarchyRoom[]
|
||||||
while (hierarchy?.canLoadMore && !unmounted && space === hierarchy.root) {
|
while (hierarchy?.canLoadMore && !unmounted && space === hierarchy.root) {
|
||||||
await hierarchy.load();
|
await hierarchy.load();
|
||||||
if (hierarchy.canLoadMore) hierarchy.load(); // start next load so that the loading attribute is right
|
if (hierarchy.canLoadMore) hierarchy.load(); // start next load so that the loading attribute is right
|
||||||
setRooms(hierarchy.rooms);
|
setRooms(hierarchy.rooms!);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
|
@ -453,6 +453,7 @@
|
||||||
"Opens the Developer Tools dialog": "Opens the Developer Tools dialog",
|
"Opens the Developer Tools dialog": "Opens the Developer Tools dialog",
|
||||||
"Adds a custom widget by URL to the room": "Adds a custom widget by URL to the room",
|
"Adds a custom widget by URL to the room": "Adds a custom widget by URL to the room",
|
||||||
"Please supply a widget URL or embed code": "Please supply a widget URL or embed code",
|
"Please supply a widget URL or embed code": "Please supply a widget URL or embed code",
|
||||||
|
"iframe has no src attribute": "iframe has no src attribute",
|
||||||
"Please supply a https:// or http:// widget URL": "Please supply a https:// or http:// widget URL",
|
"Please supply a https:// or http:// widget URL": "Please supply a https:// or http:// widget URL",
|
||||||
"You cannot modify widgets in this room.": "You cannot modify widgets in this room.",
|
"You cannot modify widgets in this room.": "You cannot modify widgets in this room.",
|
||||||
"Verifies a user, session, and pubkey tuple": "Verifies a user, session, and pubkey tuple",
|
"Verifies a user, session, and pubkey tuple": "Verifies a user, session, and pubkey tuple",
|
||||||
|
@ -478,6 +479,7 @@
|
||||||
"No active call in this room": "No active call in this room",
|
"No active call in this room": "No active call in this room",
|
||||||
"Takes the call in the current room off hold": "Takes the call in the current room off hold",
|
"Takes the call in the current room off hold": "Takes the call in the current room off hold",
|
||||||
"Converts the room to a DM": "Converts the room to a DM",
|
"Converts the room to a DM": "Converts the room to a DM",
|
||||||
|
"Could not find room": "Could not find room",
|
||||||
"Converts the DM to a room": "Converts the DM to a room",
|
"Converts the DM to a room": "Converts the DM to a room",
|
||||||
"Displays action": "Displays action",
|
"Displays action": "Displays action",
|
||||||
"Someone": "Someone",
|
"Someone": "Someone",
|
||||||
|
|
|
@ -21,7 +21,7 @@ import { MatrixGlob } from "../utils/MatrixGlob";
|
||||||
export const RECOMMENDATION_BAN = "m.ban";
|
export const RECOMMENDATION_BAN = "m.ban";
|
||||||
export const RECOMMENDATION_BAN_TYPES = [RECOMMENDATION_BAN, "org.matrix.mjolnir.ban"];
|
export const RECOMMENDATION_BAN_TYPES = [RECOMMENDATION_BAN, "org.matrix.mjolnir.ban"];
|
||||||
|
|
||||||
export function recommendationToStable(recommendation: string, unstable = true): string {
|
export function recommendationToStable(recommendation: string, unstable = true): string | null {
|
||||||
if (RECOMMENDATION_BAN_TYPES.includes(recommendation)) {
|
if (RECOMMENDATION_BAN_TYPES.includes(recommendation)) {
|
||||||
return unstable ? RECOMMENDATION_BAN_TYPES[RECOMMENDATION_BAN_TYPES.length - 1] : RECOMMENDATION_BAN;
|
return unstable ? RECOMMENDATION_BAN_TYPES[RECOMMENDATION_BAN_TYPES.length - 1] : RECOMMENDATION_BAN;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ export function recommendationToStable(recommendation: string, unstable = true):
|
||||||
export class ListRule {
|
export class ListRule {
|
||||||
private _glob: MatrixGlob;
|
private _glob: MatrixGlob;
|
||||||
private readonly _entity: string;
|
private readonly _entity: string;
|
||||||
private readonly _action: string;
|
private readonly _action: string | null;
|
||||||
private readonly _reason: string;
|
private readonly _reason: string;
|
||||||
private readonly _kind: string;
|
private readonly _kind: string;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ export class ListRule {
|
||||||
return this._kind;
|
return this._kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get recommendation(): string {
|
public get recommendation(): string | null {
|
||||||
return this._action;
|
return this._action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ export class ProxiedModuleApi implements ModuleApi {
|
||||||
},
|
},
|
||||||
"mx_CompoundDialog",
|
"mx_CompoundDialog",
|
||||||
).finished.then(([didOkOrSubmit, model]) => {
|
).finished.then(([didOkOrSubmit, model]) => {
|
||||||
resolve({ didOkOrSubmit, model: model as M });
|
resolve({ didOkOrSubmit: !!didOkOrSubmit, model: model as M });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,7 @@ export class ProxiedModuleApi implements ModuleApi {
|
||||||
displayName?: string,
|
displayName?: string,
|
||||||
): Promise<AccountAuthInfo> {
|
): Promise<AccountAuthInfo> {
|
||||||
const hsUrl = SdkConfig.get("validated_server_config")?.hsUrl;
|
const hsUrl = SdkConfig.get("validated_server_config")?.hsUrl;
|
||||||
|
if (!hsUrl) throw new Error("Could not get homeserver url");
|
||||||
const client = Matrix.createClient({ baseUrl: hsUrl });
|
const client = Matrix.createClient({ baseUrl: hsUrl });
|
||||||
const deviceName =
|
const deviceName =
|
||||||
SdkConfig.get("default_device_display_name") || PlatformPeg.get()?.getDefaultDeviceDisplayName();
|
SdkConfig.get("default_device_display_name") || PlatformPeg.get()?.getDefaultDeviceDisplayName();
|
||||||
|
|
|
@ -107,8 +107,8 @@ export class ContentRules {
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const kind in rulesets.global) {
|
for (const kind in rulesets.global) {
|
||||||
for (let i = 0; i < Object.keys(rulesets.global[kind as keyof PushRuleSet]).length; ++i) {
|
for (let i = 0; i < Object.keys(rulesets.global[kind as keyof PushRuleSet]!).length; ++i) {
|
||||||
const r = rulesets.global[kind as keyof PushRuleSet][i] as IAnnotatedPushRule;
|
const r = rulesets.global[kind as keyof PushRuleSet]![i] as IAnnotatedPushRule;
|
||||||
|
|
||||||
// check it's not a default rule
|
// check it's not a default rule
|
||||||
if (r.rule_id[0] === "." || kind !== PushRuleKind.ContentSpecific) {
|
if (r.rule_id[0] === "." || kind !== PushRuleKind.ContentSpecific) {
|
||||||
|
|
|
@ -89,7 +89,7 @@ async function getStorageContext(): Promise<StorageContext> {
|
||||||
if (estimate.usageDetails) {
|
if (estimate.usageDetails) {
|
||||||
const usageDetails: string[] = [];
|
const usageDetails: string[] = [];
|
||||||
Object.keys(estimate.usageDetails).forEach((k) => {
|
Object.keys(estimate.usageDetails).forEach((k) => {
|
||||||
usageDetails.push(`${k}: ${String(estimate.usageDetails[k])}`);
|
usageDetails.push(`${k}: ${String(estimate.usageDetails![k])}`);
|
||||||
});
|
});
|
||||||
result[`storageManager_usage`] = usageDetails.join(", ");
|
result[`storageManager_usage`] = usageDetails.join(", ");
|
||||||
}
|
}
|
||||||
|
@ -137,9 +137,9 @@ async function getCryptoContext(client: MatrixClient): Promise<CryptoContext> {
|
||||||
),
|
),
|
||||||
cross_signing_key: crossSigning.getId()!,
|
cross_signing_key: crossSigning.getId()!,
|
||||||
cross_signing_privkey_in_secret_storage: String(!!(await crossSigning.isStoredInSecretStorage(secretStorage))),
|
cross_signing_privkey_in_secret_storage: String(!!(await crossSigning.isStoredInSecretStorage(secretStorage))),
|
||||||
cross_signing_master_privkey_cached: String(!!(pkCache && (await pkCache.getCrossSigningKeyCache("master")))),
|
cross_signing_master_privkey_cached: String(!!(pkCache && (await pkCache.getCrossSigningKeyCache?.("master")))),
|
||||||
cross_signing_user_signing_privkey_cached: String(
|
cross_signing_user_signing_privkey_cached: String(
|
||||||
!!(pkCache && (await pkCache.getCrossSigningKeyCache("user_signing"))),
|
!!(pkCache && (await pkCache.getCrossSigningKeyCache?.("user_signing"))),
|
||||||
),
|
),
|
||||||
secret_storage_ready: String(await client.isSecretStorageReady()),
|
secret_storage_ready: String(await client.isSecretStorageReady()),
|
||||||
secret_storage_key_in_account: String(!!(await secretStorage.hasKey())),
|
secret_storage_key_in_account: String(!!(await secretStorage.hasKey())),
|
||||||
|
@ -151,7 +151,7 @@ async function getCryptoContext(client: MatrixClient): Promise<CryptoContext> {
|
||||||
|
|
||||||
function getDeviceContext(client: MatrixClient): DeviceContext {
|
function getDeviceContext(client: MatrixClient): DeviceContext {
|
||||||
const result: DeviceContext = {
|
const result: DeviceContext = {
|
||||||
device_id: client?.deviceId,
|
device_id: client?.deviceId ?? undefined,
|
||||||
mx_local_settings: localStorage.getItem("mx_local_settings"),
|
mx_local_settings: localStorage.getItem("mx_local_settings"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ export default class ServerSupportUnstableFeatureController extends MatrixClient
|
||||||
if (!v === this.enabled) return;
|
if (!v === this.enabled) return;
|
||||||
this.enabled = !v;
|
this.enabled = !v;
|
||||||
const level = SettingsStore.firstSupportedLevel(this.settingName);
|
const level = SettingsStore.firstSupportedLevel(this.settingName);
|
||||||
|
if (!level) return;
|
||||||
const settingValue = SettingsStore.getValue(this.settingName, null);
|
const settingValue = SettingsStore.getValue(this.settingName, null);
|
||||||
this.watchers.notifyUpdate(this.settingName, null, level, settingValue);
|
this.watchers.notifyUpdate(this.settingName, null, level, settingValue);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +62,7 @@ export default class ServerSupportUnstableFeatureController extends MatrixClient
|
||||||
|
|
||||||
public getValueOverride(
|
public getValueOverride(
|
||||||
level: SettingLevel,
|
level: SettingLevel,
|
||||||
roomId: string,
|
roomId: string | null,
|
||||||
calculatedValue: any,
|
calculatedValue: any,
|
||||||
calculatedAtLevel: SettingLevel | null,
|
calculatedAtLevel: SettingLevel | null,
|
||||||
): any {
|
): any {
|
||||||
|
|
|
@ -39,9 +39,17 @@ interface IState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class IncomingLegacyCallToast extends React.Component<IProps, IState> {
|
export default class IncomingLegacyCallToast extends React.Component<IProps, IState> {
|
||||||
|
private readonly roomId: string;
|
||||||
|
|
||||||
public constructor(props: IProps) {
|
public constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
const roomId = LegacyCallHandler.instance.roomIdForCall(this.props.call);
|
||||||
|
if (!roomId) {
|
||||||
|
throw new Error("Unable to find room for incoming call");
|
||||||
|
}
|
||||||
|
this.roomId = roomId;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
silenced: LegacyCallHandler.instance.isCallSilenced(this.props.call.callId),
|
silenced: LegacyCallHandler.instance.isCallSilenced(this.props.call.callId),
|
||||||
};
|
};
|
||||||
|
@ -67,12 +75,12 @@ export default class IncomingLegacyCallToast extends React.Component<IProps, ISt
|
||||||
|
|
||||||
private onAnswerClick = (e: React.MouseEvent): void => {
|
private onAnswerClick = (e: React.MouseEvent): void => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
LegacyCallHandler.instance.answerCall(LegacyCallHandler.instance.roomIdForCall(this.props.call));
|
LegacyCallHandler.instance.answerCall(this.roomId);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onRejectClick = (e: React.MouseEvent): void => {
|
private onRejectClick = (e: React.MouseEvent): void => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
LegacyCallHandler.instance.hangupOrReject(LegacyCallHandler.instance.roomIdForCall(this.props.call), true);
|
LegacyCallHandler.instance.hangupOrReject(this.roomId, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onSilenceClick = (e: React.MouseEvent): void => {
|
private onSilenceClick = (e: React.MouseEvent): void => {
|
||||||
|
@ -84,9 +92,8 @@ export default class IncomingLegacyCallToast extends React.Component<IProps, ISt
|
||||||
};
|
};
|
||||||
|
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
const call = this.props.call;
|
const room = MatrixClientPeg.get().getRoom(this.roomId);
|
||||||
const room = MatrixClientPeg.get().getRoom(LegacyCallHandler.instance.roomIdForCall(call));
|
const isVoice = this.props.call.type === CallType.Voice;
|
||||||
const isVoice = call.type === CallType.Voice;
|
|
||||||
const callForcedSilent = LegacyCallHandler.instance.isForcedSilent();
|
const callForcedSilent = LegacyCallHandler.instance.isForcedSilent();
|
||||||
|
|
||||||
let silenceButtonTooltip = this.state.silenced ? _t("Sound on") : _t("Silence call");
|
let silenceButtonTooltip = this.state.silenced ? _t("Sound on") : _t("Silence call");
|
||||||
|
|
|
@ -50,11 +50,11 @@ export const getClientInformationEventType = (deviceId: string): string => `${cl
|
||||||
export const recordClientInformation = async (
|
export const recordClientInformation = async (
|
||||||
matrixClient: MatrixClient,
|
matrixClient: MatrixClient,
|
||||||
sdkConfig: IConfigOptions,
|
sdkConfig: IConfigOptions,
|
||||||
platform: BasePlatform,
|
platform?: BasePlatform,
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const deviceId = matrixClient.getDeviceId()!;
|
const deviceId = matrixClient.getDeviceId()!;
|
||||||
const { brand } = sdkConfig;
|
const { brand } = sdkConfig;
|
||||||
const version = await platform.getAppVersion();
|
const version = await platform?.getAppVersion();
|
||||||
const type = getClientInformationEventType(deviceId);
|
const type = getClientInformationEventType(deviceId);
|
||||||
const url = formatUrl();
|
const url = formatUrl();
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ export class Jitsi {
|
||||||
this.update(cli.getClientWellKnown());
|
this.update(cli.getClientWellKnown());
|
||||||
}
|
}
|
||||||
|
|
||||||
private update = async (discoveryResponse: IClientWellKnown): Promise<any> => {
|
private update = async (discoveryResponse?: IClientWellKnown): Promise<any> => {
|
||||||
// Start with a default of the config's domain
|
// Start with a default of the config's domain
|
||||||
let domain = SdkConfig.getObject("jitsi")?.get("preferred_domain") || "meet.element.io";
|
let domain = SdkConfig.getObject("jitsi")?.get("preferred_domain") || "meet.element.io";
|
||||||
|
|
||||||
|
|
|
@ -412,9 +412,9 @@ describe("Spotlight Dialog", () => {
|
||||||
jest.advanceTimersByTime(200);
|
jest.advanceTimersByTime(200);
|
||||||
await flushPromisesWithFakeTimers();
|
await flushPromisesWithFakeTimers();
|
||||||
|
|
||||||
expect(screen.getByText(potatoRoom.name)).toBeInTheDocument();
|
expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument();
|
||||||
expect(screen.queryByText(nsfwTopicRoom.name)).not.toBeInTheDocument();
|
expect(screen.queryByText(nsfwTopicRoom.name!)).not.toBeInTheDocument();
|
||||||
expect(screen.queryByText(nsfwTopicRoom.name)).not.toBeInTheDocument();
|
expect(screen.queryByText(nsfwTopicRoom.name!)).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("displays rooms with nsfw keywords in results when showNsfwPublicRooms is truthy", async () => {
|
it("displays rooms with nsfw keywords in results when showNsfwPublicRooms is truthy", async () => {
|
||||||
|
@ -425,9 +425,9 @@ describe("Spotlight Dialog", () => {
|
||||||
jest.advanceTimersByTime(200);
|
jest.advanceTimersByTime(200);
|
||||||
await flushPromisesWithFakeTimers();
|
await flushPromisesWithFakeTimers();
|
||||||
|
|
||||||
expect(screen.getByText(nsfwTopicRoom.name)).toBeInTheDocument();
|
expect(screen.getByText(nsfwTopicRoom.name!)).toBeInTheDocument();
|
||||||
expect(screen.getByText(nsfwNameRoom.name)).toBeInTheDocument();
|
expect(screen.getByText(nsfwNameRoom.name!)).toBeInTheDocument();
|
||||||
expect(screen.getByText(potatoRoom.name)).toBeInTheDocument();
|
expect(screen.getByText(potatoRoom.name!)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -328,7 +328,7 @@ describe("<DeviceItem />", () => {
|
||||||
it("with unverified user and device, displays button without a label", () => {
|
it("with unverified user and device, displays button without a label", () => {
|
||||||
renderComponent();
|
renderComponent();
|
||||||
|
|
||||||
expect(screen.getByRole("button", { name: device.getDisplayName() })).toBeInTheDocument;
|
expect(screen.getByRole("button", { name: device.getDisplayName()! })).toBeInTheDocument;
|
||||||
expect(screen.queryByText(/trusted/i)).not.toBeInTheDocument();
|
expect(screen.queryByText(/trusted/i)).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ describe("<DeviceItem />", () => {
|
||||||
setMockDeviceTrust(true);
|
setMockDeviceTrust(true);
|
||||||
renderComponent();
|
renderComponent();
|
||||||
|
|
||||||
expect(screen.getByText(device.getDisplayName())).toBeInTheDocument();
|
expect(screen.getByText(device.getDisplayName()!)).toBeInTheDocument();
|
||||||
expect(screen.queryByText(/trusted/)).not.toBeInTheDocument();
|
expect(screen.queryByText(/trusted/)).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ describe("<DeviceItem />", () => {
|
||||||
|
|
||||||
// expect to see no button in this case
|
// expect to see no button in this case
|
||||||
expect(screen.queryByRole("button")).not.toBeInTheDocument;
|
expect(screen.queryByRole("button")).not.toBeInTheDocument;
|
||||||
expect(screen.getByText(device.getDisplayName())).toBeInTheDocument();
|
expect(screen.getByText(device.getDisplayName()!)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("with verified user and device, displays no button and a 'Trusted' label", () => {
|
it("with verified user and device, displays no button and a 'Trusted' label", () => {
|
||||||
|
@ -365,7 +365,7 @@ describe("<DeviceItem />", () => {
|
||||||
renderComponent();
|
renderComponent();
|
||||||
|
|
||||||
expect(screen.queryByRole("button")).not.toBeInTheDocument;
|
expect(screen.queryByRole("button")).not.toBeInTheDocument;
|
||||||
expect(screen.getByText(device.getDisplayName())).toBeInTheDocument();
|
expect(screen.getByText(device.getDisplayName()!)).toBeInTheDocument();
|
||||||
expect(screen.getByText("Trusted")).toBeInTheDocument();
|
expect(screen.getByText("Trusted")).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ describe("<DeviceItem />", () => {
|
||||||
mockClient.getUser.mockReturnValueOnce(null);
|
mockClient.getUser.mockReturnValueOnce(null);
|
||||||
renderComponent();
|
renderComponent();
|
||||||
|
|
||||||
const button = screen.getByRole("button", { name: device.getDisplayName() });
|
const button = screen.getByRole("button", { name: device.getDisplayName()! });
|
||||||
expect(button).toBeInTheDocument;
|
expect(button).toBeInTheDocument;
|
||||||
await userEvent.click(button);
|
await userEvent.click(button);
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ describe("<DeviceItem />", () => {
|
||||||
mockClient.isGuest.mockReturnValueOnce(true);
|
mockClient.isGuest.mockReturnValueOnce(true);
|
||||||
renderComponent();
|
renderComponent();
|
||||||
|
|
||||||
const button = screen.getByRole("button", { name: device.getDisplayName() });
|
const button = screen.getByRole("button", { name: device.getDisplayName()! });
|
||||||
expect(button).toBeInTheDocument;
|
expect(button).toBeInTheDocument;
|
||||||
await userEvent.click(button);
|
await userEvent.click(button);
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ describe("SetupEncryptionStore", () => {
|
||||||
const makeRequest = jest.fn();
|
const makeRequest = jest.fn();
|
||||||
client.hasSecretStorageKey.mockResolvedValue(true);
|
client.hasSecretStorageKey.mockResolvedValue(true);
|
||||||
client.bootstrapCrossSigning.mockImplementation(async (opts: IBootstrapCrossSigningOpts) => {
|
client.bootstrapCrossSigning.mockImplementation(async (opts: IBootstrapCrossSigningOpts) => {
|
||||||
await opts?.authUploadDeviceSigningKeys(makeRequest);
|
await opts?.authUploadDeviceSigningKeys?.(makeRequest);
|
||||||
});
|
});
|
||||||
mocked(accessSecretStorage).mockImplementation(async (func: () => Promise<void>) => {
|
mocked(accessSecretStorage).mockImplementation(async (func: () => Promise<void>) => {
|
||||||
await func();
|
await func();
|
||||||
|
|
Loading…
Reference in a new issue