diff --git a/src/app/components/create-room/utils.ts b/src/app/components/create-room/utils.ts index 394b0226c..957ec3285 100644 --- a/src/app/components/create-room/utils.ts +++ b/src/app/components/create-room/utils.ts @@ -8,6 +8,7 @@ import { } from 'matrix-js-sdk'; import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types'; import { RoomType, StateEvent } from '../../../types/matrix/room'; +import { sendStateEvent } from '../../utils/room'; import { getViaServers } from '../../plugins/via-servers'; import { getMxIdServer } from '../../utils/matrix'; import { CreateRoomAccess } from './types'; @@ -150,9 +151,10 @@ export const createRoom = async (mx: MatrixClient, data: CreateRoomData): Promis const result = await mx.createRoom(options); if (data.parent) { - await mx.sendStateEvent( + await sendStateEvent( + mx, data.parent.roomId, - StateEvent.SpaceChild as any, + StateEvent.SpaceChild, { auto_join: false, suggested: false, diff --git a/src/app/features/add-existing/AddExisting.tsx b/src/app/features/add-existing/AddExisting.tsx index 3a202dc44..e9d974647 100644 --- a/src/app/features/add-existing/AddExisting.tsx +++ b/src/app/features/add-existing/AddExisting.tsx @@ -38,7 +38,7 @@ import { mDirectAtom } from '../../state/mDirectList'; import { roomToParentsAtom } from '../../state/room/roomToParents'; import { useAllJoinedRoomsSet, useGetRoom } from '../../hooks/useGetRoom'; import { VirtualTile } from '../../components/virtualizer'; -import { getDirectRoomAvatarUrl, getRoomAvatarUrl } from '../../utils/room'; +import { getDirectRoomAvatarUrl, getRoomAvatarUrl, sendStateEvent } from '../../utils/room'; import { RoomAvatar, RoomIcon } from '../../components/room-avatar'; import { nameInitials } from '../../utils/common'; import { useMediaAuthentication } from '../../hooks/useMediaAuthentication'; @@ -136,9 +136,10 @@ export function AddExistingModal({ parentId, space, requestClose }: AddExistingM await rateLimitedActions(selectedRooms, async (room) => { const via = getViaServers(room); - await mx.sendStateEvent( + await sendStateEvent( + mx, parentId, - StateEvent.SpaceChild as any, + StateEvent.SpaceChild, { auto_join: false, suggested: false, diff --git a/src/app/features/common-settings/emojis-stickers/RoomPacks.tsx b/src/app/features/common-settings/emojis-stickers/RoomPacks.tsx index 18aa2b96d..eb0b45503 100644 --- a/src/app/features/common-settings/emojis-stickers/RoomPacks.tsx +++ b/src/app/features/common-settings/emojis-stickers/RoomPacks.tsx @@ -35,6 +35,7 @@ import { mxcUrlToHttp } from '../../../utils/matrix'; import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; import { usePowerLevels } from '../../../hooks/usePowerLevels'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { suffixRename } from '../../../utils/common'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useAlive } from '../../../hooks/useAlive'; @@ -57,7 +58,7 @@ function CreatePackTile({ packs, roomId }: CreatePackTileProps) { display_name: name, }, }; - await mx.sendStateEvent(roomId, StateEvent.PoniesRoomEmotes as any, content, stateKey); + await sendStateEvent(mx, roomId, StateEvent.PoniesRoomEmotes, content, stateKey); }, [mx, roomId], ), @@ -164,7 +165,7 @@ export function RoomPacks({ onViewPack }: RoomPacksProps) { for (let i = 0; i < removedPacks.length; i += 1) { const addr = removedPacks[i]; // eslint-disable-next-line no-await-in-loop - await mx.sendStateEvent(room.roomId, StateEvent.PoniesRoomEmotes as any, {}, addr.stateKey); + await sendStateEvent(mx, room.roomId, StateEvent.PoniesRoomEmotes, {}, addr.stateKey); } }, [mx, room, removedPacks]), ); diff --git a/src/app/features/common-settings/general/RoomEncryption.tsx b/src/app/features/common-settings/general/RoomEncryption.tsx index 90d4f616a..e615cdb87 100644 --- a/src/app/features/common-settings/general/RoomEncryption.tsx +++ b/src/app/features/common-settings/general/RoomEncryption.tsx @@ -23,6 +23,7 @@ import { SequenceCardStyle } from '../../room-settings/styles.css'; import { SettingTile } from '../../../components/setting-tile'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useRoom } from '../../../hooks/useRoom'; import { useStateEvent } from '../../../hooks/useStateEvent'; @@ -48,7 +49,7 @@ export function RoomEncryption({ permissions }: RoomEncryptionProps) { const [enableState, enable] = useAsyncCallback( useCallback(async () => { - await mx.sendStateEvent(room.roomId, StateEvent.RoomEncryption as any, { + await sendStateEvent(mx, room.roomId, StateEvent.RoomEncryption, { algorithm: ROOM_ENC_ALGO, }); }, [mx, room.roomId]), diff --git a/src/app/features/common-settings/general/RoomHistoryVisibility.tsx b/src/app/features/common-settings/general/RoomHistoryVisibility.tsx index 6071baeb7..198ed2dcf 100644 --- a/src/app/features/common-settings/general/RoomHistoryVisibility.tsx +++ b/src/app/features/common-settings/general/RoomHistoryVisibility.tsx @@ -21,6 +21,7 @@ import { SettingTile } from '../../../components/setting-tile'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useRoom } from '../../../hooks/useRoom'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useStateEvent } from '../../../hooks/useStateEvent'; import { stopPropagation } from '../../../utils/keyboard'; @@ -76,7 +77,7 @@ export function RoomHistoryVisibility({ permissions }: RoomHistoryVisibilityProp const content: RoomHistoryVisibilityEventContent = { history_visibility: visibility, }; - await mx.sendStateEvent(room.roomId, StateEvent.RoomHistoryVisibility as any, content); + await sendStateEvent(mx, room.roomId, StateEvent.RoomHistoryVisibility, content); }, [mx, room.roomId], ), diff --git a/src/app/features/common-settings/general/RoomJoinRules.tsx b/src/app/features/common-settings/general/RoomJoinRules.tsx index 3526aea1d..2e875ea24 100644 --- a/src/app/features/common-settings/general/RoomJoinRules.tsx +++ b/src/app/features/common-settings/general/RoomJoinRules.tsx @@ -18,7 +18,7 @@ import { StateEvent } from '../../../../types/matrix/room'; import { useStateEvent } from '../../../hooks/useStateEvent'; import { useSpaceOptionally } from '../../../hooks/useSpace'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; -import { getStateEvents } from '../../../utils/room'; +import { getStateEvents, sendStateEvent } from '../../../utils/room'; import { useRecursiveChildSpaceScopeFactory, useSpaceChildren, @@ -111,7 +111,7 @@ export function RoomJoinRules({ permissions }: RoomJoinRulesProps) { join_rule: joinRule as JoinRule, }; if (allow.length > 0) c.allow = allow; - await mx.sendStateEvent(room.roomId, StateEvent.RoomJoinRules as any, c); + await sendStateEvent(mx, room.roomId, StateEvent.RoomJoinRules, c); }, [mx, room, space, subspaces, roomIdToParents], ), diff --git a/src/app/features/common-settings/general/RoomProfile.tsx b/src/app/features/common-settings/general/RoomProfile.tsx index 96dcb8157..b9e7c8b84 100644 --- a/src/app/features/common-settings/general/RoomProfile.tsx +++ b/src/app/features/common-settings/general/RoomProfile.tsx @@ -39,6 +39,7 @@ import { mxcUrlToHttp } from '../../../utils/matrix'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { CompactUploadCardRenderer } from '../../../components/upload-card'; import { useObjectURL } from '../../../hooks/useObjectURL'; import { createUploadAtom, UploadSuccess } from '../../../state/upload'; @@ -152,16 +153,16 @@ export function RoomProfileEdit({ useCallback( async (roomAvatarMxc?: string | null, roomName?: string, roomTopic?: string) => { if (roomAvatarMxc !== undefined) { - await mx.sendStateEvent(room.roomId, StateEvent.RoomAvatar as any, { + await sendStateEvent(mx, room.roomId, StateEvent.RoomAvatar, { url: roomAvatarMxc, }); } if (roomName !== undefined) { - await mx.sendStateEvent(room.roomId, StateEvent.RoomName as any, { name: roomName }); + await sendStateEvent(mx, room.roomId, StateEvent.RoomName, { name: roomName }); } if (roomTopic !== undefined) { const topicContent = buildTopicContent(roomTopic); - await mx.sendStateEvent(room.roomId, StateEvent.RoomTopic as any, topicContent); + await sendStateEvent(mx, room.roomId, StateEvent.RoomTopic, topicContent); } }, [mx, room.roomId], diff --git a/src/app/features/common-settings/general/RoomQuality.tsx b/src/app/features/common-settings/general/RoomQuality.tsx index aa8322f75..292d4a148 100644 --- a/src/app/features/common-settings/general/RoomQuality.tsx +++ b/src/app/features/common-settings/general/RoomQuality.tsx @@ -7,6 +7,7 @@ import { SettingsSelect } from '../../../components/settings-select/SettingsSele import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useRoom } from '../../../hooks/useRoom'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { useStateEvent } from '../../../hooks/useStateEvent'; import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; @@ -55,7 +56,7 @@ export function RoomQuality({ permissions }: RoomQualityProps) { useCallback( async (next: RoomQualityContent) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any - await mx.sendStateEvent(room.roomId, StateEvent.LotusRoomQuality as any, next); + await sendStateEvent(mx, room.roomId, StateEvent.LotusRoomQuality, next); }, [mx, room.roomId], ), diff --git a/src/app/features/common-settings/general/RoomRetention.tsx b/src/app/features/common-settings/general/RoomRetention.tsx index 753a47b33..0f78f77c2 100644 --- a/src/app/features/common-settings/general/RoomRetention.tsx +++ b/src/app/features/common-settings/general/RoomRetention.tsx @@ -7,6 +7,7 @@ import { SettingTile } from '../../../components/setting-tile'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useRoom } from '../../../hooks/useRoom'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useStateEvent } from '../../../hooks/useStateEvent'; import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions'; @@ -31,7 +32,7 @@ export function RoomRetention({ permissions }: RoomRetentionProps) { // Lotus custom-state convention: cast the type key (RoomRetention isn't a // typed key in the SDK's StateEvents map). // eslint-disable-next-line @typescript-eslint/no-explicit-any - await mx.sendStateEvent(room.roomId, StateEvent.RoomRetention as any, content); + await sendStateEvent(mx, room.roomId, StateEvent.RoomRetention, content); }, [mx, room.roomId], ), diff --git a/src/app/features/common-settings/general/RoomVoiceLimit.tsx b/src/app/features/common-settings/general/RoomVoiceLimit.tsx index 89df85297..55ca87e75 100644 --- a/src/app/features/common-settings/general/RoomVoiceLimit.tsx +++ b/src/app/features/common-settings/general/RoomVoiceLimit.tsx @@ -7,6 +7,7 @@ import { SettingTile } from '../../../components/setting-tile'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useRoom } from '../../../hooks/useRoom'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useStateEvent } from '../../../hooks/useStateEvent'; import { RoomPermissionsAPI } from '../../../hooks/useRoomPermissions'; @@ -31,7 +32,7 @@ export function RoomVoiceLimit({ permissions }: RoomVoiceLimitProps) { useCallback( async (value: number) => { const content: VoiceLimitContent = value > 0 ? { max_users: value } : {}; - await mx.sendStateEvent(room.roomId, StateEvent.LotusVoiceLimit as any, content); + await sendStateEvent(mx, room.roomId, StateEvent.LotusVoiceLimit, content); }, [mx, room.roomId], ), diff --git a/src/app/features/common-settings/permissions/PermissionGroups.tsx b/src/app/features/common-settings/permissions/PermissionGroups.tsx index 27acac2f9..39b6a520f 100644 --- a/src/app/features/common-settings/permissions/PermissionGroups.tsx +++ b/src/app/features/common-settings/permissions/PermissionGroups.tsx @@ -15,6 +15,7 @@ import { getPowerLevelTag, getPowers, usePowerLevelTags } from '../../../hooks/u import { useRoom } from '../../../hooks/useRoom'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { PowerSwitcher } from '../../../components/power'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { useAlive } from '../../../hooks/useAlive'; @@ -84,7 +85,7 @@ export function PermissionGroups({ return draftPowerLevels; }); - await mx.sendStateEvent(room.roomId, StateEvent.RoomPowerLevels as any, editedPowerLevels); + await sendStateEvent(mx, room.roomId, StateEvent.RoomPowerLevels, editedPowerLevels); }, [mx, room, powerLevels, permissionUpdate, permissionGroups]), ); diff --git a/src/app/features/common-settings/permissions/PowersEditor.tsx b/src/app/features/common-settings/permissions/PowersEditor.tsx index f577621cc..469b49c01 100644 --- a/src/app/features/common-settings/permissions/PowersEditor.tsx +++ b/src/app/features/common-settings/permissions/PowersEditor.tsx @@ -45,6 +45,7 @@ import { CompactUploadCardRenderer } from '../../../components/upload-card'; import { createUploadAtom, UploadSuccess } from '../../../state/upload'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { MemberPowerTag, MemberPowerTagIcon, StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { useAlive } from '../../../hooks/useAlive'; import { BetaNoticeBadge } from '../../../components/BetaNoticeBadge'; import { getPowerTagIconSrc } from '../../../hooks/useMemberPowerTag'; @@ -335,7 +336,7 @@ export function PowersEditor({ powerLevels, requestClose }: PowersEditorProps) { deleted.forEach((power) => { delete content[power]; }); - await mx.sendStateEvent(room.roomId, StateEvent.PowerLevelTags as any, content); + await sendStateEvent(mx, room.roomId, StateEvent.PowerLevelTags, content); }, [mx, room, powerLevelTags, editedPowerTags, deleted]), ); diff --git a/src/app/features/lobby/HierarchyItemMenu.tsx b/src/app/features/lobby/HierarchyItemMenu.tsx index 63bdbb63e..fa921c33d 100644 --- a/src/app/features/lobby/HierarchyItemMenu.tsx +++ b/src/app/features/lobby/HierarchyItemMenu.tsx @@ -18,6 +18,7 @@ import { import { HierarchyItem } from '../../hooks/useSpaceHierarchy'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { MSpaceChildContent, StateEvent } from '../../../types/matrix/room'; +import { sendStateEvent } from '../../utils/room'; import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback'; import { UseStateProvider } from '../../components/UseStateProvider'; import { LeaveSpacePrompt } from '../../components/leave-space-prompt'; @@ -48,7 +49,7 @@ function SuggestMenuItem({ const [toggleState, handleToggleSuggested] = useAsyncCallback( useCallback(() => { const newContent: MSpaceChildContent = { ...content, suggested: !content.suggested }; - return mx.sendStateEvent(parentId, StateEvent.SpaceChild as any, newContent, roomId); + return sendStateEvent(mx, parentId, StateEvent.SpaceChild, newContent, roomId); }, [mx, parentId, roomId, content]), ); @@ -85,7 +86,7 @@ function RemoveMenuItem({ const [removeState, handleRemove] = useAsyncCallback( useCallback( - () => mx.sendStateEvent(parentId, StateEvent.SpaceChild as any, {}, roomId), + () => sendStateEvent(mx, parentId, StateEvent.SpaceChild, {}, roomId), [mx, parentId, roomId], ), ); diff --git a/src/app/features/lobby/Lobby.tsx b/src/app/features/lobby/Lobby.tsx index ab3ab31a6..bb43554ed 100644 --- a/src/app/features/lobby/Lobby.tsx +++ b/src/app/features/lobby/Lobby.tsx @@ -40,7 +40,7 @@ import { getSpaceRoomPath, withSearchParam } from '../../pages/pathUtils'; import { StateEvent } from '../../../types/matrix/room'; import { CanDropCallback, useDnDMonitor } from './DnD'; import { ASCIILexicalTable, orderKeys } from '../../utils/ASCIILexicalTable'; -import { getStateEvent } from '../../utils/room'; +import { getStateEvent, sendStateEvent } from '../../utils/room'; import { setAccountData } from '../../utils/accountData'; import { useClosedLobbyCategoriesAtom } from '../../state/hooks/closedLobbyCategories'; import { @@ -272,9 +272,10 @@ export function Lobby() { if (reorders) { await rateLimitedActions(reorders, async (reorder) => { if (!reorder.item.parentId) return; - await mx.sendStateEvent( + await sendStateEvent( + mx, reorder.item.parentId, - StateEvent.SpaceChild as any, + StateEvent.SpaceChild, { ...reorder.item.content, order: reorder.orderKey }, reorder.item.roomId, ); @@ -299,7 +300,7 @@ export function Lobby() { // remove from current space if (item.parentId !== containerParentId) { - mx.sendStateEvent(item.parentId, StateEvent.SpaceChild as any, {}, item.roomId); + sendStateEvent(mx, item.parentId, StateEvent.SpaceChild, {}, item.roomId); } if ( @@ -319,7 +320,7 @@ export function Lobby() { joinRuleContent.allow?.filter((allowRule) => allowRule.room_id !== item.parentId) ?? []; allow.push({ type: RestrictedAllowType.RoomMembership, room_id: containerParentId }); - mx.sendStateEvent(itemRoom.roomId, StateEvent.RoomJoinRules as any, { + sendStateEvent(mx, itemRoom.roomId, StateEvent.RoomJoinRules, { ...joinRuleContent, allow, }); @@ -359,9 +360,10 @@ export function Lobby() { if (reorders) { await rateLimitedActions(reorders, async (reorder) => { - await mx.sendStateEvent( + await sendStateEvent( + mx, containerParentId, - StateEvent.SpaceChild as any, + StateEvent.SpaceChild, { ...reorder.item.content, order: reorder.orderKey }, reorder.item.roomId, ); diff --git a/src/app/features/room-settings/RoomServerACL.tsx b/src/app/features/room-settings/RoomServerACL.tsx index 70b3dba14..089682567 100644 --- a/src/app/features/room-settings/RoomServerACL.tsx +++ b/src/app/features/room-settings/RoomServerACL.tsx @@ -24,6 +24,7 @@ import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useRoom } from '../../hooks/useRoom'; import { useStateEvent } from '../../hooks/useStateEvent'; import { StateEvent } from '../../../types/matrix/room'; +import { sendStateEvent } from '../../utils/room'; import { usePowerLevels, readPowerLevel } from '../../hooks/usePowerLevels'; import { useRoomCreators } from '../../hooks/useRoomCreators'; import { useRoomPermissions } from '../../hooks/useRoomPermissions'; @@ -250,7 +251,7 @@ export function RoomServerACL({ requestClose }: RoomServerACLProps) { // Save handler const [saveState, save] = useAsyncCallback( useCallback(async () => { - await mx.sendStateEvent(room.roomId, StateEvent.RoomServerAcl as any, { + await sendStateEvent(mx, room.roomId, StateEvent.RoomServerAcl, { allow: allowList, deny: denyList, allow_ip_literals: allowIpLiterals, diff --git a/src/app/features/room/message/Message.tsx b/src/app/features/room/message/Message.tsx index fe729514f..9a1d15f63 100644 --- a/src/app/features/room/message/Message.tsx +++ b/src/app/features/room/message/Message.tsx @@ -54,6 +54,7 @@ import { getEventEdits, getMemberAvatarMxc, getMemberName, + sendStateEvent, } from '../../../utils/room'; import { mxcUrlToHttp } from '../../../utils/matrix'; import { messageAriaLabel } from '../../../utils/a11y'; @@ -428,7 +429,7 @@ export const MessagePinItem = as< if (!isPinned && eventId) { pinContent.pinned.push(eventId); } - mx.sendStateEvent(room.roomId, StateEvent.RoomPinnedEvents as any, pinContent); + sendStateEvent(mx, room.roomId, StateEvent.RoomPinnedEvents, pinContent); onClose?.(); }; diff --git a/src/app/features/room/room-pin-menu/RoomPinMenu.tsx b/src/app/features/room/room-pin-menu/RoomPinMenu.tsx index 10e3a9d56..859d0a463 100644 --- a/src/app/features/room/room-pin-menu/RoomPinMenu.tsx +++ b/src/app/features/room/room-pin-menu/RoomPinMenu.tsx @@ -47,6 +47,7 @@ import { getMemberAvatarMxc, getMemberName, getStateEvent, + sendStateEvent, } from '../../../utils/room'; import { GetContentCallback, MessageEvent, StateEvent } from '../../../../types/matrix/room'; import { useMentionClickHandler } from '../../../hooks/useMentionClickHandler'; @@ -122,7 +123,7 @@ function PinnedMessage({ pinned: content.pinned.filter((id) => id !== eventId), }; - return mx.sendStateEvent(room.roomId, StateEvent.RoomPinnedEvents as any, newContent); + return sendStateEvent(mx, room.roomId, StateEvent.RoomPinnedEvents, newContent); }, [room, eventId, mx]), ); diff --git a/src/app/features/room/widgets/WidgetsPanel.tsx b/src/app/features/room/widgets/WidgetsPanel.tsx index d51ac373b..c93a1b60e 100644 --- a/src/app/features/room/widgets/WidgetsPanel.tsx +++ b/src/app/features/room/widgets/WidgetsPanel.tsx @@ -26,6 +26,7 @@ import { usePowerLevelsContext } from '../../../hooks/usePowerLevels'; import { useRoomCreators } from '../../../hooks/useRoomCreators'; import { useRoomPermissions } from '../../../hooks/useRoomPermissions'; import { StateEvent } from '../../../../types/matrix/room'; +import { sendStateEvent } from '../../../utils/room'; import { generateWidgetId, validateWidgetUrl, WidgetUrlError } from './widgetUtils'; const urlErrorMessage = (err: WidgetUrlError): string => { @@ -84,7 +85,7 @@ export function WidgetsPanel({ room, requestClose }: WidgetsPanelProps) { }; try { // eslint-disable-next-line @typescript-eslint/no-explicit-any - await mx.sendStateEvent(room.roomId, StateEvent.Widget as any, content as any, id); + await sendStateEvent(mx, room.roomId, StateEvent.Widget, content, id); setAdding(false); } catch (e) { setError((e as Error).message); @@ -96,7 +97,7 @@ export function WidgetsPanel({ room, requestClose }: WidgetsPanelProps) { const handleRemove = (id: string) => { if (viewingId === id) setViewingId(null); // eslint-disable-next-line @typescript-eslint/no-explicit-any - mx.sendStateEvent(room.roomId, StateEvent.Widget as any, {} as any, id).catch(() => undefined); + sendStateEvent(mx, room.roomId, StateEvent.Widget, {}, id).catch(() => undefined); }; return ( diff --git a/src/app/hooks/useCommands.ts b/src/app/hooks/useCommands.ts index 6caeaaddd..8e3e33d88 100644 --- a/src/app/hooks/useCommands.ts +++ b/src/app/hooks/useCommands.ts @@ -24,7 +24,7 @@ import { } from '../utils/matrix'; import { useRoomNavigate } from './useRoomNavigate'; import { Membership, StateEvent } from '../../types/matrix/room'; -import { getStateEvent } from '../utils/room'; +import { getStateEvent, sendStateEvent } from '../utils/room'; import { splitWithSpace } from '../utils/common'; import { createRoomEncryptionState } from '../components/create-room'; @@ -368,9 +368,10 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { ?.getStateEvents(StateEvent.RoomMember, mx.getSafeUserId()); const content = mEvent?.getContent(); if (!content) return; - await mx.sendStateEvent( + await sendStateEvent( + mx, room.roomId, - StateEvent.RoomMember as any, + StateEvent.RoomMember, { ...content, displayname: nick, @@ -390,9 +391,10 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { ?.getStateEvents(StateEvent.RoomMember, mx.getSafeUserId()); const content = mEvent?.getContent(); if (!content) return; - await mx.sendStateEvent( + await sendStateEvent( + mx, room.roomId, - StateEvent.RoomMember as any, + StateEvent.RoomMember, { ...content, avatar_url: payload, @@ -532,7 +534,7 @@ export const useCommands = (mx: MatrixClient, room: Room): CommandRecord => { aclContent.allow?.sort(); aclContent.deny?.sort(); - await mx.sendStateEvent(room.roomId, StateEvent.RoomServerAcl as any, aclContent); + await sendStateEvent(mx, room.roomId, StateEvent.RoomServerAcl, aclContent); }, }, }), diff --git a/src/app/hooks/useRoomAliases.ts b/src/app/hooks/useRoomAliases.ts index 186137967..c6d9f5aeb 100644 --- a/src/app/hooks/useRoomAliases.ts +++ b/src/app/hooks/useRoomAliases.ts @@ -6,7 +6,7 @@ import { useMatrixClient } from './useMatrixClient'; import { useAlive } from './useAlive'; import { useStateEvent } from './useStateEvent'; import { StateEvent } from '../../types/matrix/room'; -import { getStateEvent } from '../utils/room'; +import { getStateEvent, sendStateEvent } from '../utils/room'; export const usePublishedAliases = (room: Room): [string | undefined, string[]] => { const aliasContent = useStateEvent( @@ -56,7 +56,7 @@ export const useSetMainAlias = (room: Room): ((alias: string | undefined) => Pro alt_aliases: altAliases, }; - await mx.sendStateEvent(room.roomId, StateEvent.RoomCanonicalAlias as any, newContent); + await sendStateEvent(mx, room.roomId, StateEvent.RoomCanonicalAlias, newContent); }, [mx, room], ); @@ -90,7 +90,7 @@ export const usePublishUnpublishAliases = ( alt_aliases: altAliases, }; - await mx.sendStateEvent(room.roomId, StateEvent.RoomCanonicalAlias as any, newContent); + await sendStateEvent(mx, room.roomId, StateEvent.RoomCanonicalAlias, newContent); }, [mx, room], ); @@ -114,7 +114,7 @@ export const usePublishUnpublishAliases = ( alt_aliases: altAliases, }; - await mx.sendStateEvent(room.roomId, StateEvent.RoomCanonicalAlias as any, newContent); + await sendStateEvent(mx, room.roomId, StateEvent.RoomCanonicalAlias, newContent); }, [mx, room], ); diff --git a/src/app/utils/room.ts b/src/app/utils/room.ts index b79b79bd6..2cbd9b21d 100644 --- a/src/app/utils/room.ts +++ b/src/app/utils/room.ts @@ -8,6 +8,7 @@ import { IPowerLevelsContent, IPushRule, IPushRules, + ISendEventResponse, JoinRule, MatrixClient, MatrixEvent, @@ -43,6 +44,24 @@ export const getStateEvent = ( export const getStateEvents = (room: Room, eventType: StateEvent): MatrixEvent[] => room.getLiveTimeline().getState(EventTimeline.FORWARDS)?.getStateEvents(eventType) ?? []; +// Typed state-event write helper. +// +// matrix-js-sdk's `sendStateEvent` typed overload rejects the fork's custom +// `StateEvent` enum values (the `io.lotus.*` / `im.ponies.*` / etc. values in +// `types/matrix/room.ts`), and casting the event type to `any` at each call site +// also collapses the `content` argument to `any`. We centralize the single +// `as any` cast here so every call site keeps its own `content` type checked. +export function sendStateEvent( + mx: MatrixClient, + roomId: string, + eventType: StateEvent, + content: T, + stateKey = '', +): Promise { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return mx.sendStateEvent(roomId, eventType as any, content, stateKey); +} + export const getAccountData = ( mx: MatrixClient, eventType: AccountDataEvent | string,