Apply corrections identified by SonarQube (#8457)

This commit is contained in:
Michael Telatynski 2022-05-03 22:04:37 +01:00 committed by GitHub
parent 99cb83a9df
commit 964c60d086
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
73 changed files with 211 additions and 232 deletions

View file

@ -380,11 +380,11 @@ export default class ContentMessages {
const tooBigFiles = []; const tooBigFiles = [];
const okFiles = []; const okFiles = [];
for (let i = 0; i < files.length; ++i) { for (const file of files) {
if (this.isFileSizeAcceptable(files[i])) { if (this.isFileSizeAcceptable(file)) {
okFiles.push(files[i]); okFiles.push(file);
} else { } else {
tooBigFiles.push(files[i]); tooBigFiles.push(file);
} }
} }
@ -450,13 +450,7 @@ export default class ContentMessages {
} }
public cancelUpload(promise: Promise<any>, matrixClient: MatrixClient): void { public cancelUpload(promise: Promise<any>, matrixClient: MatrixClient): void {
let upload: IUpload; const upload = this.inprogress.find(item => item.promise === promise);
for (let i = 0; i < this.inprogress.length; ++i) {
if (this.inprogress[i].promise === promise) {
upload = this.inprogress[i];
break;
}
}
if (upload) { if (upload) {
upload.canceled = true; upload.canceled = true;
matrixClient.cancelUpload(upload.promise); matrixClient.cancelUpload(upload.promise);

View file

@ -27,13 +27,17 @@ import katex from 'katex';
import { AllHtmlEntities } from 'html-entities'; import { AllHtmlEntities } from 'html-entities';
import { IContent } from 'matrix-js-sdk/src/models/event'; import { IContent } from 'matrix-js-sdk/src/models/event';
import { _linkifyElement, _linkifyString } from './linkify-matrix'; import {
_linkifyElement,
_linkifyString,
ELEMENT_URL_PATTERN,
options as linkifyMatrixOptions,
} from './linkify-matrix';
import { IExtendedSanitizeOptions } from './@types/sanitize-html'; import { IExtendedSanitizeOptions } from './@types/sanitize-html';
import SettingsStore from './settings/SettingsStore'; import SettingsStore from './settings/SettingsStore';
import { tryTransformPermalinkToLocalHref } from "./utils/permalinks/Permalinks"; import { tryTransformPermalinkToLocalHref } from "./utils/permalinks/Permalinks";
import { getEmojiFromUnicode } from "./emoji"; import { getEmojiFromUnicode } from "./emoji";
import { mediaFromMxc } from "./customisations/Media"; import { mediaFromMxc } from "./customisations/Media";
import { ELEMENT_URL_PATTERN, options as linkifyMatrixOptions } from './linkify-matrix';
import { stripHTMLReply, stripPlainReply } from './utils/Reply'; import { stripHTMLReply, stripPlainReply } from './utils/Reply';
// Anything outside the basic multilingual plane will be a surrogate pair // Anything outside the basic multilingual plane will be a surrogate pair
@ -45,10 +49,10 @@ const SURROGATE_PAIR_PATTERN = /([\ud800-\udbff])([\udc00-\udfff])/;
const SYMBOL_PATTERN = /([\u2100-\u2bff])/; const SYMBOL_PATTERN = /([\u2100-\u2bff])/;
// Regex pattern for Zero-Width joiner unicode characters // Regex pattern for Zero-Width joiner unicode characters
const ZWJ_REGEX = new RegExp("\u200D|\u2003", "g"); const ZWJ_REGEX = /[\u200D\u2003]/g;
// Regex pattern for whitespace characters // Regex pattern for whitespace characters
const WHITESPACE_REGEX = new RegExp("\\s", "g"); const WHITESPACE_REGEX = /\s/g;
const BIGEMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})+$`, 'i'); const BIGEMOJI_REGEX = new RegExp(`^(${EMOJIBASE_REGEX.source})+$`, 'i');

View file

@ -15,14 +15,10 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { isMac, Key } from "./Keyboard"; import { IS_MAC, Key } from "./Keyboard";
import SettingsStore from "./settings/SettingsStore"; import SettingsStore from "./settings/SettingsStore";
import SdkConfig from "./SdkConfig"; import SdkConfig from "./SdkConfig";
import { import { IKeyBindingsProvider, KeyBinding } from "./KeyBindingsManager";
IKeyBindingsProvider,
KeyBinding,
KeyCombo,
} from "./KeyBindingsManager";
import { import {
CATEGORIES, CATEGORIES,
CategoryName, CategoryName,
@ -31,13 +27,10 @@ import {
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, name) => { return CATEGORIES[category].settingNames.reduce((bindings, action) => {
const value = getKeyboardShortcuts()[name]?.default; const keyCombo = getKeyboardShortcuts()[action]?.default;
if (value) { if (keyCombo) {
bindings.push({ bindings.push({ action, keyCombo });
action: name as KeyBindingAction,
keyCombo: value as KeyCombo,
});
} }
return bindings; return bindings;
}, []); }, []);
@ -81,7 +74,7 @@ const messageComposerBindings = (): KeyBinding[] => {
shiftKey: true, shiftKey: true,
}, },
}); });
if (isMac) { if (IS_MAC) {
bindings.push({ bindings.push({
action: KeyBindingAction.NewLine, action: KeyBindingAction.NewLine,
keyCombo: { keyCombo: {

View file

@ -17,7 +17,7 @@ limitations under the License.
import { KeyBindingAction } from "./accessibility/KeyboardShortcuts"; import { KeyBindingAction } from "./accessibility/KeyboardShortcuts";
import { defaultBindingsProvider } from './KeyBindingsDefaults'; import { defaultBindingsProvider } from './KeyBindingsDefaults';
import { isMac } from './Keyboard'; import { IS_MAC } from './Keyboard';
/** /**
* Represent a key combination. * Represent a key combination.
@ -127,7 +127,7 @@ export class KeyBindingsManager {
): KeyBindingAction | undefined { ): KeyBindingAction | undefined {
for (const getter of getters) { for (const getter of getters) {
const bindings = getter(); const bindings = getter();
const binding = bindings.find(it => isKeyComboMatch(ev, it.keyCombo, isMac)); const binding = bindings.find(it => isKeyComboMatch(ev, it.keyCombo, IS_MAC));
if (binding) { if (binding) {
return binding.action; return binding.action;
} }

View file

@ -74,10 +74,10 @@ export const Key = {
Z: "z", Z: "z",
}; };
export const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; export const IS_MAC = navigator.platform.toUpperCase().includes('MAC');
export function isOnlyCtrlOrCmdKeyEvent(ev) { export function isOnlyCtrlOrCmdKeyEvent(ev) {
if (isMac) { if (IS_MAC) {
return ev.metaKey && !ev.altKey && !ev.ctrlKey && !ev.shiftKey; return ev.metaKey && !ev.altKey && !ev.ctrlKey && !ev.shiftKey;
} else { } else {
return ev.ctrlKey && !ev.altKey && !ev.metaKey && !ev.shiftKey; return ev.ctrlKey && !ev.altKey && !ev.metaKey && !ev.shiftKey;
@ -85,7 +85,7 @@ export function isOnlyCtrlOrCmdKeyEvent(ev) {
} }
export function isOnlyCtrlOrCmdIgnoreShiftKeyEvent(ev) { export function isOnlyCtrlOrCmdIgnoreShiftKeyEvent(ev) {
if (isMac) { if (IS_MAC) {
return ev.metaKey && !ev.altKey && !ev.ctrlKey; return ev.metaKey && !ev.altKey && !ev.ctrlKey;
} else { } else {
return ev.ctrlKey && !ev.altKey && !ev.metaKey; return ev.ctrlKey && !ev.altKey && !ev.metaKey;

View file

@ -833,7 +833,7 @@ async function startMatrixClient(startSyncing = true): Promise<void> {
} }
// Now that we have a MatrixClientPeg, update the Jitsi info // Now that we have a MatrixClientPeg, update the Jitsi info
await Jitsi.getInstance().start(); Jitsi.getInstance().start();
// dispatch that we finished starting up to wire up any other bits // dispatch that we finished starting up to wire up any other bits
// of the matrix client that cannot be set prior to starting up. // of the matrix client that cannot be set prior to starting up.

View file

@ -305,7 +305,6 @@ export default class Markdown {
renderer.html_inline = function(node: commonmark.Node) { renderer.html_inline = function(node: commonmark.Node) {
if (isAllowedHtmlTag(node)) { if (isAllowedHtmlTag(node)) {
this.lit(node.literal); this.lit(node.literal);
return;
} else { } else {
this.lit(escape(node.literal)); this.lit(escape(node.literal));
} }

View file

@ -123,9 +123,6 @@ class MatrixClientPegClass implements IMatrixClientPeg {
// used if we tear it down & recreate it with a different store // used if we tear it down & recreate it with a different store
private currentClientCreds: IMatrixClientCreds; private currentClientCreds: IMatrixClientCreds;
constructor() {
}
public get(): MatrixClient { public get(): MatrixClient {
return this.matrixClient; return this.matrixClient;
} }

View file

@ -19,6 +19,7 @@ import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { User } from "matrix-js-sdk/src/models/user"; import { User } from "matrix-js-sdk/src/models/user";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixClientPeg } from './MatrixClientPeg'; import { MatrixClientPeg } from './MatrixClientPeg';
import MultiInviter, { CompletionStates } from './utils/MultiInviter'; import MultiInviter, { CompletionStates } from './utils/MultiInviter';
@ -84,12 +85,12 @@ export function showRoomInviteDialog(roomId: string, initialText = ""): void {
* @returns {boolean} True if valid, false otherwise * @returns {boolean} True if valid, false otherwise
*/ */
export function isValid3pidInvite(event: MatrixEvent): boolean { export function isValid3pidInvite(event: MatrixEvent): boolean {
if (!event || event.getType() !== "m.room.third_party_invite") return false; if (!event || event.getType() !== EventType.RoomThirdPartyInvite) return false;
// any events without these keys are not valid 3pid invites, so we ignore them // any events without these keys are not valid 3pid invites, so we ignore them
const requiredKeys = ['key_validity_url', 'public_key', 'display_name']; const requiredKeys = ['key_validity_url', 'public_key', 'display_name'];
for (let i = 0; i < requiredKeys.length; ++i) { if (requiredKeys.some(key => !event.getContent()[key])) {
if (!event.getContent()[requiredKeys[i]]) return false; return false;
} }
// Valid enough by our standards // Valid enough by our standards

View file

@ -83,9 +83,11 @@ async function confirmToDismiss(): Promise<boolean> {
return !sure; return !sure;
} }
type KeyParams = { passphrase: string, recoveryKey: string };
function makeInputToKey( function makeInputToKey(
keyInfo: ISecretStorageKeyInfo, keyInfo: ISecretStorageKeyInfo,
): (keyParams: { passphrase: string, recoveryKey: string }) => Promise<Uint8Array> { ): (keyParams: KeyParams) => Promise<Uint8Array> {
return async ({ passphrase, recoveryKey }) => { return async ({ passphrase, recoveryKey }) => {
if (passphrase) { if (passphrase) {
return deriveKey( return deriveKey(
@ -101,11 +103,10 @@ function makeInputToKey(
async function getSecretStorageKey( async function getSecretStorageKey(
{ keys: keyInfos }: { keys: Record<string, ISecretStorageKeyInfo> }, { keys: keyInfos }: { keys: Record<string, ISecretStorageKeyInfo> },
ssssItemName,
): Promise<[string, Uint8Array]> { ): Promise<[string, Uint8Array]> {
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
let keyId = await cli.getDefaultSecretStorageKeyId(); let keyId = await cli.getDefaultSecretStorageKeyId();
let keyInfo; let keyInfo: ISecretStorageKeyInfo;
if (keyId) { if (keyId) {
// use the default SSSS key if set // use the default SSSS key if set
keyInfo = keyInfos[keyId]; keyInfo = keyInfos[keyId];
@ -154,9 +155,9 @@ async function getSecretStorageKey(
/* props= */ /* props= */
{ {
keyInfo, keyInfo,
checkPrivateKey: async (input) => { checkPrivateKey: async (input: KeyParams) => {
const key = await inputToKey(input); const key = await inputToKey(input);
return await MatrixClientPeg.get().checkSecretStorageKey(key, keyInfo); return MatrixClientPeg.get().checkSecretStorageKey(key, keyInfo);
}, },
}, },
/* className= */ null, /* className= */ null,
@ -171,11 +172,11 @@ async function getSecretStorageKey(
}, },
}, },
); );
const [input] = await finished; const [keyParams] = await finished;
if (!input) { if (!keyParams) {
throw new AccessCancelledError(); throw new AccessCancelledError();
} }
const key = await inputToKey(input); const key = await inputToKey(keyParams);
// Save to cache to avoid future prompts in the current session // Save to cache to avoid future prompts in the current session
cacheSecretStorageKey(keyId, keyInfo, key); cacheSecretStorageKey(keyId, keyInfo, key);

View file

@ -224,7 +224,7 @@ const onViewJoinRuleSettingsClick = () => {
}); });
}; };
function textForJoinRulesEvent(ev: MatrixEvent, allowJSX: boolean): () => string | JSX.Element | null { function textForJoinRulesEvent(ev: MatrixEvent, allowJSX: boolean): () => Renderable {
const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender(); const senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
switch (ev.getContent().join_rule) { switch (ev.getContent().join_rule) {
case JoinRule.Public: case JoinRule.Public:
@ -281,7 +281,7 @@ function textForServerACLEvent(ev: MatrixEvent): () => string | null {
const prev = { const prev = {
deny: Array.isArray(prevContent.deny) ? prevContent.deny : [], deny: Array.isArray(prevContent.deny) ? prevContent.deny : [],
allow: Array.isArray(prevContent.allow) ? prevContent.allow : [], allow: Array.isArray(prevContent.allow) ? prevContent.allow : [],
allow_ip_literals: !(prevContent.allow_ip_literals === false), allow_ip_literals: prevContent.allow_ip_literals !== false,
}; };
let getText = null; let getText = null;
@ -372,13 +372,15 @@ function textForCanonicalAliasEvent(ev: MatrixEvent): () => string | null {
addresses: addedAltAliases.join(", "), addresses: addedAltAliases.join(", "),
count: addedAltAliases.length, count: addedAltAliases.length,
}); });
} if (removedAltAliases.length && !addedAltAliases.length) { }
if (removedAltAliases.length && !addedAltAliases.length) {
return () => _t('%(senderName)s removed the alternative addresses %(addresses)s for this room.', { return () => _t('%(senderName)s removed the alternative addresses %(addresses)s for this room.', {
senderName, senderName,
addresses: removedAltAliases.join(", "), addresses: removedAltAliases.join(", "),
count: removedAltAliases.length, count: removedAltAliases.length,
}); });
} if (removedAltAliases.length && addedAltAliases.length) { }
if (removedAltAliases.length && addedAltAliases.length) {
return () => _t('%(senderName)s changed the alternative addresses for this room.', { return () => _t('%(senderName)s changed the alternative addresses for this room.', {
senderName, senderName,
}); });
@ -504,7 +506,7 @@ const onPinnedMessagesClick = (): void => {
RightPanelStore.instance.setCard({ phase: RightPanelPhases.PinnedMessages }, false); RightPanelStore.instance.setCard({ phase: RightPanelPhases.PinnedMessages }, false);
}; };
function textForPinnedEvent(event: MatrixEvent, allowJSX: boolean): () => string | JSX.Element | null { function textForPinnedEvent(event: MatrixEvent, allowJSX: boolean): () => Renderable {
if (!SettingsStore.getValue("feature_pinning")) return null; if (!SettingsStore.getValue("feature_pinning")) return null;
const senderName = getSenderName(event); const senderName = getSenderName(event);
const roomId = event.getRoomId(); const roomId = event.getRoomId();
@ -758,10 +760,12 @@ function textForPollEndEvent(event: MatrixEvent): () => string | null {
}); });
} }
type Renderable = string | JSX.Element | null;
interface IHandlers { interface IHandlers {
[type: string]: [type: string]:
(ev: MatrixEvent, allowJSX: boolean, showHiddenEvents?: boolean) => (ev: MatrixEvent, allowJSX: boolean, showHiddenEvents?: boolean) =>
(() => string | JSX.Element | null); (() => Renderable);
} }
const handlers: IHandlers = { const handlers: IHandlers = {

View file

@ -15,7 +15,7 @@ limitations under the License.
*/ */
import { KeyCombo } from "../KeyBindingsManager"; import { KeyCombo } from "../KeyBindingsManager";
import { isMac, Key } from "../Keyboard"; import { IS_MAC, Key } from "../Keyboard";
import { _t, _td } from "../languageHandler"; import { _t, _td } from "../languageHandler";
import PlatformPeg from "../PlatformPeg"; import PlatformPeg from "../PlatformPeg";
import SettingsStore from "../settings/SettingsStore"; import SettingsStore from "../settings/SettingsStore";
@ -96,7 +96,7 @@ export const getKeyboardShortcuts = (): IKeyboardShortcuts => {
return Object.keys(KEYBOARD_SHORTCUTS).filter((k: KeyBindingAction) => { return Object.keys(KEYBOARD_SHORTCUTS).filter((k: KeyBindingAction) => {
if (KEYBOARD_SHORTCUTS[k]?.controller?.settingDisabled) return false; if (KEYBOARD_SHORTCUTS[k]?.controller?.settingDisabled) return false;
if (MAC_ONLY_SHORTCUTS.includes(k) && !isMac) return false; if (MAC_ONLY_SHORTCUTS.includes(k) && !IS_MAC) return false;
if (DESKTOP_SHORTCUTS.includes(k) && !overrideBrowserShortcuts) return false; if (DESKTOP_SHORTCUTS.includes(k) && !overrideBrowserShortcuts) return false;
return true; return true;

View file

@ -16,7 +16,7 @@ limitations under the License.
*/ */
import { _td } from "../languageHandler"; import { _td } from "../languageHandler";
import { isMac, Key } from "../Keyboard"; import { IS_MAC, Key } from "../Keyboard";
import { IBaseSetting } from "../settings/Settings"; import { IBaseSetting } from "../settings/Settings";
import IncompatibleController from "../settings/controllers/IncompatibleController"; import IncompatibleController from "../settings/controllers/IncompatibleController";
import { KeyCombo } from "../KeyBindingsManager"; import { KeyCombo } from "../KeyBindingsManager";
@ -200,7 +200,7 @@ export const KEY_ICON: Record<string, string> = {
[Key.ARROW_LEFT]: "←", [Key.ARROW_LEFT]: "←",
[Key.ARROW_RIGHT]: "→", [Key.ARROW_RIGHT]: "→",
}; };
if (isMac) { if (IS_MAC) {
KEY_ICON[Key.META] = "⌘"; KEY_ICON[Key.META] = "⌘";
KEY_ICON[Key.ALT] = "⌥"; KEY_ICON[Key.ALT] = "⌥";
} }
@ -528,8 +528,8 @@ export const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
[KeyBindingAction.GoToHome]: { [KeyBindingAction.GoToHome]: {
default: { default: {
ctrlOrCmdKey: true, ctrlOrCmdKey: true,
altKey: !isMac, altKey: !IS_MAC,
shiftKey: isMac, shiftKey: IS_MAC,
key: Key.H, key: Key.H,
}, },
displayName: _td("Go to Home View"), displayName: _td("Go to Home View"),
@ -621,25 +621,25 @@ export const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
}, },
[KeyBindingAction.EditRedo]: { [KeyBindingAction.EditRedo]: {
default: { default: {
key: isMac ? Key.Z : Key.Y, key: IS_MAC ? Key.Z : Key.Y,
ctrlOrCmdKey: true, ctrlOrCmdKey: true,
shiftKey: isMac, shiftKey: IS_MAC,
}, },
displayName: _td("Redo edit"), displayName: _td("Redo edit"),
}, },
[KeyBindingAction.PreviousVisitedRoomOrSpace]: { [KeyBindingAction.PreviousVisitedRoomOrSpace]: {
default: { default: {
metaKey: isMac, metaKey: IS_MAC,
altKey: !isMac, altKey: !IS_MAC,
key: isMac ? Key.SQUARE_BRACKET_LEFT : Key.ARROW_LEFT, key: IS_MAC ? Key.SQUARE_BRACKET_LEFT : Key.ARROW_LEFT,
}, },
displayName: _td("Previous recently visited room or space"), displayName: _td("Previous recently visited room or space"),
}, },
[KeyBindingAction.NextVisitedRoomOrSpace]: { [KeyBindingAction.NextVisitedRoomOrSpace]: {
default: { default: {
metaKey: isMac, metaKey: IS_MAC,
altKey: !isMac, altKey: !IS_MAC,
key: isMac ? Key.SQUARE_BRACKET_RIGHT : Key.ARROW_RIGHT, key: IS_MAC ? Key.SQUARE_BRACKET_RIGHT : Key.ARROW_RIGHT,
}, },
displayName: _td("Next recently visited room or space"), displayName: _td("Next recently visited room or space"),
}, },

View file

@ -276,7 +276,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
private doBootstrapUIAuth = async (makeRequest: (authData: any) => void): Promise<void> => { private doBootstrapUIAuth = async (makeRequest: (authData: any) => void): Promise<void> => {
if (this.state.canUploadKeysWithPasswordOnly && this.state.accountPassword) { if (this.state.canUploadKeysWithPasswordOnly && this.state.accountPassword) {
await makeRequest({ makeRequest({
type: 'm.login.password', type: 'm.login.password',
identifier: { identifier: {
type: 'm.id.user', type: 'm.id.user',

View file

@ -95,7 +95,7 @@ export default class Autocompleter {
*/ */
// list of results from each provider, each being a list of completions or null if it times out // list of results from each provider, each being a list of completions or null if it times out
const completionsList: ICompletion[][] = await Promise.all(this.providers.map(async provider => { const completionsList: ICompletion[][] = await Promise.all(this.providers.map(async provider => {
return await timeout( return timeout(
provider.getCompletions(query, selection, force, limit), provider.getCompletions(query, selection, force, limit),
null, null,
PROVIDER_COMPLETION_TIMEOUT, PROVIDER_COMPLETION_TIMEOUT,

View file

@ -53,7 +53,7 @@ export async function getThreepidsWithBindStatus(
} }
} catch (e) { } catch (e) {
// Ignore terms errors here and assume other flows handle this // Ignore terms errors here and assume other flows handle this
if (!(e.errcode === "M_TERMS_NOT_SIGNED")) { if (e.errcode !== "M_TERMS_NOT_SIGNED") {
throw e; throw e;
} }
} }

View file

@ -157,12 +157,14 @@ export default class ContextMenu extends React.PureComponent<IProps, IState> {
// XXX: This isn't pretty but the only way to allow opening a different context menu on right click whilst // XXX: This isn't pretty but the only way to allow opening a different context menu on right click whilst
// a context menu and its click-guard are up without completely rewriting how the context menus work. // a context menu and its click-guard are up without completely rewriting how the context menus work.
setImmediate(() => { setImmediate(() => {
const clickEvent = document.createEvent('MouseEvents'); const clickEvent = new MouseEvent("contextmenu", {
clickEvent.initMouseEvent( clientX: x,
'contextmenu', true, true, window, 0, clientY: y,
0, 0, x, y, false, false, screenX: 0,
false, false, 0, null, screenY: 0,
); button: 0, // Left
relatedTarget: null,
});
document.elementFromPoint(x, y).dispatchEvent(clickEvent); document.elementFromPoint(x, y).dispatchEvent(clickEvent);
}); });
} }
@ -417,8 +419,8 @@ export type ToRightOf = {
// Placement method for <ContextMenu /> to position context menu to right of elementRect with chevronOffset // Placement method for <ContextMenu /> to position context menu to right of elementRect with chevronOffset
export const toRightOf = (elementRect: Pick<DOMRect, "right" | "top" | "height">, chevronOffset = 12): ToRightOf => { export const toRightOf = (elementRect: Pick<DOMRect, "right" | "top" | "height">, chevronOffset = 12): ToRightOf => {
const left = elementRect.right + window.pageXOffset + 3; const left = elementRect.right + window.scrollX + 3;
let top = elementRect.top + (elementRect.height / 2) + window.pageYOffset; let top = elementRect.top + (elementRect.height / 2) + window.scrollY;
top -= chevronOffset + 8; // where 8 is half the height of the chevron top -= chevronOffset + 8; // where 8 is half the height of the chevron
return { left, top, chevronOffset }; return { left, top, chevronOffset };
}; };
@ -436,9 +438,9 @@ export const aboveLeftOf = (
): AboveLeftOf => { ): AboveLeftOf => {
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace }; const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
const buttonRight = elementRect.right + window.pageXOffset; const buttonRight = elementRect.right + window.scrollX;
const buttonBottom = elementRect.bottom + window.pageYOffset; const buttonBottom = elementRect.bottom + window.scrollY;
const buttonTop = elementRect.top + window.pageYOffset; const buttonTop = elementRect.top + window.scrollY;
// Align the right edge of the menu to the right edge of the button // Align the right edge of the menu to the right edge of the button
menuOptions.right = UIStore.instance.windowWidth - buttonRight; menuOptions.right = UIStore.instance.windowWidth - buttonRight;
// Align the menu vertically on whichever side of the button has more space available. // Align the menu vertically on whichever side of the button has more space available.
@ -460,9 +462,9 @@ export const aboveRightOf = (
): AboveLeftOf => { ): AboveLeftOf => {
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace }; const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
const buttonLeft = elementRect.left + window.pageXOffset; const buttonLeft = elementRect.left + window.scrollX;
const buttonBottom = elementRect.bottom + window.pageYOffset; const buttonBottom = elementRect.bottom + window.scrollY;
const buttonTop = elementRect.top + window.pageYOffset; const buttonTop = elementRect.top + window.scrollY;
// Align the left edge of the menu to the left edge of the button // Align the left edge of the menu to the left edge of the button
menuOptions.left = buttonLeft; menuOptions.left = buttonLeft;
// Align the menu vertically on whichever side of the button has more space available. // Align the menu vertically on whichever side of the button has more space available.
@ -484,9 +486,9 @@ export const alwaysAboveLeftOf = (
) => { ) => {
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace }; const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
const buttonRight = elementRect.right + window.pageXOffset; const buttonRight = elementRect.right + window.scrollX;
const buttonBottom = elementRect.bottom + window.pageYOffset; const buttonBottom = elementRect.bottom + window.scrollY;
const buttonTop = elementRect.top + window.pageYOffset; const buttonTop = elementRect.top + window.scrollY;
// Align the right edge of the menu to the right edge of the button // Align the right edge of the menu to the right edge of the button
menuOptions.right = UIStore.instance.windowWidth - buttonRight; menuOptions.right = UIStore.instance.windowWidth - buttonRight;
// Align the menu vertically on whichever side of the button has more space available. // Align the menu vertically on whichever side of the button has more space available.
@ -508,8 +510,8 @@ export const alwaysAboveRightOf = (
) => { ) => {
const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace }; const menuOptions: IPosition & { chevronFace: ChevronFace } = { chevronFace };
const buttonLeft = elementRect.left + window.pageXOffset; const buttonLeft = elementRect.left + window.scrollX;
const buttonTop = elementRect.top + window.pageYOffset; const buttonTop = elementRect.top + window.scrollY;
// Align the left edge of the menu to the left edge of the button // Align the left edge of the menu to the left edge of the button
menuOptions.left = buttonLeft; menuOptions.left = buttonLeft;
// Align the menu vertically above the menu // Align the menu vertically above the menu

View file

@ -26,7 +26,7 @@ import dis from "../../dispatcher/dispatcher";
import Modal from "../../Modal"; import Modal from "../../Modal";
import { _t } from '../../languageHandler'; import { _t } from '../../languageHandler';
import SdkConfig from '../../SdkConfig'; import SdkConfig from '../../SdkConfig';
import { instanceForInstanceId, protocolNameForInstanceId } from '../../utils/DirectoryUtils'; import { instanceForInstanceId, protocolNameForInstanceId, ALL_ROOMS, Protocols } from '../../utils/DirectoryUtils';
import Analytics from '../../Analytics'; import Analytics from '../../Analytics';
import NetworkDropdown from "../views/directory/NetworkDropdown"; import NetworkDropdown from "../views/directory/NetworkDropdown";
import SettingsStore from "../../settings/SettingsStore"; import SettingsStore from "../../settings/SettingsStore";
@ -43,7 +43,6 @@ import PosthogTrackers from "../../PosthogTrackers";
import { PublicRoomTile } from "../views/rooms/PublicRoomTile"; import { PublicRoomTile } from "../views/rooms/PublicRoomTile";
import { getFieldsForThirdPartyLocation, joinRoomByAlias, showRoom } from "../../utils/rooms"; import { getFieldsForThirdPartyLocation, joinRoomByAlias, showRoom } from "../../utils/rooms";
import { GenericError } from "../../utils/error"; import { GenericError } from "../../utils/error";
import { ALL_ROOMS, Protocols } from "../../utils/DirectoryUtils";
const LAST_SERVER_KEY = "mx_last_room_directory_server"; const LAST_SERVER_KEY = "mx_last_room_directory_server";
const LAST_INSTANCE_KEY = "mx_last_room_directory_instance"; const LAST_INSTANCE_KEY = "mx_last_room_directory_instance";

View file

@ -28,7 +28,7 @@ import { NameFilterCondition } from "../../stores/room-list/filters/NameFilterCo
import { getKeyBindingsManager } from "../../KeyBindingsManager"; import { getKeyBindingsManager } from "../../KeyBindingsManager";
import SpaceStore from "../../stores/spaces/SpaceStore"; import SpaceStore from "../../stores/spaces/SpaceStore";
import { UPDATE_SELECTED_SPACE } from "../../stores/spaces"; import { UPDATE_SELECTED_SPACE } from "../../stores/spaces";
import { isMac, Key } from "../../Keyboard"; import { IS_MAC, Key } from "../../Keyboard";
import SettingsStore from "../../settings/SettingsStore"; import SettingsStore from "../../settings/SettingsStore";
import Modal from "../../Modal"; import Modal from "../../Modal";
import SpotlightDialog from "../views/dialogs/SpotlightDialog"; import SpotlightDialog from "../views/dialogs/SpotlightDialog";
@ -206,7 +206,7 @@ export default class RoomSearch extends React.PureComponent<IProps, IState> {
); );
let shortcutPrompt = <div className="mx_RoomSearch_shortcutPrompt"> let shortcutPrompt = <div className="mx_RoomSearch_shortcutPrompt">
{ isMac ? "⌘ K" : _t(ALTERNATE_KEY_NAME[Key.CONTROL]) + " K" } { IS_MAC ? "⌘ K" : _t(ALTERNATE_KEY_NAME[Key.CONTROL]) + " K" }
</div>; </div>;
if (this.props.isMinimized) { if (this.props.isMinimized) {

View file

@ -36,7 +36,6 @@ import classNames from "classnames";
import { sortBy, uniqBy } from "lodash"; import { sortBy, uniqBy } from "lodash";
import { GuestAccess, HistoryVisibility } from "matrix-js-sdk/src/@types/partials"; import { GuestAccess, HistoryVisibility } from "matrix-js-sdk/src/@types/partials";
import dis from "../../dispatcher/dispatcher";
import defaultDispatcher from "../../dispatcher/dispatcher"; import defaultDispatcher from "../../dispatcher/dispatcher";
import { _t } from "../../languageHandler"; import { _t } from "../../languageHandler";
import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton"; import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton";
@ -330,13 +329,13 @@ export const showRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: st
// fail earlier so they don't have to click back to the directory. // fail earlier so they don't have to click back to the directory.
if (cli.isGuest()) { if (cli.isGuest()) {
if (!room.world_readable && !room.guest_can_join) { if (!room.world_readable && !room.guest_can_join) {
dis.dispatch({ action: "require_registration" }); defaultDispatcher.dispatch({ action: "require_registration" });
return; return;
} }
} }
const roomAlias = getDisplayAliasForRoom(room) || undefined; const roomAlias = getDisplayAliasForRoom(room) || undefined;
dis.dispatch<ViewRoomPayload>({ defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom, action: Action.ViewRoom,
should_peek: true, should_peek: true,
room_alias: roomAlias, room_alias: roomAlias,
@ -356,7 +355,7 @@ export const joinRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: st
// Don't let the user view a room they won't be able to either peek or join: // Don't let the user view a room they won't be able to either peek or join:
// fail earlier so they don't have to click back to the directory. // fail earlier so they don't have to click back to the directory.
if (cli.isGuest()) { if (cli.isGuest()) {
dis.dispatch({ action: "require_registration" }); defaultDispatcher.dispatch({ action: "require_registration" });
return; return;
} }
@ -365,7 +364,7 @@ export const joinRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: st
}); });
prom.then(() => { prom.then(() => {
dis.dispatch<JoinRoomReadyPayload>({ defaultDispatcher.dispatch<JoinRoomReadyPayload>({
action: Action.JoinRoomReady, action: Action.JoinRoomReady,
roomId, roomId,
metricsTrigger: "SpaceHierarchy", metricsTrigger: "SpaceHierarchy",
@ -569,7 +568,7 @@ const ManageButtons = ({ hierarchy, selected, setSelected, setError }: IManageBu
const selectedRelations = Array.from(selected.keys()).flatMap(parentId => { const selectedRelations = Array.from(selected.keys()).flatMap(parentId => {
return [ return [
...selected.get(parentId).values(), ...selected.get(parentId).values(),
].map(childId => [parentId, childId]) as [string, string][]; ].map(childId => [parentId, childId]);
}); });
const selectionAllSuggested = selectedRelations.every(([parentId, childId]) => { const selectionAllSuggested = selectedRelations.every(([parentId, childId]) => {

View file

@ -36,7 +36,6 @@ import { useTypedEventEmitter } from "../../hooks/useEventEmitter";
import withValidation from "../views/elements/Validation"; import withValidation from "../views/elements/Validation";
import * as Email from "../../email"; import * as Email from "../../email";
import defaultDispatcher from "../../dispatcher/dispatcher"; import defaultDispatcher from "../../dispatcher/dispatcher";
import dis from "../../dispatcher/dispatcher";
import { Action } from "../../dispatcher/actions"; import { Action } from "../../dispatcher/actions";
import ResizeNotifier from "../../utils/ResizeNotifier"; import ResizeNotifier from "../../utils/ResizeNotifier";
import MainSplit from './MainSplit'; import MainSplit from './MainSplit';
@ -204,7 +203,7 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }: ISp
<AccessibleButton <AccessibleButton
kind="danger_outline" kind="danger_outline"
onClick={() => { onClick={() => {
dis.dispatch({ defaultDispatcher.dispatch({
action: "leave_room", action: "leave_room",
room_id: space.roomId, room_id: space.roomId,
}); });
@ -316,8 +315,8 @@ const SpaceLandingAddButton = ({ space }) => {
if (menuDisplayed) { if (menuDisplayed) {
const rect = handle.current.getBoundingClientRect(); const rect = handle.current.getBoundingClientRect();
contextMenu = <IconizedContextMenu contextMenu = <IconizedContextMenu
left={rect.left + window.pageXOffset + 0} left={rect.left + window.scrollX + 0}
top={rect.bottom + window.pageYOffset + 8} top={rect.bottom + window.scrollY + 8}
chevronFace={ChevronFace.None} chevronFace={ChevronFace.None}
onFinished={closeMenu} onFinished={closeMenu}
className="mx_RoomTile_contextMenu" className="mx_RoomTile_contextMenu"

View file

@ -20,7 +20,6 @@ import classNames from "classnames";
import { MatrixClientPeg } from "../../MatrixClientPeg"; import { MatrixClientPeg } from "../../MatrixClientPeg";
import defaultDispatcher from "../../dispatcher/dispatcher"; import defaultDispatcher from "../../dispatcher/dispatcher";
import dis from "../../dispatcher/dispatcher";
import { ActionPayload } from "../../dispatcher/payloads"; import { ActionPayload } from "../../dispatcher/payloads";
import { Action } from "../../dispatcher/actions"; import { Action } from "../../dispatcher/actions";
import { _t } from "../../languageHandler"; import { _t } from "../../languageHandler";
@ -323,7 +322,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
const cli = MatrixClientPeg.get(); const cli = MatrixClientPeg.get();
if (!cli || !cli.isCryptoEnabled() || !(await cli.exportRoomKeys())?.length) { if (!cli || !cli.isCryptoEnabled() || !(await cli.exportRoomKeys())?.length) {
// log out without user prompt if they have no local megolm sessions // log out without user prompt if they have no local megolm sessions
dis.dispatch({ action: 'logout' }); defaultDispatcher.dispatch({ action: 'logout' });
} else { } else {
Modal.createTrackedDialog('Logout from LeftPanel', '', LogoutDialog); Modal.createTrackedDialog('Logout from LeftPanel', '', LogoutDialog);
} }
@ -332,12 +331,12 @@ export default class UserMenu extends React.Component<IProps, IState> {
}; };
private onSignInClick = () => { private onSignInClick = () => {
dis.dispatch({ action: 'start_login' }); defaultDispatcher.dispatch({ action: 'start_login' });
this.setState({ contextMenuPosition: null }); // also close the menu this.setState({ contextMenuPosition: null }); // also close the menu
}; };
private onRegisterClick = () => { private onRegisterClick = () => {
dis.dispatch({ action: 'start_registration' }); defaultDispatcher.dispatch({ action: 'start_registration' });
this.setState({ contextMenuPosition: null }); // also close the menu this.setState({ contextMenuPosition: null }); // also close the menu
}; };

View file

@ -37,12 +37,11 @@ import { Action } from "../../../dispatcher/actions";
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks'; import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
import { ButtonEvent } from '../elements/AccessibleButton'; import { ButtonEvent } from '../elements/AccessibleButton';
import { copyPlaintext, getSelectedText } from '../../../utils/strings'; import { copyPlaintext, getSelectedText } from '../../../utils/strings';
import ContextMenu, { toRightOf } from '../../structures/ContextMenu'; import ContextMenu, { toRightOf, IPosition, ChevronFace } from '../../structures/ContextMenu';
import ReactionPicker from '../emojipicker/ReactionPicker'; import ReactionPicker from '../emojipicker/ReactionPicker';
import ViewSource from '../../structures/ViewSource'; import ViewSource from '../../structures/ViewSource';
import { createRedactEventDialog } from '../dialogs/ConfirmRedactDialog'; import { createRedactEventDialog } from '../dialogs/ConfirmRedactDialog';
import ShareDialog from '../dialogs/ShareDialog'; import ShareDialog from '../dialogs/ShareDialog';
import { IPosition, ChevronFace } from '../../structures/ContextMenu';
import RoomContext, { TimelineRenderingType } from '../../../contexts/RoomContext'; import RoomContext, { TimelineRenderingType } from '../../../contexts/RoomContext';
import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload"; import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload";
import EndPollDialog from '../dialogs/EndPollDialog'; import EndPollDialog from '../dialogs/EndPollDialog';

View file

@ -37,8 +37,8 @@ interface IProps {
const contextMenuBelow = (elementRect: DOMRect) => { const contextMenuBelow = (elementRect: DOMRect) => {
// align the context menu's icons with the icon which opened the context menu // align the context menu's icons with the icon which opened the context menu
const left = elementRect.left + window.pageXOffset + elementRect.width; const left = elementRect.left + window.scrollX + elementRect.width;
const top = elementRect.bottom + window.pageYOffset; const top = elementRect.bottom + window.scrollY;
const chevronFace = ChevronFace.None; const chevronFace = ChevronFace.None;
return { left, top, chevronFace }; return { left, top, chevronFace };
}; };

View file

@ -200,7 +200,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
}, { }, {
key: "number", key: "number",
test: ({ value }) => { test: ({ value }) => {
const parsedSize = parseInt(value as string, 10); const parsedSize = parseInt(value, 10);
return validateNumberInRange(1, 2000)(parsedSize); return validateNumberInRange(1, 2000)(parsedSize);
}, },
invalid: () => { invalid: () => {
@ -238,7 +238,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
}, { }, {
key: "number", key: "number",
test: ({ value }) => { test: ({ value }) => {
const parsedSize = parseInt(value as string, 10); const parsedSize = parseInt(value, 10);
return validateNumberInRange(1, 10 ** 8)(parsedSize); return validateNumberInRange(1, 10 ** 8)(parsedSize);
}, },
invalid: () => { invalid: () => {

View file

@ -138,7 +138,8 @@ export default class MessageEditHistoryDialog extends React.PureComponent<IProps
isBaseEvent={isBaseEvent} isBaseEvent={isBaseEvent}
mxEvent={e} mxEvent={e}
isTwelveHour={this.state.isTwelveHour} isTwelveHour={this.state.isTwelveHour}
/>)); />
));
lastEvent = e; lastEvent = e;
}); });
return nodes; return nodes;

View file

@ -367,16 +367,16 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", onFinished }) =>
); );
} }
const otherResult = (result as IResult); // IResult case
return ( return (
<Option <Option
id={`mx_SpotlightDialog_button_result_${otherResult.name}`} id={`mx_SpotlightDialog_button_result_${result.name}`}
key={otherResult.name} key={result.name}
onClick={otherResult.onClick} onClick={result.onClick}
> >
{ otherResult.avatar } { result.avatar }
{ otherResult.name } { result.name }
{ otherResult.description } { result.description }
</Option> </Option>
); );
}; };

View file

@ -93,7 +93,7 @@ export default class CreateCrossSigningDialog extends React.PureComponent<IProps
private doBootstrapUIAuth = async (makeRequest: (authData: any) => void): Promise<void> => { private doBootstrapUIAuth = async (makeRequest: (authData: any) => void): Promise<void> => {
if (this.state.canUploadKeysWithPasswordOnly && this.state.accountPassword) { if (this.state.canUploadKeysWithPasswordOnly && this.state.accountPassword) {
await makeRequest({ makeRequest({
type: 'm.login.password', type: 'm.login.password',
identifier: { identifier: {
type: 'm.id.user', type: 'm.id.user',
@ -106,7 +106,7 @@ export default class CreateCrossSigningDialog extends React.PureComponent<IProps
}); });
} else if (this.props.tokenLogin) { } else if (this.props.tokenLogin) {
// We are hoping the grace period is active // We are hoping the grace period is active
await makeRequest({}); makeRequest({});
} else { } else {
const dialogAesthetics = { const dialogAesthetics = {
[SSOAuthEntry.PHASE_PREAUTH]: { [SSOAuthEntry.PHASE_PREAUTH]: {

View file

@ -19,7 +19,7 @@ import React, { useEffect, useState } from "react";
import { MatrixError } from "matrix-js-sdk/src/http-api"; import { MatrixError } from "matrix-js-sdk/src/http-api";
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import { instanceForInstanceId } from '../../../utils/DirectoryUtils'; import { instanceForInstanceId, ALL_ROOMS, Protocols } from '../../../utils/DirectoryUtils';
import ContextMenu, { import ContextMenu, {
ChevronFace, ChevronFace,
ContextMenuButton, ContextMenuButton,
@ -41,7 +41,6 @@ import UIStore from "../../../stores/UIStore";
import { compare } from "../../../utils/strings"; import { compare } from "../../../utils/strings";
import { SnakedObject } from "../../../utils/SnakedObject"; import { SnakedObject } from "../../../utils/SnakedObject";
import { IConfigOptions } from "../../../IConfigOptions"; import { IConfigOptions } from "../../../IConfigOptions";
import { ALL_ROOMS, Protocols } from "../../../utils/DirectoryUtils";
const SETTING_NAME = "room_directory_servers"; const SETTING_NAME = "room_directory_servers";

View file

@ -44,7 +44,7 @@ export default class IRCTimelineProfileResizer extends React.Component<IProps, I
componentDidMount() { componentDidMount() {
this.setState({ this.setState({
IRCLayoutRoot: document.querySelector(".mx_IRCLayout") as HTMLElement, IRCLayoutRoot: document.querySelector(".mx_IRCLayout"),
}, () => this.updateCSSWidth(this.state.width)); }, () => this.updateCSSWidth(this.state.width));
} }

View file

@ -352,10 +352,10 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
const targetRect = this.target.getBoundingClientRect(); const targetRect = this.target.getBoundingClientRect();
if (this.props.direction === Direction.Left) { if (this.props.direction === Direction.Left) {
const targetLeft = targetRect.left + window.pageXOffset; const targetLeft = targetRect.left + window.scrollX;
return !contentRect || (targetLeft - contentRect.width > MIN_SAFE_DISTANCE_TO_WINDOW_EDGE); return !contentRect || (targetLeft - contentRect.width > MIN_SAFE_DISTANCE_TO_WINDOW_EDGE);
} else { } else {
const targetRight = targetRect.right + window.pageXOffset; const targetRight = targetRect.right + window.scrollX;
const spaceOnRight = UIStore.instance.windowWidth - targetRight; const spaceOnRight = UIStore.instance.windowWidth - targetRight;
return contentRect && (spaceOnRight - contentRect.width < MIN_SAFE_DISTANCE_TO_WINDOW_EDGE); return contentRect && (spaceOnRight - contentRect.width < MIN_SAFE_DISTANCE_TO_WINDOW_EDGE);
} }
@ -366,10 +366,10 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
const targetRect = this.target.getBoundingClientRect(); const targetRect = this.target.getBoundingClientRect();
if (this.props.direction === Direction.Top) { if (this.props.direction === Direction.Top) {
const targetTop = targetRect.top + window.pageYOffset; const targetTop = targetRect.top + window.scrollY;
return !contentRect || (targetTop - contentRect.height > MIN_SAFE_DISTANCE_TO_WINDOW_EDGE); return !contentRect || (targetTop - contentRect.height > MIN_SAFE_DISTANCE_TO_WINDOW_EDGE);
} else { } else {
const targetBottom = targetRect.bottom + window.pageYOffset; const targetBottom = targetRect.bottom + window.scrollY;
const spaceBelow = UIStore.instance.windowHeight - targetBottom; const spaceBelow = UIStore.instance.windowHeight - targetBottom;
return contentRect && (spaceBelow - contentRect.height < MIN_SAFE_DISTANCE_TO_WINDOW_EDGE); return contentRect && (spaceBelow - contentRect.height < MIN_SAFE_DISTANCE_TO_WINDOW_EDGE);
} }
@ -429,10 +429,10 @@ export default class InteractiveTooltip extends React.Component<IProps, IState>
const targetRect = this.target.getBoundingClientRect(); const targetRect = this.target.getBoundingClientRect();
// The window X and Y offsets are to adjust position when zoomed in to page // The window X and Y offsets are to adjust position when zoomed in to page
const targetLeft = targetRect.left + window.pageXOffset; const targetLeft = targetRect.left + window.scrollX;
const targetRight = targetRect.right + window.pageXOffset; const targetRight = targetRect.right + window.scrollX;
const targetBottom = targetRect.bottom + window.pageYOffset; const targetBottom = targetRect.bottom + window.scrollY;
const targetTop = targetRect.top + window.pageYOffset; const targetTop = targetRect.top + window.scrollY;
// Place the tooltip above the target by default. If we find that the // Place the tooltip above the target by default. If we find that the
// tooltip content would extend past the safe area towards the window // tooltip content would extend past the safe area towards the window

View file

@ -116,12 +116,12 @@ export default class Tooltip extends React.Component<ITooltipProps> {
? Math.min(parentBox.width, this.props.maxParentWidth) ? Math.min(parentBox.width, this.props.maxParentWidth)
: parentBox.width : parentBox.width
); );
const baseTop = (parentBox.top - 2 + this.props.yOffset) + window.pageYOffset; const baseTop = (parentBox.top - 2 + this.props.yOffset) + window.scrollY;
const top = baseTop + offset; const top = baseTop + offset;
const right = width - parentBox.left - window.pageXOffset; const right = width - parentBox.left - window.scrollX;
const left = parentBox.right + window.pageXOffset; const left = parentBox.right + window.scrollX;
const horizontalCenter = ( const horizontalCenter = (
parentBox.left - window.pageXOffset + (parentWidth / 2) parentBox.left - window.scrollX + (parentWidth / 2)
); );
switch (this.props.alignment) { switch (this.props.alignment) {
case Alignment.Natural: case Alignment.Natural:
@ -154,7 +154,7 @@ export default class Tooltip extends React.Component<ITooltipProps> {
break; break;
case Alignment.TopRight: case Alignment.TopRight:
style.top = baseTop - 5; style.top = baseTop - 5;
style.right = width - parentBox.right - window.pageXOffset; style.right = width - parentBox.right - window.scrollX;
style.transform = "translate(5px, -100%)"; style.transform = "translate(5px, -100%)";
break; break;
case Alignment.TopCenter: case Alignment.TopCenter:

View file

@ -52,7 +52,7 @@ class Category extends React.PureComponent<IProps> {
const { onClick, onMouseEnter, onMouseLeave, selectedEmojis, emojis } = this.props; const { onClick, onMouseEnter, onMouseLeave, selectedEmojis, emojis } = this.props;
const emojisForRow = emojis.slice(rowIndex * 8, (rowIndex + 1) * 8); const emojisForRow = emojis.slice(rowIndex * 8, (rowIndex + 1) * 8);
return (<div key={rowIndex}>{ return (<div key={rowIndex}>{
emojisForRow.map(emoji => (( emojisForRow.map(emoji => (
<Emoji <Emoji
key={emoji.hexcode} key={emoji.hexcode}
emoji={emoji} emoji={emoji}
@ -61,7 +61,7 @@ class Category extends React.PureComponent<IProps> {
onMouseEnter={onMouseEnter} onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave} onMouseLeave={onMouseLeave}
/> />
))) ))
}</div>); }</div>);
}; };

View file

@ -249,7 +249,7 @@ class EmojiPicker extends React.Component<IProps, IState> {
> >
{ this.categories.map(category => { { this.categories.map(category => {
const emojis = this.memoizedDataByCategory[category.id]; const emojis = this.memoizedDataByCategory[category.id];
const categoryElement = (( const categoryElement = (
<Category <Category
key={category.id} key={category.id}
id={category.id} id={category.id}
@ -263,7 +263,7 @@ class EmojiPicker extends React.Component<IProps, IState> {
onMouseLeave={this.onHoverEmojiEnd} onMouseLeave={this.onHoverEmojiEnd}
selectedEmojis={this.props.selectedEmojis} selectedEmojis={this.props.selectedEmojis}
/> />
)); );
const height = EmojiPicker.categoryHeightForEmojiCount(emojis.length); const height = EmojiPicker.categoryHeightForEmojiCount(emojis.length);
heightBefore += height; heightBefore += height;
return categoryElement; return categoryElement;

View file

@ -72,7 +72,7 @@ class QuickReactions extends React.Component<IProps, IState> {
} }
</h2> </h2>
<ul className="mx_EmojiPicker_list" aria-label={_t("Quick Reactions")}> <ul className="mx_EmojiPicker_list" aria-label={_t("Quick Reactions")}>
{ QUICK_REACTIONS.map(emoji => (( { QUICK_REACTIONS.map(emoji => (
<Emoji <Emoji
key={emoji.hexcode} key={emoji.hexcode}
emoji={emoji} emoji={emoji}
@ -81,7 +81,7 @@ class QuickReactions extends React.Component<IProps, IState> {
onMouseLeave={this.onMouseLeave} onMouseLeave={this.onMouseLeave}
selectedEmojis={this.props.selectedEmojis} selectedEmojis={this.props.selectedEmojis}
/> />
))) } )) }
</ul> </ul>
</section> </section>
); );

View file

@ -21,11 +21,10 @@ import { IEventRelation } from 'matrix-js-sdk/src/models/event';
import MatrixClientContext from '../../../contexts/MatrixClientContext'; import MatrixClientContext from '../../../contexts/MatrixClientContext';
import ContextMenu, { AboveLeftOf } from '../../structures/ContextMenu'; import ContextMenu, { AboveLeftOf } from '../../structures/ContextMenu';
import LocationPicker, { ILocationPickerProps } from "./LocationPicker"; import LocationPicker, { ILocationPickerProps } from "./LocationPicker";
import { shareLiveLocation, shareLocation } from './shareLocation'; import { shareLiveLocation, shareLocation, LocationShareType } from './shareLocation';
import SettingsStore from '../../../settings/SettingsStore'; import SettingsStore from '../../../settings/SettingsStore';
import ShareDialogButtons from './ShareDialogButtons'; import ShareDialogButtons from './ShareDialogButtons';
import ShareType from './ShareType'; import ShareType from './ShareType';
import { LocationShareType } from './shareLocation';
import { OwnProfileStore } from '../../../stores/OwnProfileStore'; import { OwnProfileStore } from '../../../stores/OwnProfileStore';
import { EnableLiveShare } from './EnableLiveShare'; import { EnableLiveShare } from './EnableLiveShare';
import { useFeatureEnabled } from '../../../hooks/useSettings'; import { useFeatureEnabled } from '../../../hooks/useSettings';

View file

@ -32,7 +32,7 @@ import { parseEvent, parsePlainTextMessage } from '../../../editor/deserialize';
import { renderModel } from '../../../editor/render'; import { renderModel } from '../../../editor/render';
import TypingStore from "../../../stores/TypingStore"; import TypingStore from "../../../stores/TypingStore";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { Key } from "../../../Keyboard"; import { IS_MAC, Key } from "../../../Keyboard";
import { EMOTICON_TO_EMOJI } from "../../../emoji"; import { EMOTICON_TO_EMOJI } from "../../../emoji";
import { CommandCategories, CommandMap, parseCommandString } from "../../../SlashCommands"; import { CommandCategories, CommandMap, parseCommandString } from "../../../SlashCommands";
import Range from "../../../editor/range"; import Range from "../../../editor/range";
@ -50,8 +50,6 @@ import { _t } from "../../../languageHandler";
const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s|:^$'); const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s|:^$');
export const REGEX_EMOTICON = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')$'); export const REGEX_EMOTICON = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')$');
const IS_MAC = navigator.platform.indexOf("Mac") !== -1;
const SURROUND_WITH_CHARACTERS = ["\"", "_", "`", "'", "*", "~", "$"]; const SURROUND_WITH_CHARACTERS = ["\"", "_", "`", "'", "*", "~", "$"];
const SURROUND_WITH_DOUBLE_CHARACTERS = new Map([ const SURROUND_WITH_DOUBLE_CHARACTERS = new Map([
["(", ")"], ["(", ")"],

View file

@ -28,7 +28,6 @@ import AccessibleButton from "../elements/AccessibleButton";
import MiniAvatarUploader, { AVATAR_SIZE } from "../elements/MiniAvatarUploader"; import MiniAvatarUploader, { AVATAR_SIZE } from "../elements/MiniAvatarUploader";
import RoomAvatar from "../avatars/RoomAvatar"; import RoomAvatar from "../avatars/RoomAvatar";
import defaultDispatcher from "../../../dispatcher/dispatcher"; import defaultDispatcher from "../../../dispatcher/dispatcher";
import dis from "../../../dispatcher/dispatcher";
import { ViewUserPayload } from "../../../dispatcher/payloads/ViewUserPayload"; import { ViewUserPayload } from "../../../dispatcher/payloads/ViewUserPayload";
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import SpaceStore from "../../../stores/spaces/SpaceStore"; import SpaceStore from "../../../stores/spaces/SpaceStore";
@ -87,7 +86,7 @@ const NewRoomIntro = () => {
const canAddTopic = inRoom && room.currentState.maySendStateEvent(EventType.RoomTopic, cli.getUserId()); const canAddTopic = inRoom && room.currentState.maySendStateEvent(EventType.RoomTopic, cli.getUserId());
const onTopicClick = () => { const onTopicClick = () => {
dis.dispatch({ defaultDispatcher.dispatch({
action: "open_room_settings", action: "open_room_settings",
room_id: roomId, room_id: roomId,
}, true); }, true);
@ -150,7 +149,7 @@ const NewRoomIntro = () => {
className="mx_NewRoomIntro_inviteButton" className="mx_NewRoomIntro_inviteButton"
kind="primary_outline" kind="primary_outline"
onClick={() => { onClick={() => {
dis.dispatch({ action: "view_invite", roomId }); defaultDispatcher.dispatch({ action: "view_invite", roomId });
}} }}
> >
{ _t("Invite to just this room") } { _t("Invite to just this room") }
@ -162,7 +161,7 @@ const NewRoomIntro = () => {
className="mx_NewRoomIntro_inviteButton" className="mx_NewRoomIntro_inviteButton"
kind="primary" kind="primary"
onClick={() => { onClick={() => {
dis.dispatch({ action: "view_invite", roomId }); defaultDispatcher.dispatch({ action: "view_invite", roomId });
}} }}
> >
{ _t("Invite to this room") } { _t("Invite to this room") }
@ -192,7 +191,7 @@ const NewRoomIntro = () => {
function openRoomSettings(event) { function openRoomSettings(event) {
event.preventDefault(); event.preventDefault();
dis.dispatch({ defaultDispatcher.dispatch({
action: "open_room_settings", action: "open_room_settings",
initial_tab_id: ROOM_SECURITY_TAB, initial_tab_id: ROOM_SECURITY_TAB,
}); });

View file

@ -16,9 +16,8 @@ limitations under the License.
import React, { ComponentType, createRef, ReactComponentElement, RefObject } from "react"; import React, { ComponentType, createRef, ReactComponentElement, RefObject } from "react";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { RoomType } from "matrix-js-sdk/src/@types/event"; import { RoomType, EventType } from "matrix-js-sdk/src/@types/event";
import * as fbEmitter from "fbemitter"; import * as fbEmitter from "fbemitter";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { _t, _td } from "../../../languageHandler"; import { _t, _td } from "../../../languageHandler";
import { IState as IRovingTabIndexState, RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex"; import { IState as IRovingTabIndexState, RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";

View file

@ -60,8 +60,8 @@ import { UIComponent } from "../../../settings/UIFeature";
const contextMenuBelow = (elementRect: DOMRect) => { const contextMenuBelow = (elementRect: DOMRect) => {
// align the context menu's icons with the icon which opened the context menu // align the context menu's icons with the icon which opened the context menu
const left = elementRect.left + window.pageXOffset; const left = elementRect.left + window.scrollX;
const top = elementRect.bottom + window.pageYOffset + 12; const top = elementRect.bottom + window.scrollY + 12;
const chevronFace = ChevronFace.None; const chevronFace = ChevronFace.None;
return { left, top, chevronFace }; return { left, top, chevronFace };
}; };

View file

@ -39,7 +39,6 @@ import ContextMenu, {
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore"; import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
import { ListAlgorithm, SortAlgorithm } from "../../../stores/room-list/algorithms/models"; import { ListAlgorithm, SortAlgorithm } from "../../../stores/room-list/algorithms/models";
import { DefaultTagID, TagID } from "../../../stores/room-list/models"; import { DefaultTagID, TagID } from "../../../stores/room-list/models";
import dis from "../../../dispatcher/dispatcher";
import defaultDispatcher from "../../../dispatcher/dispatcher"; import defaultDispatcher from "../../../dispatcher/dispatcher";
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import NotificationBadge from "./NotificationBadge"; import NotificationBadge from "./NotificationBadge";
@ -426,7 +425,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
} }
if (room) { if (room) {
dis.dispatch<ViewRoomPayload>({ defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom, action: Action.ViewRoom,
room_id: room.roomId, room_id: room.roomId,
show_room_tile: true, // to make sure the room gets scrolled into view show_room_tile: true, // to make sure the room gets scrolled into view

View file

@ -24,7 +24,6 @@ import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex";
import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton"; import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton";
import dis from '../../../dispatcher/dispatcher';
import defaultDispatcher from '../../../dispatcher/dispatcher'; import defaultDispatcher from '../../../dispatcher/dispatcher';
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
@ -90,8 +89,8 @@ const messagePreviewId = (roomId: string) => `mx_RoomTile_messagePreview_${roomI
export const contextMenuBelow = (elementRect: PartialDOMRect) => { export const contextMenuBelow = (elementRect: PartialDOMRect) => {
// align the context menu's icons with the icon which opened the context menu // align the context menu's icons with the icon which opened the context menu
const left = elementRect.left + window.pageXOffset - 9; const left = elementRect.left + window.scrollX - 9;
const top = elementRect.bottom + window.pageYOffset + 17; const top = elementRect.bottom + window.scrollY + 17;
const chevronFace = ChevronFace.None; const chevronFace = ChevronFace.None;
return { left, top, chevronFace }; return { left, top, chevronFace };
}; };
@ -260,7 +259,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
const action = getKeyBindingsManager().getAccessibilityAction(ev); const action = getKeyBindingsManager().getAccessibilityAction(ev);
dis.dispatch<ViewRoomPayload>({ defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom, action: Action.ViewRoom,
show_room_tile: true, // make sure the room is visible in the list show_room_tile: true, // make sure the room is visible in the list
room_id: this.props.room.roomId, room_id: this.props.room.roomId,
@ -321,7 +320,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
const isApplied = RoomListStore.instance.getTagsForRoom(this.props.room).includes(tagId); const isApplied = RoomListStore.instance.getTagsForRoom(this.props.room).includes(tagId);
const removeTag = isApplied ? tagId : inverseTag; const removeTag = isApplied ? tagId : inverseTag;
const addTag = isApplied ? null : tagId; const addTag = isApplied ? null : tagId;
dis.dispatch(RoomListActions.tagRoom( defaultDispatcher.dispatch(RoomListActions.tagRoom(
MatrixClientPeg.get(), MatrixClientPeg.get(),
this.props.room, this.props.room,
removeTag, removeTag,
@ -346,7 +345,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
dis.dispatch({ defaultDispatcher.dispatch({
action: 'leave_room', action: 'leave_room',
room_id: this.props.room.roomId, room_id: this.props.room.roomId,
}); });
@ -359,7 +358,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
dis.dispatch({ defaultDispatcher.dispatch({
action: 'forget_room', action: 'forget_room',
room_id: this.props.room.roomId, room_id: this.props.room.roomId,
}); });
@ -370,7 +369,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
dis.dispatch({ defaultDispatcher.dispatch({
action: 'open_room_settings', action: 'open_room_settings',
room_id: this.props.room.roomId, room_id: this.props.room.roomId,
}); });
@ -383,7 +382,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
dis.dispatch({ defaultDispatcher.dispatch({
action: 'copy_room', action: 'copy_room',
room_id: this.props.room.roomId, room_id: this.props.room.roomId,
}); });
@ -394,7 +393,7 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
dis.dispatch({ defaultDispatcher.dispatch({
action: 'view_invite', action: 'view_invite',
roomId: this.props.room.roomId, roomId: this.props.room.roomId,
}); });

View file

@ -196,7 +196,7 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
try { try {
// stop any noises which might be happening // stop any noises which might be happening
await PlaybackManager.instance.pauseAllExcept(null); PlaybackManager.instance.pauseAllExcept(null);
const recorder = VoiceRecordingStore.instance.startRecording(this.props.room.roomId); const recorder = VoiceRecordingStore.instance.startRecording(this.props.room.roomId);
await recorder.start(); await recorder.start();

View file

@ -21,8 +21,7 @@ import { logger } from "matrix-js-sdk/src/logger";
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import { formatDate } from '../../../DateUtils'; import { formatDate } from '../../../DateUtils';
import StyledCheckbox from '../elements/StyledCheckbox'; import StyledCheckbox, { CheckboxStyle } from '../elements/StyledCheckbox';
import { CheckboxStyle } from '../elements/StyledCheckbox';
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import Field from "../elements/Field"; import Field from "../elements/Field";
import TextWithTooltip from "../elements/TextWithTooltip"; import TextWithTooltip from "../elements/TextWithTooltip";

View file

@ -125,7 +125,7 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
await EventIndexPeg.initEventIndex(); await EventIndexPeg.initEventIndex();
await EventIndexPeg.get().addInitialCheckpoints(); await EventIndexPeg.get().addInitialCheckpoints();
await EventIndexPeg.get().startCrawler(); EventIndexPeg.get().startCrawler();
await SettingsStore.setValue('enableEventIndexing', null, SettingLevel.DEVICE, true); await SettingsStore.setValue('enableEventIndexing', null, SettingLevel.DEVICE, true);
await this.updateState(); await this.updateState();
}; };

View file

@ -18,7 +18,7 @@ import React from "react";
import { ALTERNATE_KEY_NAME, KEY_ICON } from "../../../accessibility/KeyboardShortcuts"; import { ALTERNATE_KEY_NAME, KEY_ICON } from "../../../accessibility/KeyboardShortcuts";
import { KeyCombo } from "../../../KeyBindingsManager"; import { KeyCombo } from "../../../KeyBindingsManager";
import { isMac, Key } from "../../../Keyboard"; import { IS_MAC, Key } from "../../../Keyboard";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
interface IKeyboardKeyProps { interface IKeyboardKeyProps {
@ -45,7 +45,7 @@ export const KeyboardShortcut: React.FC<IKeyboardShortcutProps> = ({ value }) =>
const modifiersElement = []; const modifiersElement = [];
if (value.ctrlOrCmdKey) { if (value.ctrlOrCmdKey) {
modifiersElement.push(<KeyboardKey key="ctrlOrCmdKey" name={isMac ? Key.META : Key.CONTROL} />); modifiersElement.push(<KeyboardKey key="ctrlOrCmdKey" name={IS_MAC ? Key.META : Key.CONTROL} />);
} else if (value.ctrlKey) { } else if (value.ctrlKey) {
modifiersElement.push(<KeyboardKey key="ctrlKey" name={Key.CONTROL} />); modifiersElement.push(<KeyboardKey key="ctrlKey" name={Key.CONTROL} />);
} else if (value.metaKey) { } else if (value.metaKey) {

View file

@ -148,7 +148,7 @@ export default class HelpUserSettingsTab extends React.Component<IProps, IState>
<a href="https://mozilla.org" rel="noreferrer noopener" target="_blank"> <a href="https://mozilla.org" rel="noreferrer noopener" target="_blank">
Mozilla Foundation Mozilla Foundation
</a> used under the terms of&nbsp; </a> used under the terms of&nbsp;
<a href="http://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noopener" target="_blank">Apache 2.0</a>. <a href="https://www.apache.org/licenses/LICENSE-2.0" rel="noreferrer noopener" target="_blank">Apache 2.0</a>.
</li> </li>
<li> <li>
The <a href="https://twemoji.twitter.com/" rel="noreferrer noopener" target="_blank"> The <a href="https://twemoji.twitter.com/" rel="noreferrer noopener" target="_blank">

View file

@ -63,7 +63,7 @@ import QuickSettingsButton from "./QuickSettingsButton";
import { useSettingValue } from "../../../hooks/useSettings"; import { useSettingValue } from "../../../hooks/useSettings";
import UserMenu from "../../structures/UserMenu"; import UserMenu from "../../structures/UserMenu";
import IndicatorScrollbar from "../../structures/IndicatorScrollbar"; import IndicatorScrollbar from "../../structures/IndicatorScrollbar";
import { isMac, Key } from "../../../Keyboard"; import { IS_MAC, Key } from "../../../Keyboard";
import { useDispatcher } from "../../../hooks/useDispatcher"; import { useDispatcher } from "../../../hooks/useDispatcher";
import defaultDispatcher from "../../../dispatcher/dispatcher"; import defaultDispatcher from "../../../dispatcher/dispatcher";
import { ActionPayload } from "../../../dispatcher/payloads"; import { ActionPayload } from "../../../dispatcher/payloads";
@ -365,7 +365,7 @@ const SpacePanel = () => {
{ isPanelCollapsed ? _t("Expand") : _t("Collapse") } { isPanelCollapsed ? _t("Expand") : _t("Collapse") }
</div> </div>
<div className="mx_Tooltip_sub"> <div className="mx_Tooltip_sub">
{ isMac { IS_MAC
? "⌘ + ⇧ + D" ? "⌘ + ⇧ + D"
: _t(ALTERNATE_KEY_NAME[Key.CONTROL]) + " + " + : _t(ALTERNATE_KEY_NAME[Key.CONTROL]) + " + " +
_t(ALTERNATE_KEY_NAME[Key.SHIFT]) + " + D" _t(ALTERNATE_KEY_NAME[Key.SHIFT]) + " + D"

View file

@ -16,6 +16,7 @@
import { MatrixClient } from "matrix-js-sdk/src/client"; import { MatrixClient } from "matrix-js-sdk/src/client";
import { ResizeMethod } from "matrix-js-sdk/src/@types/partials"; import { ResizeMethod } from "matrix-js-sdk/src/@types/partials";
import { Optional } from "matrix-events-sdk";
import { MatrixClientPeg } from "../MatrixClientPeg"; import { MatrixClientPeg } from "../MatrixClientPeg";
import { IMediaEventContent, IPreparedMedia, prepEventContentAsMedia } from "./models/IMediaEventContent"; import { IMediaEventContent, IPreparedMedia, prepEventContentAsMedia } from "./models/IMediaEventContent";
@ -60,7 +61,7 @@ export class Media {
* The MXC URI of the thumbnail media, if a thumbnail is recorded. Null/undefined * The MXC URI of the thumbnail media, if a thumbnail is recorded. Null/undefined
* otherwise. * otherwise.
*/ */
public get thumbnailMxc(): string | undefined | null { public get thumbnailMxc(): Optional<string> {
return this.prepared.thumbnail?.mxc; return this.prepared.thumbnail?.mxc;
} }

View file

@ -59,8 +59,8 @@ export default class AutocompleteWrapperModel {
return ac && ac.countCompletions() > 0; return ac && ac.countCompletions() > 0;
} }
public async confirmCompletion(): Promise<void> { public confirmCompletion(): void {
await this.getAutocompleterComponent().onConfirmCompletion(); this.getAutocompleterComponent().onConfirmCompletion();
this.updateCallback({ close: true }); this.updateCallback({ close: true });
} }

View file

@ -173,7 +173,6 @@ export default class EventIndex extends EventEmitter {
// A sync was done, presumably we queued up some live events, // A sync was done, presumably we queued up some live events,
// commit them now. // commit them now.
await indexManager.commitLiveEvents(); await indexManager.commitLiveEvents();
return;
} }
}; };
@ -650,7 +649,6 @@ export default class EventIndex extends EventEmitter {
this.removeListeners(); this.removeListeners();
this.stopCrawler(); this.stopCrawler();
await indexManager.closeEventIndex(); await indexManager.closeEventIndex();
return;
} }
/** /**

View file

@ -165,7 +165,8 @@ export default class PerformanceMonitor {
* @returns {string} a compound of the name and identifier if present * @returns {string} a compound of the name and identifier if present
*/ */
private buildKey(name: string, id?: string): string { private buildKey(name: string, id?: string): string {
return `${name}${id ? `:${id}` : ''}`; const suffix = id ? `:${id}` : '';
return `${name}${suffix}`;
} }
} }

View file

@ -524,7 +524,7 @@ export async function getLogsForReport() {
if (global.mx_rage_store) { if (global.mx_rage_store) {
// flush most recent logs // flush most recent logs
await global.mx_rage_store.flush(); await global.mx_rage_store.flush();
return await global.mx_rage_store.consume(); return global.mx_rage_store.consume();
} else { } else {
return [{ return [{
lines: global.mx_rage_logger.flush(true), lines: global.mx_rage_logger.flush(true),

View file

@ -212,7 +212,7 @@ export default async function sendBugReport(bugReportEndpoint: string, opts: IOp
const body = await collectBugReport(opts); const body = await collectBugReport(opts);
progressCallback(_t("Uploading logs")); progressCallback(_t("Uploading logs"));
return await submitReport(bugReportEndpoint, body, progressCallback); return submitReport(bugReportEndpoint, body, progressCallback);
} }
/** /**

View file

@ -30,7 +30,7 @@ export default class ResizeItem<C extends IConfig = IConfig> {
) { ) {
this.reverse = resizer.isReverseResizeHandle(handle); this.reverse = resizer.isReverseResizeHandle(handle);
if (container) { if (container) {
this.domNode = <HTMLElement>(container); this.domNode = container;
} else { } else {
this.domNode = <HTMLElement>(this.reverse ? handle.nextElementSibling : handle.previousElementSibling); this.domNode = <HTMLElement>(this.reverse ? handle.nextElementSibling : handle.previousElementSibling);
} }

View file

@ -195,11 +195,11 @@ export default class Resizer<C extends IConfig = IConfig> {
return { sizer, distributor }; return { sizer, distributor };
} }
private getResizeHandles() { private getResizeHandles(): HTMLElement[] {
if (this?.config?.handler) { if (this?.config?.handler) {
return [this.config.handler]; return [this.config.handler];
} }
if (!this.container?.children) return []; if (!this.container?.children) return [];
return Array.from(this.container.querySelectorAll(`.${this.classNames.handle}`)) as HTMLElement[]; return Array.from(this.container.querySelectorAll(`.${this.classNames.handle}`));
} }
} }

View file

@ -32,7 +32,7 @@ import SystemFontController from './controllers/SystemFontController';
import UseSystemFontController from './controllers/UseSystemFontController'; import UseSystemFontController from './controllers/UseSystemFontController';
import { SettingLevel } from "./SettingLevel"; import { SettingLevel } from "./SettingLevel";
import SettingController from "./controllers/SettingController"; import SettingController from "./controllers/SettingController";
import { isMac } from '../Keyboard'; import { IS_MAC } from '../Keyboard';
import UIFeatureController from "./controllers/UIFeatureController"; import UIFeatureController from "./controllers/UIFeatureController";
import { UIFeature } from "./UIFeature"; import { UIFeature } from "./UIFeature";
import { OrderedMultiController } from "./controllers/OrderedMultiController"; import { OrderedMultiController } from "./controllers/OrderedMultiController";
@ -592,12 +592,12 @@ export const SETTINGS: {[setting: string]: ISetting} = {
}, },
"ctrlFForSearch": { "ctrlFForSearch": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS, supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: isMac ? _td("Use Command + F to search timeline") : _td("Use Ctrl + F to search timeline"), displayName: IS_MAC ? _td("Use Command + F to search timeline") : _td("Use Ctrl + F to search timeline"),
default: false, default: false,
}, },
"MessageComposerInput.ctrlEnterToSend": { "MessageComposerInput.ctrlEnterToSend": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS, supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: isMac ? _td("Use Command + Enter to send a message") : _td("Use Ctrl + Enter to send a message"), displayName: IS_MAC ? _td("Use Command + Enter to send a message") : _td("Use Ctrl + Enter to send a message"),
default: false, default: false,
}, },
"MessageComposerInput.surroundWith": { "MessageComposerInput.surroundWith": {

View file

@ -60,7 +60,7 @@ export class FontWatcher implements IWatcher {
if (fontSize !== size) { if (fontSize !== size) {
SettingsStore.setValue("baseFontSize", null, SettingLevel.DEVICE, fontSize); SettingsStore.setValue("baseFontSize", null, SettingLevel.DEVICE, fontSize);
} }
(<HTMLElement>document.querySelector(":root")).style.fontSize = toPx(fontSize); document.querySelector<HTMLElement>(":root").style.fontSize = toPx(fontSize);
}; };
private setSystemFont = ({ useSystemFont, font }) => { private setSystemFont = ({ useSystemFont, font }) => {

View file

@ -418,10 +418,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
this.stopPollingLocation(); this.stopPollingLocation();
try { try {
this.clearPositionWatch = await watchPosition( this.clearPositionWatch = watchPosition(this.onWatchedPosition, this.onGeolocationError);
this.onWatchedPosition,
this.onGeolocationError,
);
} catch (error) { } catch (error) {
this.onGeolocationError(error?.message); this.onGeolocationError(error?.message);
// don't set locationInterval if geolocation failed to setup // don't set locationInterval if geolocation failed to setup

View file

@ -49,8 +49,8 @@ export class RoomEchoChamber extends GenericEchoChamber<RoomEchoContext, CachedR
private onAccountData = (event: MatrixEvent) => { private onAccountData = (event: MatrixEvent) => {
if (event.getType() === EventType.PushRules) { if (event.getType() === EventType.PushRules) {
const currentVolume = this.properties.get(CachedRoomKey.NotificationVolume) as RoomNotifState; const currentVolume = this.properties.get(CachedRoomKey.NotificationVolume);
const newVolume = getRoomNotifsState(this.context.room.roomId) as RoomNotifState; const newVolume = getRoomNotifsState(this.context.room.roomId);
if (currentVolume !== newVolume) { if (currentVolume !== newVolume) {
this.updateNotificationVolume(); this.updateNotificationVolume();
} }

View file

@ -141,7 +141,6 @@ export default class RightPanelStore extends ReadyWatchingStore {
const hist = this.byRoom[rId]?.history ?? []; const hist = this.byRoom[rId]?.history ?? [];
hist[hist.length - 1].state = cardState; hist[hist.length - 1].state = cardState;
this.emitAndUpdateSettings(); this.emitAndUpdateSettings();
return;
} else if (targetPhase !== this.currentCard?.phase) { } else if (targetPhase !== this.currentCard?.phase) {
// Set right panel and erase history. // Set right panel and erase history.
this.show(); this.show();

View file

@ -732,7 +732,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
const newPath = new Set(parentPath).add(spaceId); const newPath = new Set(parentPath).add(spaceId);
childSpaces.forEach(childSpace => { childSpaces.forEach(childSpace => {
traverseSpace(childSpace.roomId, newPath) ?? []; traverseSpace(childSpace.roomId, newPath);
}); });
hiddenChildren.get(spaceId)?.forEach(roomId => { hiddenChildren.get(spaceId)?.forEach(roomId => {
roomIds.add(roomId); roomIds.add(roomId);
@ -1076,7 +1076,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
}); });
const enabledMetaSpaces = SettingsStore.getValue("Spaces.enabledMetaSpaces"); const enabledMetaSpaces = SettingsStore.getValue("Spaces.enabledMetaSpaces");
this._enabledMetaSpaces = metaSpaceOrder.filter(k => enabledMetaSpaces[k]) as MetaSpace[]; this._enabledMetaSpaces = metaSpaceOrder.filter(k => enabledMetaSpaces[k]);
this._allRoomsInHome = SettingsStore.getValue("Spaces.allRoomsInHome"); this._allRoomsInHome = SettingsStore.getValue("Spaces.allRoomsInHome");
this.sendUserProperties(); this.sendUserProperties();
@ -1169,8 +1169,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
} }
case Action.SettingUpdated: { case Action.SettingUpdated: {
const settingUpdatedPayload = payload as SettingUpdatedPayload; switch (payload.settingName) {
switch (settingUpdatedPayload.settingName) {
case "Spaces.allRoomsInHome": { case "Spaces.allRoomsInHome": {
const newValue = SettingsStore.getValue("Spaces.allRoomsInHome"); const newValue = SettingsStore.getValue("Spaces.allRoomsInHome");
if (this.allRoomsInHome !== newValue) { if (this.allRoomsInHome !== newValue) {
@ -1186,7 +1185,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
case "Spaces.enabledMetaSpaces": { case "Spaces.enabledMetaSpaces": {
const newValue = SettingsStore.getValue("Spaces.enabledMetaSpaces"); const newValue = SettingsStore.getValue("Spaces.enabledMetaSpaces");
const enabledMetaSpaces = metaSpaceOrder.filter(k => newValue[k]) as MetaSpace[]; const enabledMetaSpaces = metaSpaceOrder.filter(k => newValue[k]);
if (arrayHasDiff(this._enabledMetaSpaces, enabledMetaSpaces)) { if (arrayHasDiff(this._enabledMetaSpaces, enabledMetaSpaces)) {
const hadPeopleOrHomeEnabled = this.enabledMetaSpaces.some(s => { const hadPeopleOrHomeEnabled = this.enabledMetaSpaces.some(s => {
return s === MetaSpace.Home || s === MetaSpace.People; return s === MetaSpace.Home || s === MetaSpace.People;
@ -1217,9 +1216,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
case "Spaces.showPeopleInSpace": case "Spaces.showPeopleInSpace":
// getSpaceFilteredUserIds will return the appropriate value // getSpaceFilteredUserIds will return the appropriate value
this.emit(settingUpdatedPayload.roomId); this.emit(payload.roomId);
if (!this.enabledMetaSpaces.some(s => s === MetaSpace.Home || s === MetaSpace.People)) { if (!this.enabledMetaSpaces.some(s => s === MetaSpace.Home || s === MetaSpace.People)) {
this.updateNotificationStates([settingUpdatedPayload.roomId]); this.updateNotificationStates([payload.roomId]);
} }
break; break;
} }

View file

@ -20,6 +20,7 @@ import { ClientEvent, MatrixClient } from "matrix-js-sdk/src/client";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { EventType } from "matrix-js-sdk/src/@types/event"; import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { Optional } from "matrix-events-sdk";
import { MatrixClientPeg } from '../MatrixClientPeg'; import { MatrixClientPeg } from '../MatrixClientPeg';
@ -159,7 +160,7 @@ export default class DMRoomMap {
return joinedRooms[0]; return joinedRooms[0];
} }
public getUserIdForRoomId(roomId: string) { public getUserIdForRoomId(roomId: string): Optional<string> {
if (this.roomToUser == null) { if (this.roomToUser == null) {
// we lazily populate roomToUser so you can use // we lazily populate roomToUser so you can use
// this class just to call getDMRoomsForUserId // this class just to call getDMRoomsForUserId

View file

@ -261,7 +261,7 @@ async function deriveKeys(salt: Uint8Array, iterations: number, password: string
throw friendlyError('subtleCrypto.importKey failed for HMAC key: ' + e, cryptoFailMsg()); throw friendlyError('subtleCrypto.importKey failed for HMAC key: ' + e, cryptoFailMsg());
}); });
return await Promise.all([aesProm, hmacProm]); return Promise.all([aesProm, hmacProm]);
} }
const HEADER_LINE = '-----BEGIN MEGOLM SESSION DATA-----'; const HEADER_LINE = '-----BEGIN MEGOLM SESSION DATA-----';

View file

@ -136,7 +136,8 @@ export const getCurrentPosition = async (): Promise<GeolocationPosition> => {
export type ClearWatchCallback = () => void; export type ClearWatchCallback = () => void;
export const watchPosition = ( export const watchPosition = (
onWatchPosition: PositionCallback, onWatchPosition: PositionCallback,
onWatchPositionError: (error: GeolocationError) => void): ClearWatchCallback => { onWatchPositionError: (error: GeolocationError) => void,
): ClearWatchCallback => {
try { try {
const onError = (error) => onWatchPositionError(mapGeolocationError(error)); const onError = (error) => onWatchPositionError(mapGeolocationError(error));
const watchId = getGeolocation().watchPosition(onWatchPosition, onError, GeolocationOptions); const watchId = getGeolocation().watchPosition(onWatchPosition, onError, GeolocationOptions);

View file

@ -80,7 +80,9 @@ export const useOwnLiveBeacons = (liveBeaconIds: BeaconIdentifier[]): LiveBeacon
}; };
const onResetLocationPublishError = () => { const onResetLocationPublishError = () => {
liveBeaconIds.map(beaconId => OwnBeaconStore.instance.resetLocationPublishError(beaconId)); liveBeaconIds.forEach(beaconId => {
OwnBeaconStore.instance.resetLocationPublishError(beaconId);
});
}; };
return { return {

View file

@ -23,7 +23,7 @@ export async function getDrawable(url: string): Promise<CanvasImageSource> {
if ('createImageBitmap' in window) { if ('createImageBitmap' in window) {
const response = await fetch(url); const response = await fetch(url);
const blob = await response.blob(); const blob = await response.blob();
return await createImageBitmap(blob); return createImageBitmap(blob);
} else { } else {
return new Promise<HTMLImageElement>((resolve, reject) => { return new Promise<HTMLImageElement>((resolve, reject) => {
const img = document.createElement("img"); const img = document.createElement("img");

View file

@ -34,8 +34,7 @@ import * as Avatar from "../../Avatar";
import EventTile from "../../components/views/rooms/EventTile"; import EventTile from "../../components/views/rooms/EventTile";
import DateSeparator from "../../components/views/messages/DateSeparator"; import DateSeparator from "../../components/views/messages/DateSeparator";
import BaseAvatar from "../../components/views/avatars/BaseAvatar"; import BaseAvatar from "../../components/views/avatars/BaseAvatar";
import { ExportType } from "./exportUtils"; import { ExportType, IExportOptions } from "./exportUtils";
import { IExportOptions } from "./exportUtils";
import MatrixClientContext from "../../contexts/MatrixClientContext"; import MatrixClientContext from "../../contexts/MatrixClientContext";
import getExportCSS from "./exportCSS"; import getExportCSS from "./exportCSS";
import { textForEvent } from "../../TextForEvent"; import { textForEvent } from "../../TextForEvent";
@ -417,7 +416,7 @@ export default class HTMLExporter extends Exporter {
content += body; content += body;
prevEvent = event; prevEvent = event;
} }
return await this.wrapHTML(content); return this.wrapHTML(content);
} }
public async export() { public async export() {

View file

@ -84,8 +84,8 @@ export async function createThumbnail(
} catch (e) { } catch (e) {
// Fallback support for other browsers (Safari and Firefox for now) // Fallback support for other browsers (Safari and Firefox for now)
canvas = document.createElement("canvas"); canvas = document.createElement("canvas");
(canvas as HTMLCanvasElement).width = targetWidth; canvas.width = targetWidth;
(canvas as HTMLCanvasElement).height = targetHeight; canvas.height = targetHeight;
context = canvas.getContext("2d"); context = canvas.getContext("2d");
} }

View file

@ -32,6 +32,8 @@ import MatrixSchemePermalinkConstructor from "./MatrixSchemePermalinkConstructor
// to add to permalinks. The servers are appended as ?via=example.org // to add to permalinks. The servers are appended as ?via=example.org
const MAX_SERVER_CANDIDATES = 3; const MAX_SERVER_CANDIDATES = 3;
const ANY_REGEX = /.*/;
// Permalinks can have servers appended to them so that the user // Permalinks can have servers appended to them so that the user
// receiving them can have a fighting chance at joining the room. // receiving them can have a fighting chance at joining the room.
// These servers are called "candidates" at this point because // These servers are called "candidates" at this point because
@ -207,7 +209,7 @@ export class RoomPermalinkCreator {
private updateAllowedServers() { private updateAllowedServers() {
const bannedHostsRegexps = []; const bannedHostsRegexps = [];
let allowedHostsRegexps = [new RegExp(".*")]; // default allow everyone let allowedHostsRegexps = [ANY_REGEX]; // default allow everyone
if (this.room.currentState) { if (this.room.currentState) {
const aclEvent = this.room.currentState.getStateEvents("m.room.server_acl", ""); const aclEvent = this.room.currentState.getStateEvents("m.room.server_acl", "");
if (aclEvent && aclEvent.getContent()) { if (aclEvent && aclEvent.getContent()) {

View file

@ -23,10 +23,9 @@ import { getE2EEWellKnown } from "./WellKnownUtils";
import dis from "../dispatcher/dispatcher"; import dis from "../dispatcher/dispatcher";
import { getDisplayAliasForAliasSet } from "../Rooms"; import { getDisplayAliasForAliasSet } from "../Rooms";
import { _t } from "../languageHandler"; import { _t } from "../languageHandler";
import { instanceForInstanceId, protocolNameForInstanceId } from "./DirectoryUtils"; import { instanceForInstanceId, protocolNameForInstanceId, ALL_ROOMS, Protocols } from "./DirectoryUtils";
import SdkConfig from "../SdkConfig"; import SdkConfig from "../SdkConfig";
import { GenericError } from "./error"; import { GenericError } from "./error";
import { ALL_ROOMS, Protocols } from "./DirectoryUtils";
export function privateShouldBeEncrypted(): boolean { export function privateShouldBeEncrypted(): boolean {
const e2eeWellKnown = getE2EEWellKnown(); const e2eeWellKnown = getE2EEWellKnown();

View file

@ -16,8 +16,7 @@ limitations under the License.
import React from "react"; import React from "react";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { RoomType } from "matrix-js-sdk/src/@types/event"; import { RoomType, EventType } from "matrix-js-sdk/src/@types/event";
import { EventType } from "matrix-js-sdk/src/@types/event";
import { JoinRule } from "matrix-js-sdk/src/@types/partials"; import { JoinRule } from "matrix-js-sdk/src/@types/partials";
import { calculateRoomVia } from "./permalinks/Permalinks"; import { calculateRoomVia } from "./permalinks/Permalinks";
@ -38,7 +37,6 @@ import { shouldShowComponent } from "../customisations/helpers/UIComponents";
import { UIComponent } from "../settings/UIFeature"; import { UIComponent } from "../settings/UIFeature";
import { OpenSpacePreferencesPayload, SpacePreferenceTab } from "../dispatcher/payloads/OpenSpacePreferencesPayload"; import { OpenSpacePreferencesPayload, SpacePreferenceTab } from "../dispatcher/payloads/OpenSpacePreferencesPayload";
import { OpenSpaceSettingsPayload } from "../dispatcher/payloads/OpenSpaceSettingsPayload"; import { OpenSpaceSettingsPayload } from "../dispatcher/payloads/OpenSpaceSettingsPayload";
import dis from "../dispatcher/dispatcher";
import { OpenAddExistingToSpaceDialogPayload } from "../dispatcher/payloads/OpenAddExistingToSpaceDialogPayload"; import { OpenAddExistingToSpaceDialogPayload } from "../dispatcher/payloads/OpenAddExistingToSpaceDialogPayload";
export const shouldShowSpaceSettings = (space: Room) => { export const shouldShowSpaceSettings = (space: Room) => {
@ -60,14 +58,14 @@ export const makeSpaceParentEvent = (room: Room, canonical = false) => ({
}); });
export function showSpaceSettings(space: Room) { export function showSpaceSettings(space: Room) {
dis.dispatch<OpenSpaceSettingsPayload>({ defaultDispatcher.dispatch<OpenSpaceSettingsPayload>({
action: Action.OpenSpaceSettings, action: Action.OpenSpaceSettings,
space, space,
}); });
} }
export const showAddExistingRooms = (space: Room): void => { export const showAddExistingRooms = (space: Room): void => {
dis.dispatch<OpenAddExistingToSpaceDialogPayload>({ defaultDispatcher.dispatch<OpenAddExistingToSpaceDialogPayload>({
action: Action.OpenAddToExistingSpaceDialog, action: Action.OpenAddToExistingSpaceDialog,
space, space,
}); });
@ -168,7 +166,7 @@ export const bulkSpaceBehaviour = async (
}; };
export const showSpacePreferences = (space: Room, initialTabId?: SpacePreferenceTab) => { export const showSpacePreferences = (space: Room, initialTabId?: SpacePreferenceTab) => {
dis.dispatch<OpenSpacePreferencesPayload>({ defaultDispatcher.dispatch<OpenSpacePreferencesPayload>({
action: Action.OpenSpacePreferences, action: Action.OpenSpacePreferences,
space, space,
initialTabId, initialTabId,

View file

@ -24,7 +24,7 @@ import { logger } from "matrix-js-sdk/src/logger";
export async function copyPlaintext(text: string): Promise<boolean> { export async function copyPlaintext(text: string): Promise<boolean> {
try { try {
if (navigator && navigator.clipboard && navigator.clipboard.writeText) { if (navigator?.clipboard?.writeText) {
await navigator.clipboard.writeText(text); await navigator.clipboard.writeText(text);
return true; return true;
} else { } else {