(fix): live reactions, message and call invites
All checks were successful
/ build-web (push) Successful in 7m40s
/ build-desktop (linux) (push) Successful in 12m10s
/ build-mobile (push) Successful in 19m43s
/ release (push) Successful in 3m35s

(fix): call ui
This commit is contained in:
Alois 2026-07-31 00:29:48 +02:00
commit f1874042ba
Signed by: alois
SSH key fingerprint: SHA256:GBzT2DXvAuGV9XIV5W3WrzVpjU54FThmxHXdbz95J24
10 changed files with 203 additions and 88 deletions

View file

@ -57,7 +57,19 @@ export type BoundSendFn = <T extends keyof Schemas & string>(
options?: { id?: number },
) => Promise<ProtocolMessage<T>>;
export type PushHandler = (message: ProtocolMessage) => void;
export type PushHandler = (
message: ProtocolMessage,
) => void | Promise<void>;
const PUSH_TYPES = [
"MessageLive",
"MessageEditLive",
"MessageReactionLive",
"MessageDeleteLive",
"MessageState",
"CallInvite",
"ErrorNoIota",
] as const;
export type MTPExchange = {
type: keyof Schemas & string;
@ -157,6 +169,7 @@ export function Provider(props: {
null,
);
const interceptorsRef = useRef(new Set<MTPInterceptor>());
const pushHandlersRef = useRef(new Set<PushHandler>());
const connected = readyState === ConnectionState.Connected;
@ -197,28 +210,8 @@ export function Provider(props: {
}, []);
const subscribePush = useCallback((handler: PushHandler) => {
const client = clientRef.current;
if (!client) {
return () => {};
}
const unsubscribers = [
"MessageLive",
"MessageEditLive",
"MessageReactionLive",
"MessageDeleteLive",
"MessageState",
"CallInvite",
"ErrorNoIota",
].map((type) =>
client.subscribe(type, (message) => {
handler(validateResponse(type as keyof Schemas & string, message));
}),
);
return () => {
unsubscribers.forEach((unsubscribe) => unsubscribe());
};
pushHandlersRef.current.add(handler);
return () => pushHandlersRef.current.delete(handler);
}, []);
const addInterceptor = useCallback((interceptor: MTPInterceptor) => {
@ -419,6 +412,28 @@ export function Provider(props: {
const activeClient = client;
clientRef.current = activeClient;
for (const type of PUSH_TYPES) {
activeClient.subscribe(type, (message) => {
let validated: ProtocolMessage;
try {
validated = validateResponse(type, message);
} catch (error) {
log(1, "mtp", "red", "Failed to validate push message", error, {
type,
data: message.data,
});
return;
}
for (const handler of [...pushHandlersRef.current]) {
void Promise.resolve()
.then(() => handler(validated))
.catch((error) => {
log(1, "mtp", "red", "Push handler failed", error, { type });
});
}
});
}
setReadyState(activeClient.state);
clearReconnectTimer();