Improve types for sendStateEvent
(#12331)
This commit is contained in:
parent
4a05de485e
commit
2cbf92860b
17 changed files with 89 additions and 44 deletions
|
@ -18,6 +18,7 @@ import { Page } from "@playwright/test";
|
|||
|
||||
import { test, expect } from "../../element-web-test";
|
||||
import { ElementAppPage } from "../../pages/ElementAppPage";
|
||||
import type { Container } from "../../../src/stores/widgets/types";
|
||||
|
||||
test.describe("Room Header", () => {
|
||||
test.use({
|
||||
|
@ -227,7 +228,7 @@ test.describe("Room Header", () => {
|
|||
{
|
||||
widgets: {
|
||||
[id]: {
|
||||
container: "top",
|
||||
container: "top" as Container,
|
||||
index: 1,
|
||||
width: 100,
|
||||
height: 0,
|
||||
|
|
|
@ -31,6 +31,7 @@ import type {
|
|||
Visibility,
|
||||
UploadOpts,
|
||||
Upload,
|
||||
StateEvents,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { Credentials } from "../plugins/homeserver";
|
||||
|
||||
|
@ -407,7 +408,7 @@ export class Client {
|
|||
const client = await this.prepareClient();
|
||||
return client.evaluate(
|
||||
async (client, { roomId, eventType, content, stateKey }) => {
|
||||
return client.sendStateEvent(roomId, eventType, content, stateKey);
|
||||
return client.sendStateEvent(roomId, eventType as keyof StateEvents, content, stateKey);
|
||||
},
|
||||
{ roomId, eventType, content, stateKey },
|
||||
);
|
||||
|
|
|
@ -16,12 +16,7 @@ limitations under the License.
|
|||
|
||||
import { JSXElementConstructor } from "react";
|
||||
|
||||
export type { NonEmptyArray } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
// Based on https://stackoverflow.com/a/53229857/3532235
|
||||
export type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
|
||||
export type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
|
||||
export type Writeable<T> = { -readonly [P in keyof T]: T[P] };
|
||||
export type { NonEmptyArray, XOR, Writeable } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
export type ComponentClass = keyof JSX.IntrinsicElements | JSXElementConstructor<any>;
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ Response:
|
|||
|
||||
*/
|
||||
|
||||
import { IContent, MatrixEvent, IEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { IContent, MatrixEvent, IEvent, StateEvents } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { MatrixClientPeg } from "./MatrixClientPeg";
|
||||
|
@ -721,7 +721,7 @@ async function getOpenIdToken(event: MessageEvent<any>): Promise<void> {
|
|||
|
||||
async function sendEvent(
|
||||
event: MessageEvent<{
|
||||
type: string;
|
||||
type: keyof StateEvents;
|
||||
state_key?: string;
|
||||
content?: IContent;
|
||||
}>,
|
||||
|
|
|
@ -18,8 +18,9 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import { User, IContent, Direction, ContentHelpers, MRoomTopicEventContent } from "matrix-js-sdk/src/matrix";
|
||||
import { ContentHelpers, Direction, EventType, IContent, MRoomTopicEventContent, User } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { RoomMemberEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import dis from "./dispatcher/dispatcher";
|
||||
import { _t, _td, UserFriendlyError } from "./languageHandler";
|
||||
|
@ -239,12 +240,12 @@ export const Commands = [
|
|||
isEnabled: (cli) => !isCurrentLocalRoom(cli),
|
||||
runFn: function (cli, roomId, threadId, args) {
|
||||
if (args) {
|
||||
const ev = cli.getRoom(roomId)?.currentState.getStateEvents("m.room.member", cli.getSafeUserId());
|
||||
const content = {
|
||||
const ev = cli.getRoom(roomId)?.currentState.getStateEvents(EventType.RoomMember, cli.getSafeUserId());
|
||||
const content: RoomMemberEventContent = {
|
||||
...(ev ? ev.getContent() : { membership: "join" }),
|
||||
displayname: args,
|
||||
};
|
||||
return success(cli.sendStateEvent(roomId, "m.room.member", content, cli.getSafeUserId()));
|
||||
return success(cli.sendStateEvent(roomId, EventType.RoomMember, content, cli.getSafeUserId()));
|
||||
}
|
||||
return reject(this.getUsage());
|
||||
},
|
||||
|
@ -265,7 +266,7 @@ export const Commands = [
|
|||
return success(
|
||||
promise.then((url) => {
|
||||
if (!url) return;
|
||||
return cli.sendStateEvent(roomId, "m.room.avatar", { url }, "");
|
||||
return cli.sendStateEvent(roomId, EventType.RoomAvatar, { url }, "");
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
@ -289,12 +290,12 @@ export const Commands = [
|
|||
return success(
|
||||
promise.then((url) => {
|
||||
if (!url) return;
|
||||
const ev = room?.currentState.getStateEvents("m.room.member", userId);
|
||||
const content = {
|
||||
const ev = room?.currentState.getStateEvents(EventType.RoomMember, userId);
|
||||
const content: RoomMemberEventContent = {
|
||||
...(ev ? ev.getContent() : { membership: "join" }),
|
||||
avatar_url: url,
|
||||
};
|
||||
return cli.sendStateEvent(roomId, "m.room.member", content, userId);
|
||||
return cli.sendStateEvent(roomId, EventType.RoomMember, content, userId);
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -46,6 +46,7 @@ import { RoomHierarchy } from "matrix-js-sdk/src/room-hierarchy";
|
|||
import classNames from "classnames";
|
||||
import { sortBy, uniqBy } from "lodash";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { SpaceChildEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||
import { _t } from "../../languageHandler";
|
||||
|
@ -726,7 +727,7 @@ const ManageButtons: React.FC<IManageButtonsProps> = ({ hierarchy, selected, set
|
|||
const existingContent = hierarchy.getRelation(parentId, childId)?.content;
|
||||
if (!existingContent || existingContent.suggested === suggested) continue;
|
||||
|
||||
const content = {
|
||||
const content: SpaceChildEventContent = {
|
||||
...existingContent,
|
||||
suggested: !selectionAllSuggested,
|
||||
};
|
||||
|
|
|
@ -38,7 +38,7 @@ export const StateEventEditor: React.FC<IEditorProps> = ({ mxEvent, onBack }) =>
|
|||
);
|
||||
|
||||
const onSend = async ([eventType, stateKey]: string[], content: IContent): Promise<void> => {
|
||||
await cli.sendStateEvent(context.room.roomId, eventType, content, stateKey);
|
||||
await cli.sendStateEvent(context.room.roomId, eventType as any, content, stateKey);
|
||||
};
|
||||
|
||||
const defaultContent = mxEvent ? stringify(mxEvent.getContent()) : undefined;
|
||||
|
|
|
@ -15,8 +15,9 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React, { ChangeEvent, ContextType, createRef, SyntheticEvent } from "react";
|
||||
import { IContent, MatrixEvent, EventType } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixEvent, EventType } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { RoomCanonicalAliasEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import EditableItemList from "../elements/EditableItemList";
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
@ -169,7 +170,7 @@ export default class AliasSettings extends React.Component<IProps, IState> {
|
|||
updatingCanonicalAlias: true,
|
||||
});
|
||||
|
||||
const eventContent: IContent = {
|
||||
const eventContent: RoomCanonicalAliasEventContent = {
|
||||
alt_aliases: this.state.altAliases,
|
||||
};
|
||||
|
||||
|
@ -197,7 +198,7 @@ export default class AliasSettings extends React.Component<IProps, IState> {
|
|||
updatingCanonicalAlias: true,
|
||||
});
|
||||
|
||||
const eventContent: IContent = {};
|
||||
const eventContent: RoomCanonicalAliasEventContent = {};
|
||||
|
||||
if (this.state.canonicalAlias) {
|
||||
eventContent["alias"] = this.state.canonicalAlias;
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { MatrixEvent, Room, RoomStateEvent, EventType } from "matrix-js-sdk/src/matrix";
|
||||
import { EventType, MatrixEvent, Room, RoomStateEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Button, Text } from "@vector-im/compound-web";
|
||||
|
||||
|
@ -101,7 +101,7 @@ export default class ThirdPartyMemberInfo extends React.Component<IProps, IState
|
|||
|
||||
public onKickClick = (): void => {
|
||||
MatrixClientPeg.safeGet()
|
||||
.sendStateEvent(this.state.roomId, "m.room.third_party_invite", {}, this.state.stateKey)
|
||||
.sendStateEvent(this.state.roomId, EventType.RoomThirdPartyInvite, {}, this.state.stateKey)
|
||||
.catch((err) => {
|
||||
logger.error(err);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import React from "react";
|
|||
import { EventType, RoomMember, RoomState, RoomStateEvent, Room, IContent } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { throttle, get } from "lodash";
|
||||
import { RoomPowerLevelsEventContent } from "matrix-js-sdk/src/types";
|
||||
|
||||
import { _t, _td, TranslationKey } from "../../../../../languageHandler";
|
||||
import AccessibleButton from "../../../elements/AccessibleButton";
|
||||
|
@ -178,7 +179,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
|||
const client = this.context;
|
||||
const room = this.props.room;
|
||||
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
|
||||
let plContent = plEvent?.getContent() ?? {};
|
||||
let plContent = plEvent?.getContent<RoomPowerLevelsEventContent>() ?? {};
|
||||
|
||||
// Clone the power levels just in case
|
||||
plContent = Object.assign({}, plContent);
|
||||
|
@ -192,7 +193,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
|||
} else {
|
||||
const keyPath = powerLevelKey.split(".");
|
||||
let parentObj: IContent = {};
|
||||
let currentObj = plContent;
|
||||
let currentObj: IContent = plContent;
|
||||
for (const key of keyPath) {
|
||||
if (!currentObj[key]) {
|
||||
currentObj[key] = {};
|
||||
|
@ -222,7 +223,7 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
|
|||
const client = this.context;
|
||||
const room = this.props.room;
|
||||
const plEvent = room.currentState.getStateEvents(EventType.RoomPowerLevels, "");
|
||||
let plContent = plEvent?.getContent() ?? {};
|
||||
let plContent = plEvent?.getContent<RoomPowerLevelsEventContent>() ?? {};
|
||||
|
||||
// Clone the power levels just in case
|
||||
plContent = Object.assign({}, plContent);
|
||||
|
|
|
@ -16,12 +16,14 @@ limitations under the License.
|
|||
|
||||
// Inspiration largely taken from Mjolnir itself
|
||||
|
||||
import { EventType } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { ListRule, RECOMMENDATION_BAN, recommendationToStable } from "./ListRule";
|
||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||
|
||||
export const RULE_USER = "m.policy.rule.user";
|
||||
export const RULE_ROOM = "m.policy.rule.room";
|
||||
export const RULE_SERVER = "m.policy.rule.server";
|
||||
export const RULE_USER = EventType.PolicyRuleUser;
|
||||
export const RULE_ROOM = EventType.PolicyRuleRoom;
|
||||
export const RULE_SERVER = EventType.PolicyRuleServer;
|
||||
|
||||
// m.room.* events are legacy from when MSC2313 changed to m.policy.* last minute.
|
||||
export const USER_RULE_TYPES = [RULE_USER, "m.room.rule.user", "org.matrix.mjolnir.rule.user"];
|
||||
|
@ -29,7 +31,9 @@ export const ROOM_RULE_TYPES = [RULE_ROOM, "m.room.rule.room", "org.matrix.mjoln
|
|||
export const SERVER_RULE_TYPES = [RULE_SERVER, "m.room.rule.server", "org.matrix.mjolnir.rule.server"];
|
||||
export const ALL_RULE_TYPES = [...USER_RULE_TYPES, ...ROOM_RULE_TYPES, ...SERVER_RULE_TYPES];
|
||||
|
||||
export function ruleTypeToStable(rule: string): string | null {
|
||||
export function ruleTypeToStable(
|
||||
rule: string,
|
||||
): EventType.PolicyRuleUser | EventType.PolicyRuleRoom | EventType.PolicyRuleServer | null {
|
||||
if (USER_RULE_TYPES.includes(rule)) {
|
||||
return RULE_USER;
|
||||
}
|
||||
|
@ -72,7 +76,7 @@ export class BanList {
|
|||
{
|
||||
entity: entity,
|
||||
reason: reason,
|
||||
recommendation: recommendationToStable(RECOMMENDATION_BAN, true),
|
||||
recommendation: recommendationToStable(RECOMMENDATION_BAN, true)!,
|
||||
},
|
||||
"rule:" + entity,
|
||||
);
|
||||
|
|
|
@ -14,14 +14,24 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// We are using experimental APIs here, so we need to disable the linter
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { PolicyRecommendation } from "matrix-js-sdk/src/models/invites-ignorer";
|
||||
|
||||
import { MatrixGlob } from "../utils/MatrixGlob";
|
||||
|
||||
// Inspiration largely taken from Mjolnir itself
|
||||
|
||||
export const RECOMMENDATION_BAN = "m.ban";
|
||||
export const RECOMMENDATION_BAN_TYPES = [RECOMMENDATION_BAN, "org.matrix.mjolnir.ban"];
|
||||
export const RECOMMENDATION_BAN = PolicyRecommendation.Ban;
|
||||
export const RECOMMENDATION_BAN_TYPES: PolicyRecommendation[] = [
|
||||
RECOMMENDATION_BAN,
|
||||
"org.matrix.mjolnir.ban" as PolicyRecommendation,
|
||||
];
|
||||
|
||||
export function recommendationToStable(recommendation: string, unstable = true): string | null {
|
||||
export function recommendationToStable(
|
||||
recommendation: PolicyRecommendation,
|
||||
unstable = true,
|
||||
): PolicyRecommendation | null {
|
||||
if (RECOMMENDATION_BAN_TYPES.includes(recommendation)) {
|
||||
return unstable ? RECOMMENDATION_BAN_TYPES[RECOMMENDATION_BAN_TYPES.length - 1] : RECOMMENDATION_BAN;
|
||||
}
|
||||
|
@ -35,7 +45,7 @@ export class ListRule {
|
|||
private readonly _reason: string;
|
||||
private readonly _kind: string;
|
||||
|
||||
public constructor(entity: string, action: string, reason: string, kind: string) {
|
||||
public constructor(entity: string, action: PolicyRecommendation, reason: string, kind: string) {
|
||||
this._glob = new MatrixGlob(entity);
|
||||
this._entity = entity;
|
||||
this._action = recommendationToStable(action, false);
|
||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { MatrixClient, MatrixEvent, RoomState, RoomStateEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixClient, MatrixEvent, RoomState, RoomStateEvent, StateEvents } from "matrix-js-sdk/src/matrix";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import MatrixClientBackedSettingsHandler from "./MatrixClientBackedSettingsHandler";
|
||||
|
@ -24,6 +24,9 @@ import { SettingLevel } from "../SettingLevel";
|
|||
import { WatchManager } from "../WatchManager";
|
||||
|
||||
const DEFAULT_SETTINGS_EVENT_TYPE = "im.vector.web.settings";
|
||||
const PREVIEW_URLS_EVENT_TYPE = "org.matrix.room.preview_urls";
|
||||
|
||||
type RoomSettingsEventType = typeof DEFAULT_SETTINGS_EVENT_TYPE | typeof PREVIEW_URLS_EVENT_TYPE;
|
||||
|
||||
/**
|
||||
* Gets and sets settings at the "room" level.
|
||||
|
@ -88,7 +91,12 @@ export default class RoomSettingsHandler extends MatrixClientBackedSettingsHandl
|
|||
}
|
||||
|
||||
// helper function to send state event then await it being echoed back
|
||||
private async sendStateEvent(roomId: string, eventType: string, field: string, value: any): Promise<void> {
|
||||
private async sendStateEvent<K extends RoomSettingsEventType, F extends keyof StateEvents[K]>(
|
||||
roomId: string,
|
||||
eventType: K,
|
||||
field: F,
|
||||
value: StateEvents[K][F],
|
||||
): Promise<void> {
|
||||
const content = this.getSettings(roomId, eventType) || {};
|
||||
content[field] = value;
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ import {
|
|||
Room,
|
||||
Direction,
|
||||
THREAD_RELATION_TYPE,
|
||||
StateEvents,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import {
|
||||
|
@ -241,7 +242,19 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
|||
return allAllowed;
|
||||
}
|
||||
|
||||
public async sendEvent<K extends keyof StateEvents>(
|
||||
eventType: K,
|
||||
content: StateEvents[K],
|
||||
stateKey?: string,
|
||||
targetRoomId?: string,
|
||||
): Promise<ISendEventDetails>;
|
||||
public async sendEvent(
|
||||
eventType: Exclude<EventType, keyof StateEvents>,
|
||||
content: IContent,
|
||||
stateKey: null,
|
||||
targetRoomId?: string,
|
||||
): Promise<ISendEventDetails>;
|
||||
public async sendEvent<K extends keyof StateEvents>(
|
||||
eventType: string,
|
||||
content: IContent,
|
||||
stateKey?: string | null,
|
||||
|
@ -255,7 +268,7 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
|||
let r: { event_id: string } | null;
|
||||
if (stateKey !== null) {
|
||||
// state event
|
||||
r = await client.sendStateEvent(roomId, eventType, content, stateKey);
|
||||
r = await client.sendStateEvent(roomId, eventType as K, content as StateEvents[K], stateKey);
|
||||
} else if (eventType === EventType.RoomRedaction) {
|
||||
// special case: extract the `redacts` property and call redact
|
||||
r = await client.redactEvent(roomId, content["redacts"]);
|
||||
|
|
|
@ -131,7 +131,7 @@ export async function upgradeRoom(
|
|||
EventType.SpaceChild,
|
||||
{
|
||||
...(currentEv?.getContent() || {}), // copy existing attributes like suggested
|
||||
via: [cli.getDomain()],
|
||||
via: [cli.getDomain()!],
|
||||
},
|
||||
newRoomId,
|
||||
);
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
RoomStateEvent,
|
||||
PendingEventOrdering,
|
||||
ISearchResults,
|
||||
IContent,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { CallType } from "matrix-js-sdk/src/webrtc/call";
|
||||
import { ClientWidgetApi, Widget } from "matrix-widget-api";
|
||||
|
@ -111,7 +112,7 @@ describe("LegacyRoomHeader", () => {
|
|||
room: roomId,
|
||||
user: alice.userId,
|
||||
skey: stateKey,
|
||||
content,
|
||||
content: content as IContent,
|
||||
});
|
||||
room.addLiveEvents([event]);
|
||||
return { event_id: event.getId()! };
|
||||
|
|
|
@ -17,7 +17,15 @@ limitations under the License.
|
|||
import EventEmitter from "events";
|
||||
import { mocked } from "jest-mock";
|
||||
import { waitFor } from "@testing-library/react";
|
||||
import { RoomType, Room, RoomEvent, MatrixEvent, RoomStateEvent, PendingEventOrdering } from "matrix-js-sdk/src/matrix";
|
||||
import {
|
||||
RoomType,
|
||||
Room,
|
||||
RoomEvent,
|
||||
MatrixEvent,
|
||||
RoomStateEvent,
|
||||
PendingEventOrdering,
|
||||
IContent,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { Widget } from "matrix-widget-api";
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { MatrixRTCSessionManagerEvents } from "matrix-js-sdk/src/matrixrtc/MatrixRTCSessionManager";
|
||||
|
@ -116,7 +124,7 @@ const setUpClientRoomAndStores = (): {
|
|||
room: roomId,
|
||||
user: alice.userId,
|
||||
skey: stateKey,
|
||||
content,
|
||||
content: content as IContent,
|
||||
});
|
||||
room.addLiveEvents([event]);
|
||||
return { event_id: event.getId()! };
|
||||
|
|
Loading…
Reference in a new issue