refactor(types): typed send helpers replace 16 as any casts (#210)
- sendRoomMessage (composer's fire-and-forget sends: text, location, voice, files, GIFs) and sendRoomEvent (polls, poll responses/ends, forwards, reactions, edits) in utils/room.ts carry the one cast each needs (`keyof TimelineEvents` / `RoomMessageEventContent`, no `any`). - sendRoomMessage also swallows the rejected promise: a failed send already shows on the local echo (Failed to send + Retry, or the consent prompt), so it no longer surfaces as an unhandled error in the console. - getAccountData narrows to `keyof AccountDataEvents`; ForwardMessageDialog's guard now narrows `contentToSend` itself (same behaviour). - `as any` 39 → 23; eslint warnings 46 → 36, ratchet tightened to 36. Verified in Chromium on a local Synapse: a text message, a quick reaction and an edit all reach the server with the right content; a consent-blocked send no longer logs an unhandled MatrixError. 1219 unit tests pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
39589b40f3
commit
e39714a6e0
@@ -112,7 +112,12 @@ import {
|
||||
getImageMsgContent,
|
||||
getVideoMsgContent,
|
||||
} from './msgContent';
|
||||
import { getMemberName, getMentionContent, trimReplyFromBody } from '../../utils/room';
|
||||
import {
|
||||
getMemberName,
|
||||
getMentionContent,
|
||||
sendRoomMessage,
|
||||
trimReplyFromBody,
|
||||
} from '../../utils/room';
|
||||
import { CommandAutocomplete } from './CommandAutocomplete';
|
||||
import {
|
||||
Command,
|
||||
@@ -324,7 +329,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
// MSC3488 extensible location: send the geo_uri (legacy) alongside the
|
||||
// m.location/m.asset/m.ts blocks so Element and other clients render a
|
||||
// proper "shared location" pin instead of falling back to plain text.
|
||||
mx.sendMessage(roomId, threadRootId ?? null, {
|
||||
sendRoomMessage(mx, roomId, threadRootId ?? null, {
|
||||
msgtype: 'm.location',
|
||||
body: `Shared a location: ${geoUri}`,
|
||||
geo_uri: geoUri,
|
||||
@@ -332,7 +337,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
'org.matrix.msc3488.asset': { type: 'm.self' },
|
||||
'org.matrix.msc3488.ts': ts,
|
||||
'm.ts': ts,
|
||||
} as any);
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
setLocating(false);
|
||||
@@ -363,19 +368,19 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
if (room.hasEncryptionStateEvent()) {
|
||||
const { encInfo, file: encBlob } = await encryptFile(blob);
|
||||
const uploadResult = await mx.uploadContent(encBlob);
|
||||
mx.sendMessage(roomId, threadRootId ?? null, {
|
||||
sendRoomMessage(mx, roomId, threadRootId ?? null, {
|
||||
...baseContent,
|
||||
file: { ...encInfo, url: uploadResult.content_uri },
|
||||
} as any);
|
||||
});
|
||||
} else {
|
||||
const uploadResult = await mx.uploadContent(blob, {
|
||||
name: 'voice-message.ogg',
|
||||
type: mimeType,
|
||||
});
|
||||
mx.sendMessage(roomId, threadRootId ?? null, {
|
||||
sendRoomMessage(mx, roomId, threadRootId ?? null, {
|
||||
...baseContent,
|
||||
url: uploadResult.content_uri,
|
||||
} as any);
|
||||
});
|
||||
}
|
||||
},
|
||||
[mx, room, roomId, threadRootId],
|
||||
@@ -625,7 +630,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
});
|
||||
handleCancelUpload(uploads);
|
||||
const contents = fulfilledPromiseSettledResult(await Promise.allSettled(contentsPromises));
|
||||
contents.forEach((content) => mx.sendMessage(roomId, threadRootId ?? null, content as any));
|
||||
contents.forEach((content) => sendRoomMessage(mx, roomId, threadRootId ?? null, content));
|
||||
},
|
||||
[mx, roomId, threadRootId, selectedFiles, handleCancelUpload],
|
||||
);
|
||||
@@ -732,7 +737,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
content['m.relates_to'].is_falling_back = false;
|
||||
}
|
||||
}
|
||||
mx.sendMessage(roomId, threadRootId ?? null, content as any);
|
||||
sendRoomMessage(mx, roomId, threadRootId ?? null, content);
|
||||
resetEditor(editor);
|
||||
resetEditorHistory(editor);
|
||||
setCharCount(0);
|
||||
@@ -955,10 +960,10 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
const uploadRes = await mx.uploadContent(encBlob);
|
||||
const mxcUrl = (uploadRes as { content_uri: string }).content_uri;
|
||||
if (!mxcUrl) return;
|
||||
mx.sendMessage(roomId, threadRootId ?? null, {
|
||||
sendRoomMessage(mx, roomId, threadRootId ?? null, {
|
||||
...baseContent,
|
||||
file: { ...encInfo, url: mxcUrl },
|
||||
} as any);
|
||||
});
|
||||
} else {
|
||||
const uploadRes = await mx.uploadContent(gifFile, {
|
||||
type: 'image/gif',
|
||||
@@ -967,10 +972,10 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
});
|
||||
const mxcUrl = (uploadRes as { content_uri: string }).content_uri;
|
||||
if (!mxcUrl) return;
|
||||
mx.sendMessage(roomId, threadRootId ?? null, {
|
||||
sendRoomMessage(mx, roomId, threadRootId ?? null, {
|
||||
...baseContent,
|
||||
url: mxcUrl,
|
||||
} as any);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('GIF send failed:', e instanceof Error ? e.message : 'unknown error');
|
||||
|
||||
Reference in New Issue
Block a user