mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-04 19:56:45 +02:00
Add lint rule to protect against this access on unbound methods (#32578)
* Add Actions to ViewModel utility types and specify `this: void` signature Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add https://typescript-eslint.io/rules/unbound-method/ linter to shared-components also fix stray lint config which doesn't apply to SC Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add https://typescript-eslint.io/rules/unbound-method/ linter to element-web Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix genuine issues identified by the linter Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Specify this:void on i18napi Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update Module API Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add comment for MapToVoidThis Added utility type to map VM actions to unbound functions. --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
87b28b725c
commit
77670eb369
@ -199,6 +199,7 @@ module.exports = {
|
||||
files: ["src/**/*.{ts,tsx}", "test/**/*.{ts,tsx}", "playwright/**/*.ts", "*.ts"],
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
rules: {
|
||||
"@typescript-eslint/unbound-method": ["error", { ignoreStatic: true }],
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
@ -238,6 +239,7 @@ module.exports = {
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/explicit-member-accessibility": "off",
|
||||
"@typescript-eslint/no-empty-object-type": "off",
|
||||
"@typescript-eslint/unbound-method": "off",
|
||||
|
||||
// Jest/Playwright specific
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ interface FooViewActions {
|
||||
|
||||
// ViewModel is an object (usually a class) that implements both the interfaces listed above.
|
||||
// https://github.com/element-hq/element-web/blob/develop/packages/shared-components/src/ViewModel.ts
|
||||
export type FooViewModel = ViewModel<FooViewSnapshot> & FooViewActions;
|
||||
export type FooViewModel = ViewModel<FooViewSnapshot, FooViewActions>;
|
||||
|
||||
interface FooViewProps {
|
||||
// Ideally the view only depends on the view model i.e you don't expect any other props here.
|
||||
|
||||
@ -9,9 +9,10 @@ module.exports = {
|
||||
root: true,
|
||||
plugins: ["matrix-org", "eslint-plugin-react-compiler"],
|
||||
extends: [
|
||||
"plugin:matrix-org/babel",
|
||||
"plugin:matrix-org/react",
|
||||
"plugin:matrix-org/a11y",
|
||||
"plugin:matrix-org/typescript",
|
||||
"plugin:matrix-org/react",
|
||||
"plugin:storybook/recommended",
|
||||
],
|
||||
parserOptions: {
|
||||
@ -42,37 +43,35 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
"@typescript-eslint/unbound-method": ["error", { ignoreStatic: true }],
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
allowExpressions: true,
|
||||
},
|
||||
],
|
||||
|
||||
// We're okay being explicit at the moment
|
||||
// "@typescript-eslint/no-empty-interface": "off",
|
||||
// We'd rather not do this but we do
|
||||
// "@typescript-eslint/ban-ts-comment": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-empty-object-type": [
|
||||
"error",
|
||||
{
|
||||
// We do this sometimes to brand interfaces
|
||||
allowInterfaces: "with-single-extends",
|
||||
},
|
||||
],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ["src/**/*.{ts,tsx}", "test/**/*.{ts,tsx}"],
|
||||
extends: ["plugin:matrix-org/typescript", "plugin:matrix-org/react"],
|
||||
files: ["src/**/*.test.{ts,tsx}"],
|
||||
rules: {
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
allowExpressions: true,
|
||||
},
|
||||
],
|
||||
|
||||
// Remove Babel things manually due to override limitations
|
||||
"@babel/no-invalid-this": ["off"],
|
||||
|
||||
// We're okay being explicit at the moment
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
// We disable this while we're transitioning
|
||||
"@typescript-eslint/unbound-method": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
// We'd rather not do this but we do
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
// We're okay with assertion errors when we ask for them
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-empty-object-type": [
|
||||
"error",
|
||||
{
|
||||
// We do this sometimes to brand interfaces
|
||||
allowInterfaces: "with-single-extends",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@ -70,7 +70,7 @@ export interface AudioPlayerViewActions {
|
||||
/**
|
||||
* The view model for the audio player.
|
||||
*/
|
||||
export type AudioPlayerViewModel = ViewModel<AudioPlayerViewSnapshot> & AudioPlayerViewActions;
|
||||
export type AudioPlayerViewModel = ViewModel<AudioPlayerViewSnapshot, AudioPlayerViewActions>;
|
||||
|
||||
interface AudioPlayerViewProps {
|
||||
/**
|
||||
|
||||
@ -84,7 +84,7 @@ interface DecryptionFailureBodyViewProps {
|
||||
/**
|
||||
* React ref to attach to any React components returned
|
||||
*/
|
||||
ref?: React.RefObject<any>;
|
||||
ref?: React.RefObject<HTMLDivElement>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -57,8 +57,10 @@ export interface DisambiguatedProfileViewActions {
|
||||
/**
|
||||
* The view model for DisambiguatedProfileView.
|
||||
*/
|
||||
export type DisambiguatedProfileViewModel = ViewModel<DisambiguatedProfileViewSnapshot> &
|
||||
DisambiguatedProfileViewActions;
|
||||
export type DisambiguatedProfileViewModel = ViewModel<
|
||||
DisambiguatedProfileViewSnapshot,
|
||||
DisambiguatedProfileViewActions
|
||||
>;
|
||||
|
||||
interface DisambiguatedProfileViewProps {
|
||||
/**
|
||||
|
||||
@ -89,7 +89,7 @@ export interface WidgetContextMenuAction {
|
||||
onMoveButton: (direction: number) => void;
|
||||
}
|
||||
|
||||
export type WidgetContextMenuViewModel = ViewModel<WidgetContextMenuSnapshot> & WidgetContextMenuAction;
|
||||
export type WidgetContextMenuViewModel = ViewModel<WidgetContextMenuSnapshot, WidgetContextMenuAction>;
|
||||
|
||||
interface WidgetContextMenuViewProps {
|
||||
vm: WidgetContextMenuViewModel;
|
||||
|
||||
@ -103,7 +103,7 @@ export interface RoomListHeaderViewActions {
|
||||
/**
|
||||
* The view model for the room list header component.
|
||||
*/
|
||||
export type RoomListHeaderViewModel = ViewModel<RoomListHeaderViewSnapshot> & RoomListHeaderViewActions;
|
||||
export type RoomListHeaderViewModel = ViewModel<RoomListHeaderViewSnapshot, RoomListHeaderViewActions>;
|
||||
|
||||
interface RoomListHeaderViewProps {
|
||||
/**
|
||||
|
||||
@ -25,7 +25,7 @@ import type { RoomListItemSnapshot, RoomListItemActions } from "./RoomListItemVi
|
||||
/**
|
||||
* View model type for room list item
|
||||
*/
|
||||
export type RoomItemViewModel = ViewModel<RoomListItemSnapshot> & RoomListItemActions;
|
||||
export type RoomItemViewModel = ViewModel<RoomListItemSnapshot, RoomListItemActions>;
|
||||
|
||||
/**
|
||||
* Props for RoomListItemMoreOptionsMenu component
|
||||
|
||||
@ -21,7 +21,7 @@ import type { RoomListItemSnapshot, RoomListItemActions } from "./RoomListItemVi
|
||||
/**
|
||||
* View model type for room list item
|
||||
*/
|
||||
export type RoomItemViewModel = ViewModel<RoomListItemSnapshot> & RoomListItemActions;
|
||||
export type RoomItemViewModel = ViewModel<RoomListItemSnapshot, RoomListItemActions>;
|
||||
|
||||
/**
|
||||
* Props for RoomListItemNotificationMenu component
|
||||
|
||||
@ -105,7 +105,7 @@ export interface RoomListItemActions {
|
||||
/**
|
||||
* The view model type for a room list item
|
||||
*/
|
||||
export type RoomItemViewModel = ViewModel<RoomListItemSnapshot> & RoomListItemActions;
|
||||
export type RoomItemViewModel = ViewModel<RoomListItemSnapshot, RoomListItemActions>;
|
||||
|
||||
/**
|
||||
* Props for RoomListItemView component
|
||||
|
||||
@ -50,7 +50,7 @@ export interface RoomListSearchViewActions {
|
||||
/**
|
||||
* The view model for the room list search component.
|
||||
*/
|
||||
export type RoomListSearchViewModel = ViewModel<RoomListSearchViewSnapshot> & RoomListSearchViewActions;
|
||||
export type RoomListSearchViewModel = ViewModel<RoomListSearchViewSnapshot, RoomListSearchViewActions>;
|
||||
|
||||
interface RoomListSearchViewProps {
|
||||
/**
|
||||
|
||||
@ -12,7 +12,7 @@ import { RoomListPrimaryFilters, type FilterId } from "../RoomListPrimaryFilters
|
||||
import { RoomListLoadingSkeleton } from "./RoomListLoadingSkeleton";
|
||||
import { RoomListEmptyStateView } from "./RoomListEmptyStateView";
|
||||
import { VirtualizedRoomListView, type RoomListViewState } from "../VirtualizedRoomListView";
|
||||
import { type Room } from "../RoomListItemView";
|
||||
import { type Room, type RoomItemViewModel } from "../RoomListItemView";
|
||||
|
||||
/**
|
||||
* Snapshot for the room list view
|
||||
@ -49,7 +49,7 @@ export interface RoomListViewActions {
|
||||
/** Called to create a new room */
|
||||
createRoom: () => void;
|
||||
/** Get view model for a specific room (virtualization API) */
|
||||
getRoomItemViewModel: (roomId: string) => any;
|
||||
getRoomItemViewModel: (roomId: string) => RoomItemViewModel;
|
||||
/** Called when the visible range changes (virtualization API) */
|
||||
updateVisibleRooms: (startIndex: number, endIndex: number) => void;
|
||||
}
|
||||
@ -57,7 +57,7 @@ export interface RoomListViewActions {
|
||||
/**
|
||||
* The view model type for the room list view
|
||||
*/
|
||||
export type RoomListViewModel = ViewModel<RoomListSnapshot> & RoomListViewActions;
|
||||
export type RoomListViewModel = ViewModel<RoomListSnapshot, RoomListViewActions>;
|
||||
|
||||
/**
|
||||
* Props for RoomListView component
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
import React from "react";
|
||||
import { fn } from "storybook/test";
|
||||
|
||||
import { type Room, type RoomListItemSnapshot, RoomNotifState } from "./RoomListItemView";
|
||||
import { type Room, type RoomItemViewModel, type RoomListItemSnapshot, RoomNotifState } from "./RoomListItemView";
|
||||
|
||||
/**
|
||||
* Mock avatar component for stories
|
||||
@ -39,6 +39,7 @@ export const mockAvatar = (name: string): React.ReactElement => (
|
||||
*/
|
||||
export const renderAvatar = (room: Room): React.ReactElement => {
|
||||
// Cast to any to access properties - in real usage, the room object from the SDK will have these
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return mockAvatar((room as any)?.name || "Room");
|
||||
};
|
||||
|
||||
@ -102,8 +103,8 @@ export const createMockRoomSnapshot = (id: string, name: string, index: number):
|
||||
/**
|
||||
* Create a mock getRoomItemViewModel function for stories
|
||||
*/
|
||||
export const createGetRoomItemViewModel = (roomIds: string[]): ((roomId: string) => any) => {
|
||||
const viewModels = new Map();
|
||||
export const createGetRoomItemViewModel = (roomIds: string[]): ((roomId: string) => RoomItemViewModel) => {
|
||||
const viewModels = new Map<string, RoomItemViewModel>();
|
||||
roomIds.forEach((roomId, index) => {
|
||||
const name = roomNames[index % roomNames.length];
|
||||
const snapshot = createMockRoomSnapshot(roomId, name, index);
|
||||
@ -125,7 +126,7 @@ export const createGetRoomItemViewModel = (roomIds: string[]): ((roomId: string)
|
||||
viewModels.set(roomId, mockViewModel);
|
||||
});
|
||||
|
||||
return (roomId: string) => viewModels.get(roomId);
|
||||
return (roomId: string) => viewModels.get(roomId)!;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -100,7 +100,7 @@ export type RoomStatusBarViewSnapshot =
|
||||
/**
|
||||
* The view model for RoomStatusBarView.
|
||||
*/
|
||||
export type RoomStatusBarViewModel = ViewModel<RoomStatusBarViewSnapshot> & RoomStatusBarViewActions;
|
||||
export type RoomStatusBarViewModel = ViewModel<RoomStatusBarViewSnapshot, RoomStatusBarViewActions>;
|
||||
|
||||
interface RoomStatusBarViewProps {
|
||||
/**
|
||||
|
||||
@ -55,7 +55,7 @@ export function Box({
|
||||
...props
|
||||
}: React.PropsWithChildren<BoxProps>): JSX.Element {
|
||||
const style = useMemo(() => {
|
||||
const style: Record<string, any> = {};
|
||||
const style: Record<string, string> = {};
|
||||
if (flex) style["--mx-box-flex"] = flex;
|
||||
if (shrink) style["--mx-box-shrink"] = shrink;
|
||||
if (grow) style["--mx-box-grow"] = grow;
|
||||
|
||||
@ -11,6 +11,7 @@ import React, { type JSX, type ComponentProps, type JSXElementConstructor, useMe
|
||||
|
||||
import styles from "./Flex.module.css";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type FlexProps<T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>> = {
|
||||
/**
|
||||
* The type of the HTML element
|
||||
@ -60,6 +61,7 @@ type FlexProps<T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any
|
||||
/**
|
||||
* A flexbox container helper
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function Flex<T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any> = "div">({
|
||||
as = "div",
|
||||
display = "flex",
|
||||
|
||||
@ -21,7 +21,7 @@ export class I18nApi implements II18nApi {
|
||||
/**
|
||||
* Register translations for the module, may override app's existing translations
|
||||
*/
|
||||
public register(translations: Partial<Translations>): void {
|
||||
public register(this: void, translations: Partial<Translations>): void {
|
||||
const langs: Record<string, Record<string, string>> = {};
|
||||
|
||||
for (const key in translations) {
|
||||
@ -42,11 +42,9 @@ export class I18nApi implements II18nApi {
|
||||
* @param key - The key to translate
|
||||
* @param variables - Optional variables to interpolate into the translation
|
||||
*/
|
||||
public translate(key: TranslationKey, variables?: Variables): string {
|
||||
public translate(this: void, key: TranslationKey, variables?: Variables): string {
|
||||
return _t(key, variables);
|
||||
}
|
||||
|
||||
public humanizeTime(timeMillis: number): string {
|
||||
return humanizeTime(timeMillis, this);
|
||||
}
|
||||
public humanizeTime = (timeMillis: number): string => humanizeTime(timeMillis, this);
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ export interface IVirtualizedListProps<Item, Context> extends Omit<
|
||||
/**
|
||||
* Utility type for the prop scrollIntoViewOnChange allowing it to be memoised by a caller without repeating types
|
||||
*/
|
||||
export type ScrollIntoViewOnChange<Item, Context = any> = NonNullable<
|
||||
export type ScrollIntoViewOnChange<Item, Context> = NonNullable<
|
||||
VirtuosoProps<Item, VirtualizedListContext<Context>>["scrollIntoViewOnChange"]
|
||||
>;
|
||||
|
||||
@ -124,7 +124,7 @@ export type ScrollIntoViewOnChange<Item, Context = any> = NonNullable<
|
||||
* @template Item - The type of data items in the list
|
||||
* @template Context - The type of additional context data passed to items
|
||||
*/
|
||||
export function VirtualizedList<Item, Context = any>(props: IVirtualizedListProps<Item, Context>): React.ReactElement {
|
||||
export function VirtualizedList<Item, Context>(props: IVirtualizedListProps<Item, Context>): React.ReactElement {
|
||||
// Extract our custom props to avoid conflicts with Virtuoso props
|
||||
const {
|
||||
items,
|
||||
|
||||
@ -9,15 +9,22 @@ Please see LICENSE files in the repository root for full details.
|
||||
* The interface for a generic View Model passed to the shared components.
|
||||
* The snapshot is of type T which is a type specifying a snapshot for the view in question.
|
||||
*/
|
||||
export interface ViewModel<T> {
|
||||
|
||||
// Utility type to map all VM actions to unbound functions so that they do not have
|
||||
// to be called with the correct 'this' context. This prevents "cannot read X of undefined" bugs.
|
||||
type MapToVoidThis<T> = {
|
||||
[K in keyof T]: T[K] extends (...args: infer A) => infer R ? (this: void, ...args: A) => R : T[K];
|
||||
};
|
||||
|
||||
export type ViewModel<Snapshot, Actions = unknown> = {
|
||||
/**
|
||||
* The current snapshot of the view model.
|
||||
*/
|
||||
getSnapshot: () => T;
|
||||
getSnapshot: () => Snapshot;
|
||||
|
||||
/**
|
||||
* Subscribes to changes in the view model.
|
||||
* The listener will be called whenever the snapshot changes.
|
||||
*/
|
||||
subscribe: (listener: () => void) => () => void;
|
||||
}
|
||||
} & MapToVoidThis<Actions>;
|
||||
|
||||
@ -14,7 +14,7 @@ import { type ViewModel } from "./ViewModel";
|
||||
* @param vm The view model to use
|
||||
* @returns The current snapshot
|
||||
*/
|
||||
export function useViewModel<T>(vm: ViewModel<T>): T {
|
||||
export function useViewModel<T>(vm: ViewModel<T, unknown>): T {
|
||||
// We need to pass the same getSnapshot function as getServerSnapshot as this
|
||||
// is used when making the HTML chat export.
|
||||
return useSyncExternalStore(vm.subscribe, vm.getSnapshot, vm.getSnapshot);
|
||||
|
||||
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@ -7,8 +7,8 @@ settings:
|
||||
catalogs:
|
||||
default:
|
||||
'@element-hq/element-web-module-api':
|
||||
specifier: 1.9.0
|
||||
version: 1.9.0
|
||||
specifier: 1.9.1
|
||||
version: 1.9.1
|
||||
'@element-hq/element-web-playwright-common':
|
||||
specifier: 2.2.7
|
||||
version: 2.2.7
|
||||
@ -91,7 +91,7 @@ importers:
|
||||
version: 7.28.6
|
||||
'@element-hq/element-web-module-api':
|
||||
specifier: 'catalog:'
|
||||
version: 1.9.0(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4)
|
||||
version: 1.9.1(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4)
|
||||
'@element-hq/web-shared-components':
|
||||
specifier: workspace:*
|
||||
version: link:packages/shared-components
|
||||
@ -371,7 +371,7 @@ importers:
|
||||
version: 0.16.3
|
||||
'@element-hq/element-web-playwright-common':
|
||||
specifier: 'catalog:'
|
||||
version: 2.2.7(@element-hq/element-web-module-api@1.9.0(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4))(@playwright/test@1.58.2)(playwright-core@1.58.2)
|
||||
version: 2.2.7(@element-hq/element-web-module-api@1.9.1(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4))(@playwright/test@1.58.2)(playwright-core@1.58.2)
|
||||
'@element-hq/element-web-playwright-common-local':
|
||||
specifier: workspace:*
|
||||
version: link:packages/playwright-common
|
||||
@ -743,7 +743,7 @@ importers:
|
||||
dependencies:
|
||||
'@element-hq/element-web-module-api':
|
||||
specifier: 'catalog:'
|
||||
version: 1.9.0(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4)
|
||||
version: 1.9.1(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4)
|
||||
'@matrix-org/spec':
|
||||
specifier: ^1.7.0
|
||||
version: 1.16.0
|
||||
@ -2021,8 +2021,8 @@ packages:
|
||||
'@element-hq/element-call-embedded@0.16.3':
|
||||
resolution: {integrity: sha512-OViKJonDaDNVBUW9WdV9mk78/Ruh34C7XsEgt3O8D9z+64C39elbIgllHSoH5S12IRlv9RYrrV37FZLo6QWsDQ==}
|
||||
|
||||
'@element-hq/element-web-module-api@1.9.0':
|
||||
resolution: {integrity: sha512-Ao/V9w+wysZK4bh61LlKlznF10n2ZbD6KcUI46/zUMttXbmJn3ahvbzhEpwYcD+Cjy3ag5ycxLIIGkKV/fncXg==}
|
||||
'@element-hq/element-web-module-api@1.9.1':
|
||||
resolution: {integrity: sha512-eCHHBkaDWc7Ai10b2VmOAkWIQAsur+YZ2kpFrPFVG41wMXn0PbFL+n6wvpbN+mU5Mg7uVIqXhQn4jflHESBUrA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
peerDependencies:
|
||||
'@matrix-org/react-sdk-module-api': '*'
|
||||
@ -12085,7 +12085,7 @@ snapshots:
|
||||
|
||||
'@element-hq/element-call-embedded@0.16.3': {}
|
||||
|
||||
'@element-hq/element-web-module-api@1.9.0(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4)':
|
||||
'@element-hq/element-web-module-api@1.9.1(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4)':
|
||||
dependencies:
|
||||
'@types/react': 19.2.10
|
||||
'@types/react-dom': 19.2.3(@types/react@19.2.10)
|
||||
@ -12094,10 +12094,10 @@ snapshots:
|
||||
'@matrix-org/react-sdk-module-api': 2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4)
|
||||
matrix-web-i18n: 3.6.0
|
||||
|
||||
'@element-hq/element-web-playwright-common@2.2.7(@element-hq/element-web-module-api@1.9.0(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4))(@playwright/test@1.58.2)(playwright-core@1.58.2)':
|
||||
'@element-hq/element-web-playwright-common@2.2.7(@element-hq/element-web-module-api@1.9.1(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4))(@playwright/test@1.58.2)(playwright-core@1.58.2)':
|
||||
dependencies:
|
||||
'@axe-core/playwright': 4.11.1(playwright-core@1.58.2)
|
||||
'@element-hq/element-web-module-api': 1.9.0(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4)
|
||||
'@element-hq/element-web-module-api': 1.9.1(@matrix-org/react-sdk-module-api@2.5.0(patch_hash=016146c9cc96e6363609d2b2ac0896ccef567882eb1d73b75a77b8a30929de96)(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(matrix-web-i18n@3.6.0)(react@19.2.4)
|
||||
'@playwright/test': 1.58.2
|
||||
'@testcontainers/postgresql': 11.11.0
|
||||
glob: 13.0.6
|
||||
|
||||
@ -16,7 +16,7 @@ catalog:
|
||||
"@element-hq/element-web-playwright-common": 2.2.7
|
||||
"@playwright/test": 1.58.2
|
||||
# Module API
|
||||
"@element-hq/element-web-module-api": 1.9.0
|
||||
"@element-hq/element-web-module-api": 1.9.1
|
||||
# Compound
|
||||
"@vector-im/compound-design-tokens": 6.9.0
|
||||
"@vector-im/compound-web": 8.3.6
|
||||
|
||||
@ -23,8 +23,8 @@ export const DAY_MS = HOUR_MS * 24;
|
||||
*/
|
||||
export function getDaysArray(weekday: Intl.DateTimeFormatOptions["weekday"] = "short"): string[] {
|
||||
const sunday = 1672574400000; // 2023-01-01 12:00 UTC
|
||||
const { format } = new Intl.DateTimeFormat(getUserLanguage(), { weekday, timeZone: "UTC" });
|
||||
return [...Array(7).keys()].map((day) => format(sunday + day * DAY_MS));
|
||||
const dateTimeFormat = new Intl.DateTimeFormat(getUserLanguage(), { weekday, timeZone: "UTC" });
|
||||
return [...Array(7).keys()].map((day) => dateTimeFormat.format(sunday + day * DAY_MS));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -32,8 +32,8 @@ export function getDaysArray(weekday: Intl.DateTimeFormatOptions["weekday"] = "s
|
||||
* @param month - format desired "numeric" | "2-digit" | "long" | "short" | "narrow"
|
||||
*/
|
||||
export function getMonthsArray(month: Intl.DateTimeFormatOptions["month"] = "short"): string[] {
|
||||
const { format } = new Intl.DateTimeFormat(getUserLanguage(), { month, timeZone: "UTC" });
|
||||
return [...Array(12).keys()].map((m) => format(Date.UTC(2021, m)));
|
||||
const dateTimeFormat = new Intl.DateTimeFormat(getUserLanguage(), { month, timeZone: "UTC" });
|
||||
return [...Array(12).keys()].map((m) => dateTimeFormat.format(Date.UTC(2021, m)));
|
||||
}
|
||||
|
||||
// XXX: Ideally we could just specify `hour12: boolean` but it has issues on Chrome in the `en` locale
|
||||
|
||||
@ -93,7 +93,7 @@ export interface IHandle<C extends ComponentType> {
|
||||
*
|
||||
* @param args - Arguments to return to {@link finished}.
|
||||
*/
|
||||
close(...args: OnFinishedParams<C>): void;
|
||||
close(this: void, ...args: OnFinishedParams<C>): void;
|
||||
}
|
||||
|
||||
interface IOptions<C extends ComponentType> {
|
||||
|
||||
@ -171,8 +171,14 @@ interface IProps {
|
||||
handleLeftRight?: boolean;
|
||||
handleInputFields?: boolean;
|
||||
scrollIntoView?: boolean | ScrollIntoViewOptions;
|
||||
children(renderProps: { onKeyDownHandler(ev: React.KeyboardEvent): void; onDragEndHandler(): void }): ReactNode;
|
||||
onKeyDown?(ev: React.KeyboardEvent, state: IState, dispatch: Dispatch<IAction>): void;
|
||||
children(
|
||||
this: void,
|
||||
renderProps: {
|
||||
onKeyDownHandler(this: void, ev: React.KeyboardEvent): void;
|
||||
onDragEndHandler(this: void): void;
|
||||
},
|
||||
): ReactNode;
|
||||
onKeyDown?(this: void, ev: React.KeyboardEvent, state: IState, dispatch: Dispatch<IAction>): void;
|
||||
}
|
||||
|
||||
export const findSiblingElement = (
|
||||
|
||||
@ -16,8 +16,8 @@ import { KeyBindingAction } from "../KeyboardShortcuts";
|
||||
import { getKeyBindingsManager } from "../../KeyBindingsManager";
|
||||
|
||||
interface IProps extends React.ComponentProps<typeof StyledCheckbox> {
|
||||
onChange(): void; // we handle keyup/down ourselves so lose the ChangeEvent
|
||||
onClose(): void; // gets called after onChange on KeyBindingAction.ActivateSelectedButton
|
||||
onChange(this: void): void; // we handle keyup/down ourselves so lose the ChangeEvent
|
||||
onClose(this: void): void; // gets called after onChange on KeyBindingAction.ActivateSelectedButton
|
||||
}
|
||||
|
||||
// Semantic component for representing a styled role=menuitemcheckbox
|
||||
|
||||
@ -17,8 +17,8 @@ import { getKeyBindingsManager } from "../../KeyBindingsManager";
|
||||
|
||||
interface IProps extends React.ComponentProps<typeof StyledRadioButton> {
|
||||
label?: string;
|
||||
onChange(): void; // we handle keyup/down ourselves so lose the ChangeEvent
|
||||
onClose(): void; // gets called after onChange on KeyBindingAction.Enter
|
||||
onChange(this: void): void; // we handle keyup/down ourselves so lose the ChangeEvent
|
||||
onClose(this: void): void; // gets called after onChange on KeyBindingAction.Enter
|
||||
}
|
||||
|
||||
// Semantic component for representing a styled role=menuitemradio
|
||||
|
||||
@ -14,11 +14,14 @@ import { type FocusHandler } from "./types";
|
||||
|
||||
interface IProps {
|
||||
inputRef?: RefObject<HTMLElement | null>;
|
||||
children(renderProps: {
|
||||
onFocus: FocusHandler;
|
||||
isActive: boolean;
|
||||
ref: RefCallback<HTMLElement>;
|
||||
}): ReactElement<any, any>;
|
||||
children(
|
||||
this: void,
|
||||
renderProps: {
|
||||
onFocus: FocusHandler;
|
||||
isActive: boolean;
|
||||
ref: RefCallback<HTMLElement>;
|
||||
},
|
||||
): ReactElement<any, any>;
|
||||
}
|
||||
|
||||
// Wrapper to allow use of useRovingTabIndex outside of React Functional Components.
|
||||
|
||||
@ -116,7 +116,7 @@ const linkFactory =
|
||||
);
|
||||
|
||||
export const UnsupportedBrowserView: React.FC<{
|
||||
onAccept?(): void;
|
||||
onAccept?(this: void): void;
|
||||
}> = ({ onAccept }) => {
|
||||
const config = SdkConfig.get();
|
||||
const brand = config.brand ?? "Element";
|
||||
|
||||
@ -26,7 +26,7 @@ interface NewRecoveryMethodDialogProps {
|
||||
/**
|
||||
* Callback when the dialog is dismissed.
|
||||
*/
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
// Export as default instead of a named export so that it can be dynamically imported with React lazy
|
||||
|
||||
@ -92,9 +92,9 @@ export interface IProps extends MenuProps {
|
||||
closeOnInteraction?: boolean;
|
||||
|
||||
// Function to be called on menu close
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
// on resize callback
|
||||
windowResize?(): void;
|
||||
windowResize?(this: void): void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
||||
@ -16,7 +16,7 @@ import { useRoomState } from "../../hooks/useRoomState.ts";
|
||||
interface IProps {
|
||||
room: Room;
|
||||
parent: HTMLElement | null;
|
||||
onFileDrop(dataTransfer: DataTransfer): void;
|
||||
onFileDrop(this: void, dataTransfer: DataTransfer): void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
|
||||
@ -87,7 +87,7 @@ interface IProps {
|
||||
matrixClient: MatrixClient;
|
||||
// Called with the credentials of a registered user (if they were a ROU that
|
||||
// transitioned to PWLU)
|
||||
onRegistered: (credentials: IMatrixClientCreds) => Promise<MatrixClient>;
|
||||
onRegistered: (this: void, credentials: IMatrixClientCreds) => Promise<MatrixClient>;
|
||||
hideToSRUsers: boolean;
|
||||
// eslint-disable-next-line camelcase
|
||||
page_type?: string;
|
||||
|
||||
@ -2023,7 +2023,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
this.setPageSubtitle();
|
||||
}
|
||||
|
||||
private onLogoutClick(event: ButtonEvent): void {
|
||||
private onLogoutClick(this: void, event: ButtonEvent): void {
|
||||
dis.dispatch({
|
||||
action: "logout",
|
||||
});
|
||||
@ -2047,7 +2047,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
this.stores.resizeNotifier.notifyWindowResized();
|
||||
};
|
||||
|
||||
private dispatchTimelineResize(): void {
|
||||
private dispatchTimelineResize(this: void): void {
|
||||
dis.dispatch({ action: "timeline_resize" });
|
||||
}
|
||||
|
||||
@ -2068,7 +2068,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
};
|
||||
|
||||
// returns a promise which resolves to the new MatrixClient
|
||||
private onRegistered(credentials: IMatrixClientCreds): Promise<MatrixClient> {
|
||||
private onRegistered(this: void, credentials: IMatrixClientCreds): Promise<MatrixClient> {
|
||||
return Lifecycle.setLoggedIn(credentials);
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export default class RoomSearch extends React.PureComponent<IProps> {
|
||||
private openSpotlight(): void {
|
||||
private openSpotlight(this: void): void {
|
||||
defaultDispatcher.fire(Action.OpenSpotlight);
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ interface Props {
|
||||
promise: Promise<ISearchResults>;
|
||||
abortController?: AbortController;
|
||||
className: string;
|
||||
onUpdate(inProgress: boolean, results: ISearchResults | null, error: Error | null): void;
|
||||
onUpdate(this: void, inProgress: boolean, results: ISearchResults | null, error: Error | null): void;
|
||||
ref?: Ref<ScrollPanel>;
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ interface IProps {
|
||||
space: Room;
|
||||
initialText?: string;
|
||||
additionalButtons?: ReactNode;
|
||||
showRoom(cli: MatrixClient, hierarchy: RoomHierarchy, roomId: string, roomType?: RoomType): void;
|
||||
showRoom(this: void, cli: MatrixClient, hierarchy: RoomHierarchy, roomId: string, roomType?: RoomType): void;
|
||||
}
|
||||
|
||||
interface ITileProps {
|
||||
@ -88,9 +88,9 @@ interface ITileProps {
|
||||
numChildRooms?: number;
|
||||
hasPermissions?: boolean;
|
||||
children?: ReactNode;
|
||||
onViewRoomClick(): void;
|
||||
onJoinRoomClick(): Promise<unknown>;
|
||||
onToggleClick?(): void;
|
||||
onViewRoomClick(this: void): void;
|
||||
onJoinRoomClick(this: void): Promise<unknown>;
|
||||
onToggleClick?(this: void): void;
|
||||
}
|
||||
|
||||
const Tile: React.FC<ITileProps> = ({
|
||||
@ -468,9 +468,9 @@ interface IHierarchyLevelProps {
|
||||
hierarchy: RoomHierarchy;
|
||||
parents: Set<string>;
|
||||
selectedMap?: Map<string, Set<string>>;
|
||||
onViewRoomClick(roomId: string, roomType?: RoomType): void;
|
||||
onJoinRoomClick(roomId: string, parents: Set<string>): Promise<unknown>;
|
||||
onToggleClick?(parentId: string, childId: string): void;
|
||||
onViewRoomClick(this: void, roomId: string, roomType?: RoomType): void;
|
||||
onJoinRoomClick(this: void, roomId: string, parents: Set<string>): Promise<unknown>;
|
||||
onToggleClick?(this: void, parentId: string, childId: string): void;
|
||||
}
|
||||
|
||||
export const toLocalRoom = (cli: MatrixClient, room: HierarchyRoom, hierarchy: RoomHierarchy): HierarchyRoom => {
|
||||
@ -600,7 +600,7 @@ export const useRoomHierarchy = (
|
||||
rooms?: HierarchyRoom[];
|
||||
hierarchy?: RoomHierarchy;
|
||||
error?: Error;
|
||||
loadMore(pageSize?: number): Promise<void>;
|
||||
loadMore(this: void, pageSize?: number): Promise<void>;
|
||||
} => {
|
||||
const [rooms, setRooms] = useState<HierarchyRoom[]>([]);
|
||||
const [hierarchy, setHierarchy] = useState<RoomHierarchy>();
|
||||
|
||||
@ -13,7 +13,7 @@ const SpacePillButton: React.FC<{
|
||||
title: string;
|
||||
icon: JSX.Element;
|
||||
description: string;
|
||||
onClick(): void;
|
||||
onClick(this: void): void;
|
||||
}> = ({ title, icon, description, onClick }) => {
|
||||
return (
|
||||
<AccessibleButton className="mx_SpacePillButton" onClick={onClick}>
|
||||
|
||||
@ -304,7 +304,7 @@ const SpaceSetupFirstRooms: React.FC<{
|
||||
space: Room;
|
||||
title: string;
|
||||
description: JSX.Element;
|
||||
onFinished(firstRoomId?: string): void;
|
||||
onFinished(this: void, firstRoomId?: string): void;
|
||||
}> = ({ space, title, description, onFinished }) => {
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
@ -399,7 +399,7 @@ const SpaceSetupFirstRooms: React.FC<{
|
||||
|
||||
const SpaceAddExistingRooms: React.FC<{
|
||||
space: Room;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}> = ({ space, onFinished }) => {
|
||||
return (
|
||||
<div>
|
||||
@ -423,7 +423,7 @@ const SpaceAddExistingRooms: React.FC<{
|
||||
};
|
||||
|
||||
interface ISpaceSetupPublicShareProps extends Pick<IProps & IState, "justCreatedOpts" | "space" | "firstRoomId"> {
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
const SpaceSetupPublicShare: React.FC<ISpaceSetupPublicShareProps> = ({
|
||||
@ -455,7 +455,7 @@ const SpaceSetupPublicShare: React.FC<ISpaceSetupPublicShareProps> = ({
|
||||
const SpaceSetupPrivateScope: React.FC<{
|
||||
space: Room;
|
||||
justCreatedOpts?: IOpts;
|
||||
onFinished(createRooms: boolean): void;
|
||||
onFinished(this: void, createRooms: boolean): void;
|
||||
}> = ({ space, justCreatedOpts, onFinished }) => {
|
||||
return (
|
||||
<div className="mx_SpaceRoomView_privateScope">
|
||||
@ -498,7 +498,7 @@ const validateEmailRules = withValidation({
|
||||
|
||||
const SpaceSetupPrivateInvite: React.FC<{
|
||||
space: Room;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}> = ({ space, onFinished }) => {
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
|
||||
@ -27,7 +27,7 @@ interface Props {
|
||||
*
|
||||
* @param event - The click event
|
||||
*/
|
||||
onLogoutClick: (event: ButtonEvent) => void;
|
||||
onLogoutClick: (this: void, event: ButtonEvent) => void;
|
||||
|
||||
/**
|
||||
* Error that caused `/sync` to fail. If set, an error message will be shown on the splash screen.
|
||||
|
||||
@ -33,7 +33,7 @@ interface IProps extends Omit<ComponentProps<typeof BaseAvatar>, "name" | "idNam
|
||||
roomId?: string;
|
||||
};
|
||||
viewAvatarOnClick?: boolean;
|
||||
onClick?(): void;
|
||||
onClick?(this: void): void;
|
||||
}
|
||||
|
||||
const RoomAvatar: React.FC<IProps> = ({ room, viewAvatarOnClick, onClick, oobData, size = "36px", ...otherProps }) => {
|
||||
|
||||
@ -33,7 +33,7 @@ export interface IProps {
|
||||
matrixClient: MatrixClient;
|
||||
// open the map centered on this beacon's location
|
||||
initialFocusedBeacon?: Beacon;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
// track the 'focused time' as ts
|
||||
|
||||
@ -36,9 +36,9 @@ interface IProps extends Omit<ComponentProps<typeof IconizedContextMenu>, "child
|
||||
userWidget?: boolean;
|
||||
showUnpin?: boolean;
|
||||
// override delete handler
|
||||
onDeleteClick?(): void;
|
||||
onDeleteClick?(this: void): void;
|
||||
// override edit handler
|
||||
onEditClick?(): void;
|
||||
onEditClick?(this: void): void;
|
||||
}
|
||||
|
||||
const showStreamAudioStreamButton = (app: IWidget): boolean => {
|
||||
|
||||
@ -17,8 +17,8 @@ import { AddExistingToSpace, defaultSpacesRenderer, SubspaceSelector } from "./A
|
||||
|
||||
interface IProps {
|
||||
space: Room;
|
||||
onCreateSubspaceClick(): void;
|
||||
onFinished(added?: boolean): void;
|
||||
onCreateSubspaceClick(this: void): void;
|
||||
onFinished(this: void, added?: boolean): void;
|
||||
}
|
||||
|
||||
const AddExistingSubspaceDialog: React.FC<IProps> = ({ space, onCreateSubspaceClick, onFinished }) => {
|
||||
|
||||
@ -43,15 +43,15 @@ const GROUP_MARGIN = 24;
|
||||
|
||||
interface IProps {
|
||||
space: Room;
|
||||
onCreateRoomClick(ev: ButtonEvent): void;
|
||||
onAddSubspaceClick(): void;
|
||||
onFinished(added?: boolean): void;
|
||||
onCreateRoomClick(this: void, ev: ButtonEvent): void;
|
||||
onAddSubspaceClick(this: void): void;
|
||||
onFinished(this: void, added?: boolean): void;
|
||||
}
|
||||
|
||||
export const Entry: React.FC<{
|
||||
room: Room;
|
||||
checked: boolean;
|
||||
onChange?(value: boolean): void;
|
||||
onChange?(this: void, value: boolean): void;
|
||||
}> = ({ room, checked, onChange }) => {
|
||||
const id = useId();
|
||||
return (
|
||||
@ -86,7 +86,7 @@ interface IAddExistingToSpaceProps {
|
||||
footerPrompt?: ReactNode;
|
||||
filterPlaceholder: string;
|
||||
emptySelectionButton?: ReactNode;
|
||||
onFinished(added: boolean): void;
|
||||
onFinished(this: void, added: boolean): void;
|
||||
roomsRenderer?: Renderer;
|
||||
spacesRenderer?: Renderer;
|
||||
dmsRenderer?: Renderer;
|
||||
@ -391,7 +391,7 @@ interface ISubspaceSelectorProps {
|
||||
title: string;
|
||||
space: Room;
|
||||
value: Room;
|
||||
onChange(space: Room): void;
|
||||
onChange(this: void, space: Room): void;
|
||||
}
|
||||
|
||||
export const SubspaceSelector: React.FC<ISubspaceSelectorProps> = ({ title, space, value, onChange }) => {
|
||||
|
||||
@ -23,7 +23,7 @@ export enum ButtonClicked {
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
onFinished(buttonClicked?: ButtonClicked): void;
|
||||
onFinished(this: void, buttonClicked?: ButtonClicked): void;
|
||||
analyticsOwner: string;
|
||||
privacyPolicyUrl?: string;
|
||||
primaryButton?: string;
|
||||
|
||||
@ -21,7 +21,7 @@ import { type SettingKey } from "../../../settings/Settings.tsx";
|
||||
|
||||
interface IProps {
|
||||
featureId: SettingKey;
|
||||
onFinished(sendFeedback?: boolean): void;
|
||||
onFinished(this: void, sendFeedback?: boolean): void;
|
||||
}
|
||||
|
||||
const BetaFeedbackDialog: React.FC<IProps> = ({ featureId, onFinished }) => {
|
||||
|
||||
@ -29,7 +29,7 @@ interface Props {
|
||||
matrixClient: MatrixClient;
|
||||
room: Room;
|
||||
member: RoomMember;
|
||||
onFinished(redact?: boolean): void;
|
||||
onFinished(this: void, redact?: boolean): void;
|
||||
}
|
||||
|
||||
const BulkRedactDialog: React.FC<Props> = (props) => {
|
||||
|
||||
@ -88,7 +88,7 @@ export default class ChangelogDialog extends React.Component<IProps, State> {
|
||||
}
|
||||
}
|
||||
|
||||
private elementsForCommit(commit: Commit): JSX.Element {
|
||||
private elementsForCommit(this: void, commit: Commit): JSX.Element {
|
||||
return (
|
||||
<li key={commit.sha} className="mx_ChangelogDialog_li">
|
||||
<a href={commit.html_url} target="_blank" rel="noreferrer noopener">
|
||||
|
||||
@ -21,8 +21,8 @@ interface IProps extends Omit<BaseProps, "matrixClient" | "children" | "onFinish
|
||||
specificLabel: string;
|
||||
noneLabel?: string;
|
||||
warningMessage?: string;
|
||||
onFinished(success?: boolean, reason?: string, rooms?: Room[]): void;
|
||||
spaceChildFilter?(child: Room): boolean;
|
||||
onFinished(this: void, success?: boolean, reason?: string, rooms?: Room[]): void;
|
||||
spaceChildFilter?(this: void, child: Room): boolean;
|
||||
}
|
||||
|
||||
const ConfirmSpaceUserActionDialog: React.FC<IProps> = ({
|
||||
|
||||
@ -23,8 +23,8 @@ import JoinRuleDropdown from "../elements/JoinRuleDropdown";
|
||||
|
||||
interface IProps {
|
||||
space: Room;
|
||||
onAddExistingSpaceClick(): void;
|
||||
onFinished(added?: boolean): void;
|
||||
onAddExistingSpaceClick(this: void): void;
|
||||
onFinished(this: void, added?: boolean): void;
|
||||
}
|
||||
|
||||
const CreateSubspaceDialog: React.FC<IProps> = ({ space, onAddExistingSpaceClick, onFinished }) => {
|
||||
|
||||
@ -61,7 +61,7 @@ const Tools: Record<Category, [label: TranslationKey, tool: Tool][]> = {
|
||||
interface IProps {
|
||||
roomId: string;
|
||||
threadRootId?: string | null;
|
||||
onFinished(finished?: boolean): void;
|
||||
onFinished(this: void, finished?: boolean): void;
|
||||
}
|
||||
|
||||
type ToolInfo = [label: TranslationKey, tool: Tool];
|
||||
|
||||
@ -37,7 +37,7 @@ import { validateNumberInRange } from "../../../utils/validate";
|
||||
|
||||
interface IProps {
|
||||
room: Room;
|
||||
onFinished(doExport?: boolean): void;
|
||||
onFinished(this: void, doExport?: boolean): void;
|
||||
}
|
||||
|
||||
interface ExportConfig {
|
||||
|
||||
@ -73,7 +73,7 @@ interface IProps {
|
||||
// We need a permalink creator for the source room to pass through to EventTile
|
||||
// in case the event is a reply (even though the user can't get at the link)
|
||||
permalinkCreator: RoomPermalinkCreator;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
interface IEntryProps<K extends keyof TimelineEvents> {
|
||||
@ -81,7 +81,7 @@ interface IEntryProps<K extends keyof TimelineEvents> {
|
||||
type: K;
|
||||
content: TimelineEvents[K];
|
||||
matrixClient: MatrixClient;
|
||||
onFinished(success: boolean): void;
|
||||
onFinished(this: void, success: boolean): void;
|
||||
}
|
||||
|
||||
enum SendState {
|
||||
|
||||
@ -22,7 +22,7 @@ interface IProps {
|
||||
rageshakeLabel?: string;
|
||||
rageshakeData?: Record<string, any>;
|
||||
children?: ReactNode;
|
||||
onFinished(sendFeedback?: boolean): void;
|
||||
onFinished(this: void, sendFeedback?: boolean): void;
|
||||
}
|
||||
|
||||
const GenericFeatureFeedbackDialog: React.FC<IProps> = ({
|
||||
|
||||
@ -16,7 +16,7 @@ import DialogButtons from "../elements/DialogButtons";
|
||||
import { UserTab } from "./UserTab";
|
||||
|
||||
interface IProps {
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
export const IntegrationsDisabledDialog: React.FC<IProps> = ({ onFinished }) => {
|
||||
|
||||
@ -1124,7 +1124,7 @@ export default class InviteDialog extends React.PureComponent<Props, IInviteDial
|
||||
this.setState({ currentTabId: tabId });
|
||||
};
|
||||
|
||||
private async onLinkClick(e: React.MouseEvent<HTMLAnchorElement>): Promise<void> {
|
||||
private async onLinkClick(this: void, e: React.MouseEvent<HTMLAnchorElement>): Promise<void> {
|
||||
e.preventDefault();
|
||||
selectText(e.currentTarget);
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ import { isOnlyAdmin } from "../../../utils/membership";
|
||||
|
||||
interface IProps {
|
||||
space: Room;
|
||||
onFinished(leave: boolean, rooms?: Room[]): void;
|
||||
onFinished(this: void, leave: boolean, rooms?: Room[]): void;
|
||||
}
|
||||
|
||||
const LeaveSpaceDialog: React.FC<IProps> = ({ space, onFinished }) => {
|
||||
|
||||
@ -25,13 +25,13 @@ import { filterBoolean } from "../../../utils/arrays";
|
||||
interface IProps {
|
||||
room: Room;
|
||||
selected?: string[];
|
||||
onFinished(rooms?: string[]): void;
|
||||
onFinished(this: void, rooms?: string[]): void;
|
||||
}
|
||||
|
||||
const Entry: React.FC<{
|
||||
room: Room;
|
||||
checked: boolean;
|
||||
onChange(value: boolean): void;
|
||||
onChange(this: void, value: boolean): void;
|
||||
}> = ({ room, checked, onChange }) => {
|
||||
const localRoom = room instanceof Room;
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ type PollHistoryDialogProps = {
|
||||
room: Room;
|
||||
matrixClient: MatrixClient;
|
||||
permalinkCreator: RoomPermalinkCreator;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
};
|
||||
|
||||
export const PollHistoryDialog: React.FC<PollHistoryDialogProps> = ({
|
||||
|
||||
@ -15,8 +15,8 @@ import DialogButtons from "../elements/DialogButtons";
|
||||
import EmailField from "../auth/EmailField";
|
||||
|
||||
interface IProps {
|
||||
onFinished(continued: false, email?: undefined): void;
|
||||
onFinished(continued: true, email: string): void;
|
||||
onFinished(this: void, continued: false, email?: undefined): void;
|
||||
onFinished(this: void, continued: true, email: string): void;
|
||||
}
|
||||
|
||||
const RegistrationEmailPromptDialog: React.FC<IProps> = ({ onFinished }) => {
|
||||
|
||||
@ -25,7 +25,7 @@ import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
|
||||
interface IProps {
|
||||
roomId: string;
|
||||
onFinished(leave: boolean): void;
|
||||
onFinished(this: void, leave: boolean): void;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -56,7 +56,7 @@ interface BaseProps {
|
||||
/**
|
||||
* A function that is called when the dialog is dismissed
|
||||
*/
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
/**
|
||||
* An optional string to use as the dialog title.
|
||||
* If not provided, an appropriate title for the target type will be used.
|
||||
|
||||
@ -20,7 +20,7 @@ import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
*/
|
||||
interface IProps {
|
||||
roomId: string;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
const SlashCommandHelpDialog: React.FC<IProps> = ({ roomId, onFinished }) => {
|
||||
|
||||
@ -26,7 +26,7 @@ import { SettingsSubsection, SettingsSubsectionText } from "../settings/shared/S
|
||||
|
||||
interface IProps {
|
||||
space: Room;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
const SpacePreferencesAppearanceTab: React.FC<Pick<IProps, "space">> = ({ space }) => {
|
||||
|
||||
@ -39,7 +39,7 @@ export enum SpaceSettingsTab {
|
||||
interface IProps {
|
||||
matrixClient: MatrixClient;
|
||||
space: Room;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
const SpaceSettingsDialog: React.FC<IProps> = ({ matrixClient: cli, space, onFinished }) => {
|
||||
|
||||
@ -31,7 +31,7 @@ interface IProps {
|
||||
* If mode is "sas", the user wants to verify the device with SAS. Otherwise, the dialog was dismissed normally.
|
||||
* @param mode The mode of dismissal.
|
||||
*/
|
||||
onFinished(mode?: "sas"): void;
|
||||
onFinished(this: void, mode?: "sas"): void;
|
||||
}
|
||||
|
||||
const UntrustedDeviceDialog: React.FC<IProps> = ({ device, user, onFinished }) => {
|
||||
|
||||
@ -58,7 +58,7 @@ interface IProps {
|
||||
*/
|
||||
initialEncryptionState?: State;
|
||||
sdkContext: SdkContextClass;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
function titleForTabID(tabId: UserTab): React.ReactNode {
|
||||
|
||||
@ -16,8 +16,8 @@ import { type XOR } from "../../../../@types/common";
|
||||
import { type Tool } from "../DevtoolsDialog";
|
||||
|
||||
export interface IDevtoolsProps {
|
||||
onBack(): void;
|
||||
setTool(label: TranslationKey, tool: Tool): void;
|
||||
onBack(this: void): void;
|
||||
setTool(this: void, label: TranslationKey, tool: Tool): void;
|
||||
}
|
||||
|
||||
interface IMinProps extends Pick<IDevtoolsProps, "onBack"> {
|
||||
@ -28,7 +28,7 @@ interface IMinProps extends Pick<IDevtoolsProps, "onBack"> {
|
||||
|
||||
interface IProps extends IMinProps {
|
||||
actionLabel: TranslationKey;
|
||||
onAction(): Promise<string | void>;
|
||||
onAction(this: void): Promise<string | void>;
|
||||
}
|
||||
|
||||
const BaseTool: React.FC<XOR<IMinProps, IProps>> = ({
|
||||
|
||||
@ -20,7 +20,7 @@ interface KeyBackupProps {
|
||||
/**
|
||||
* Callback to invoke when the back button is clicked.
|
||||
*/
|
||||
onBack(): void;
|
||||
onBack(this: void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -24,7 +24,7 @@ export const stringify = (object: object): string => {
|
||||
interface IEventEditorProps extends Pick<IDevtoolsProps, "onBack"> {
|
||||
fieldDefs: IFieldDef[]; // immutable
|
||||
defaultContent?: string;
|
||||
onSend(fields: string[], content: IContent): Promise<unknown>;
|
||||
onSend(this: void, fields: string[], content: IContent): Promise<unknown>;
|
||||
}
|
||||
|
||||
interface IFieldDef {
|
||||
|
||||
@ -19,7 +19,7 @@ const LOAD_TILES_STEP_SIZE = 50;
|
||||
interface IProps {
|
||||
children: React.ReactElement[];
|
||||
query: string;
|
||||
onChange(value: string): void;
|
||||
onChange(this: void, value: string): void;
|
||||
}
|
||||
|
||||
const FilteredList: React.FC<IProps> = ({ children, query, onChange }) => {
|
||||
|
||||
@ -40,12 +40,12 @@ export const StateEventEditor: React.FC<IEditorProps> = ({ mxEvent, onBack }) =>
|
||||
|
||||
interface StateEventButtonProps {
|
||||
label: string;
|
||||
onClick(): void;
|
||||
onClick(this: void): void;
|
||||
}
|
||||
|
||||
const RoomStateHistory: React.FC<{
|
||||
mxEvent: MatrixEvent;
|
||||
onBack(): void;
|
||||
onBack(this: void): void;
|
||||
}> = ({ mxEvent, onBack }) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const events = useAsyncMemo(
|
||||
|
||||
@ -192,7 +192,7 @@ const EditSetting: React.FC<IEditSettingProps> = ({ setting, onBack }) => {
|
||||
|
||||
interface IViewSettingProps extends Pick<IDevtoolsProps, "onBack"> {
|
||||
setting: SettingKey;
|
||||
onEdit(): Promise<void>;
|
||||
onEdit(this: void): Promise<void>;
|
||||
}
|
||||
|
||||
const ViewSetting: React.FC<IViewSettingProps> = ({ setting, onEdit, onBack }) => {
|
||||
@ -249,8 +249,8 @@ function renderSettingValue(val: any): string {
|
||||
}
|
||||
|
||||
interface ISettingsListProps extends Pick<IDevtoolsProps, "onBack"> {
|
||||
onView(setting: string): void;
|
||||
onEdit(setting: string): void;
|
||||
onView(this: void, setting: string): void;
|
||||
onEdit(this: void, setting: string): void;
|
||||
}
|
||||
|
||||
const SettingsList: React.FC<ISettingsListProps> = ({ onBack, onView, onEdit }) => {
|
||||
|
||||
@ -78,7 +78,7 @@ export const UserList: React.FC<Pick<IDevtoolsProps, "onBack">> = ({ onBack }) =
|
||||
|
||||
interface UserButtonProps {
|
||||
member: RoomMember;
|
||||
onClick(): void;
|
||||
onClick(this: void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -216,7 +216,7 @@ const UserView: React.FC<UserProps> = ({ member, onBack }) => {
|
||||
interface DeviceButtonProps {
|
||||
crypto: CryptoApi;
|
||||
device: Device;
|
||||
onClick(): void;
|
||||
onClick(this: void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -106,7 +106,7 @@ const AVATAR_SIZE = "24px";
|
||||
interface IProps {
|
||||
initialText?: string;
|
||||
initialFilter?: Filter;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
}
|
||||
|
||||
function nodeIsForRecentlyViewed(node?: HTMLElement): boolean {
|
||||
@ -191,7 +191,7 @@ interface IResult extends IBaseResult {
|
||||
avatar: JSX.Element;
|
||||
name: string;
|
||||
description?: string;
|
||||
onClick?(): void;
|
||||
onClick?(this: void): void;
|
||||
}
|
||||
|
||||
type Result = IRoomResult | IPublicRoomResult | IMemberResult | IResult;
|
||||
|
||||
@ -306,7 +306,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
||||
return keys[index <= 0 ? keys.length - 1 : (index - 1) % keys.length];
|
||||
}
|
||||
|
||||
private scrollIntoView(node: Element | null): void {
|
||||
private scrollIntoView(this: void, node: Element | null): void {
|
||||
node?.scrollIntoView({
|
||||
block: "nearest",
|
||||
behavior: "auto",
|
||||
|
||||
@ -31,7 +31,7 @@ interface IProps {
|
||||
// An array of EventTiles to render when expanded
|
||||
"children": ReactNode[] | null;
|
||||
// Called when the event list expansion is toggled
|
||||
onToggle?(): void;
|
||||
onToggle?(this: void): void;
|
||||
// The layout currently used
|
||||
"layout"?: Layout;
|
||||
"data-testid"?: string;
|
||||
|
||||
@ -26,7 +26,7 @@ interface IProps {
|
||||
labelKnock?: string;
|
||||
labelPublic?: string;
|
||||
labelRestricted?: string; // if omitted then this option will be hidden, e.g if unsupported
|
||||
onChange(value: JoinRule): void;
|
||||
onChange(this: void, value: JoinRule): void;
|
||||
}
|
||||
|
||||
const JoinRuleDropdown: React.FC<IProps> = ({
|
||||
|
||||
@ -21,7 +21,7 @@ interface IProps {
|
||||
// Whether or not to disable the checkbox
|
||||
disabled?: boolean;
|
||||
// The function to call when the value changes
|
||||
onChange(checked: boolean): void;
|
||||
onChange(this: void, checked: boolean): void;
|
||||
// Optional additional CSS class to apply to the label
|
||||
className?: string;
|
||||
// The id for the checkbox
|
||||
|
||||
@ -24,9 +24,9 @@ interface IProps {
|
||||
hasAvatar: boolean;
|
||||
noAvatarLabel?: string;
|
||||
hasAvatarLabel?: string;
|
||||
setAvatarUrl(url: string): Promise<unknown>;
|
||||
setAvatarUrl(this: void, url: string): Promise<unknown>;
|
||||
isUserAvatar?: boolean;
|
||||
onClick?(ev: MouseEvent<HTMLInputElement>): void;
|
||||
onClick?(this: void, ev: MouseEvent<HTMLInputElement>): void;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ import { useTypedEventEmitter } from "../../../hooks/useEventEmitter";
|
||||
|
||||
interface IProps {
|
||||
room?: Room;
|
||||
children?(name: string): JSX.Element;
|
||||
children?(this: void, name: string): JSX.Element;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -23,7 +23,7 @@ interface IProps {
|
||||
dialogTitle?: string;
|
||||
serverConfig: ValidatedServerConfig;
|
||||
disabled?: boolean;
|
||||
onServerConfigChange?(config: ValidatedServerConfig): void;
|
||||
onServerConfigChange?(this: void, config: ValidatedServerConfig): void;
|
||||
}
|
||||
|
||||
const showPickerDialog = (
|
||||
|
||||
@ -21,7 +21,7 @@ interface Props {
|
||||
label?: string;
|
||||
isExplicit?: boolean;
|
||||
hideIfCannotSet?: boolean;
|
||||
onChange?(option: string): void;
|
||||
onChange?(this: void, option: string): void;
|
||||
}
|
||||
|
||||
const SettingsDropdown = ({
|
||||
|
||||
@ -19,7 +19,7 @@ interface Props {
|
||||
roomId?: string; // for per-room settings
|
||||
label?: string;
|
||||
isExplicit?: boolean;
|
||||
onChange?(value: string): void;
|
||||
onChange?(this: void, value: string): void;
|
||||
}
|
||||
|
||||
const SettingsField = ({ settingKey, level, roomId, isExplicit, label, onChange: _onSave }: Props): JSX.Element => {
|
||||
|
||||
@ -81,9 +81,9 @@ export default class SpellCheckLanguagesDropdown extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
private onSearchChange(searchQuery: string): void {
|
||||
private onSearchChange = (searchQuery: string): void => {
|
||||
this.setState({ searchQuery });
|
||||
}
|
||||
};
|
||||
|
||||
public render(): React.ReactNode {
|
||||
if (!this.state.languages) {
|
||||
|
||||
@ -27,7 +27,7 @@ interface IProps<T extends string> {
|
||||
value?: T; // if not provided no options will be selected
|
||||
outlined?: boolean;
|
||||
disabled?: boolean;
|
||||
onChange(newValue: T): void;
|
||||
onChange(this: void, newValue: T): void;
|
||||
}
|
||||
|
||||
function StyledRadioGroup<T extends string>({
|
||||
|
||||
@ -25,7 +25,7 @@ interface IProps {
|
||||
tooltip?: string;
|
||||
|
||||
// Called when the checked state changes. First argument will be the new state.
|
||||
onChange(checked: boolean): void;
|
||||
onChange(this: void, checked: boolean): void;
|
||||
|
||||
// id to bind with other elements
|
||||
id?: string;
|
||||
|
||||
@ -33,7 +33,7 @@ interface IArgs<T, D = void> {
|
||||
rules: IRule<T, D>[];
|
||||
description?(this: T, derivedData: D, results: IResult[]): ReactNode;
|
||||
hideDescriptionIfValid?: boolean;
|
||||
deriveData?(data: Data): Promise<D>;
|
||||
deriveData?(this: T, data: Data): Promise<D>;
|
||||
memoize?: boolean;
|
||||
}
|
||||
|
||||
@ -78,8 +78,10 @@ export interface IValidationResult {
|
||||
* the overall validity and a feedback UI that can be rendered for more detail.
|
||||
*/
|
||||
export default function withValidation<T = void, D = void>({
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
description,
|
||||
hideDescriptionIfValid,
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
deriveData,
|
||||
rules,
|
||||
memoize,
|
||||
|
||||
@ -32,7 +32,7 @@ const useMapWithStyle = ({
|
||||
}: {
|
||||
id: string;
|
||||
centerGeoUri?: string;
|
||||
onError?(error: Error): void;
|
||||
onError?(this: void, error: Error): void;
|
||||
interactive?: boolean;
|
||||
bounds?: Bounds;
|
||||
allowGeolocate?: boolean;
|
||||
|
||||
@ -23,7 +23,7 @@ interface Props {
|
||||
|
||||
const ExpandCollapseButton: React.FC<{
|
||||
expanded: boolean;
|
||||
onClick(): void;
|
||||
onClick(this: void): void;
|
||||
}> = ({ expanded, onClick }) => {
|
||||
return (
|
||||
<span className="mx_EventTile_button" onClick={onClick}>
|
||||
|
||||
@ -16,7 +16,7 @@ import { useRoomMemberProfile } from "../../../hooks/room/useRoomMemberProfile";
|
||||
|
||||
interface IProps {
|
||||
mxEvent: MatrixEvent;
|
||||
onClick?(): void;
|
||||
onClick?(this: void): void;
|
||||
withTooltip?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ type PollHistoryProps = {
|
||||
room: Room;
|
||||
matrixClient: MatrixClient;
|
||||
permalinkCreator: RoomPermalinkCreator;
|
||||
onFinished(): void;
|
||||
onFinished(this: void): void;
|
||||
};
|
||||
|
||||
const sortEventsByLatest = (left: MatrixEvent, right: MatrixEvent): number => right.getTs() - left.getTs();
|
||||
|
||||
@ -28,9 +28,9 @@ interface IProps {
|
||||
ariaLabelledBy?: string;
|
||||
withoutScrollContainer?: boolean;
|
||||
closeLabel?: string;
|
||||
onClose?(ev: MouseEvent<HTMLButtonElement>): void;
|
||||
onBack?(ev: MouseEvent<HTMLButtonElement>): void;
|
||||
onKeyDown?(ev: KeyboardEvent): void;
|
||||
onClose?(this: void, ev: MouseEvent<HTMLButtonElement>): void;
|
||||
onBack?(this: void, ev: MouseEvent<HTMLButtonElement>): void;
|
||||
onKeyDown?(this: void, ev: KeyboardEvent): void;
|
||||
cardState?: any;
|
||||
ref?: Ref<HTMLDivElement>;
|
||||
// Ref for the 'close' button the card
|
||||
|
||||
@ -35,7 +35,7 @@ import { WidgetContextMenu } from "../../../viewmodels/right-panel/WidgetContext
|
||||
|
||||
interface Props {
|
||||
room: Room;
|
||||
onClose(): void;
|
||||
onClose(this: void): void;
|
||||
}
|
||||
|
||||
interface IAppRowProps {
|
||||
|
||||
@ -44,7 +44,7 @@ interface PinnedMessagesCardProps {
|
||||
/**
|
||||
* Callback for when the card is closed.
|
||||
*/
|
||||
onClose(): void;
|
||||
onClose(this: void): void;
|
||||
}
|
||||
|
||||
export function PinnedMessagesCard({ room, onClose, permalinkCreator }: PinnedMessagesCardProps): JSX.Element {
|
||||
|
||||
@ -192,7 +192,7 @@ interface IProps {
|
||||
user: Member;
|
||||
room?: Room;
|
||||
phase: RightPanelPhases.MemberInfo | RightPanelPhases.EncryptionPanel;
|
||||
onClose(): void;
|
||||
onClose(this: void): void;
|
||||
verificationRequest?: VerificationRequest;
|
||||
verificationRequestPromise?: Promise<VerificationRequest>;
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ import { WidgetContextMenu } from "../../../viewmodels/right-panel/WidgetContext
|
||||
interface IProps {
|
||||
room: Room;
|
||||
widgetId: string;
|
||||
onClose(): void;
|
||||
onClose(this: void): void;
|
||||
}
|
||||
|
||||
const WidgetCard: React.FC<IProps> = ({ room, widgetId, onClose }) => {
|
||||
|
||||
@ -33,8 +33,8 @@ const Container: React.FC<{
|
||||
interface IBaseProps {
|
||||
member: RoomMember;
|
||||
isUpdating: boolean;
|
||||
startUpdating(): void;
|
||||
stopUpdating(): void;
|
||||
startUpdating(this: void): void;
|
||||
stopUpdating(this: void): void;
|
||||
}
|
||||
|
||||
export const RoomKickButton = ({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user