fix(messaging): a sent message no longer shows "Seen" instantly
Two independent defects; either alone caused it, in DMs, groups and channels. 1. useMessages reported a read of the newest NON-PENDING message regardless of author. Sending therefore made the client immediately mark its own message read, the server echoed a receipt for it, and the sender's bubble showed "Seen" before anyone had opened the thread. You do not read your own message: lastReadableId now skips your own. 2. The guard meant to catch exactly this — `e.actorId !== currentActorId` — could never fire: the receipt carries the reader's IIOS actor UUID while clients hold a userId, so the comparison was always true and every receipt, including your own, counted as the other side. The gateway now also emits userId on READ and DELIVERED receipts (matching what `annotation` already did), and ReceiptEvent carries it as optional so older servers still typecheck. MockAdapter.markRead was a no-op, so it could not exercise any of this; it now echoes a receipt like a real server. Regression test verified to fail without the fix. SDK 0.1.14; suite 17 files / 101 tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -159,7 +159,9 @@ export class MessageGateway implements OnGatewayInit, OnGatewayConnection, OnGat
|
||||
async read(@ConnectedSocket() client: Socket, @MessageBody() body: { threadId: string; interactionId: string }) {
|
||||
const { principal } = client.data as SocketState;
|
||||
const r = await this.messages.markRead(body.threadId, principal, body.interactionId);
|
||||
this.server.to(body.threadId).emit('receipt', { interactionId: r.interactionId, actorId: r.actorId, kind: 'READ' });
|
||||
// userId as well as actorId: actorId is an IIOS actor UUID, but clients hold the caller's
|
||||
// USERID, so without this they cannot tell their own receipt from someone else's.
|
||||
this.server.to(body.threadId).emit('receipt', { interactionId: r.interactionId, actorId: r.actorId, userId: principal.userId, kind: 'READ' });
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
@@ -167,7 +169,9 @@ export class MessageGateway implements OnGatewayInit, OnGatewayConnection, OnGat
|
||||
async delivered(@ConnectedSocket() client: Socket, @MessageBody() body: { threadId: string; interactionId: string }) {
|
||||
const { principal } = client.data as SocketState;
|
||||
const r = await this.messages.markDelivered(body.threadId, principal, body.interactionId);
|
||||
this.server.to(body.threadId).emit('receipt', { interactionId: r.interactionId, actorId: r.actorId, kind: 'DELIVERED' });
|
||||
// userId as well as actorId: actorId is an IIOS actor UUID, but clients hold the caller's
|
||||
// USERID, so without this they cannot tell their own receipt from someone else's.
|
||||
this.server.to(body.threadId).emit('receipt', { interactionId: r.interactionId, actorId: r.actorId, userId: principal.userId, kind: 'DELIVERED' });
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user