@@ -16,11 +16,24 @@ import type {
1616 ApplicationGatewaySnapshot ,
1717} from "./context.ts" ;
1818import { loadSettings , patchSettings , persistSessionToken } from "./settings.ts" ;
19+ import { readPresenceEntries , resolveSelfPresenceUser } from "./user-profile.ts" ;
1920
2021type GatewayClientFactory = ( opts : GatewayBrowserClientOptions ) => GatewayBrowserClient ;
2122
2223const defaultClientFactory : GatewayClientFactory = ( opts ) => new GatewayBrowserClient ( opts ) ;
2324
25+ function sameSelfUser (
26+ left : ApplicationGatewaySnapshot [ "selfUser" ] ,
27+ right : ApplicationGatewaySnapshot [ "selfUser" ] ,
28+ ) : boolean {
29+ return (
30+ left ?. id === right ?. id &&
31+ left ?. email === right ?. email &&
32+ left ?. name === right ?. name &&
33+ left ?. avatarUrl === right ?. avatarUrl
34+ ) ;
35+ }
36+
2437export function createApplicationGateway (
2538 initialSettings : ReturnType < typeof loadSettings > ,
2639 initialPassword = "" ,
@@ -45,6 +58,7 @@ export function createApplicationGateway(
4558 sessionKey : settings . sessionKey ,
4659 lastError : null ,
4760 lastErrorCode : null ,
61+ selfUser : null ,
4862 } ;
4963 let client : GatewayBrowserClient | null = null ;
5064 // Session lineage for this page lifetime: once a hello succeeded, later
@@ -96,6 +110,15 @@ export function createApplicationGateway(
96110 settings = patchSettings ( patch , { selectGateway } ) ;
97111 } ;
98112 const recordGatewayEvent = ( event : Parameters < GatewayEventListener > [ 0 ] ) => {
113+ if ( event . event === "presence" ) {
114+ const entries = readPresenceEntries ( event . payload ) ;
115+ if ( entries ) {
116+ const selfUser = resolveSelfPresenceUser ( entries , client ?. instanceId ) ;
117+ if ( ! sameSelfUser ( snapshot . selfUser , selfUser ) ) {
118+ setSnapshot ( { ...snapshot , selfUser } ) ;
119+ }
120+ }
121+ }
99122 eventLog = [ { ts : Date . now ( ) , event : event . event , payload : event . payload } , ...eventLog ] . slice (
100123 0 ,
101124 250 ,
@@ -177,6 +200,10 @@ export function createApplicationGateway(
177200 sessionKey,
178201 lastError : null ,
179202 lastErrorCode : null ,
203+ selfUser : resolveSelfPresenceUser (
204+ readPresenceEntries ( hello . snapshot ) ?? [ ] ,
205+ nextClient . instanceId ,
206+ ) ,
180207 } ) ;
181208 } ,
182209 onRecoveryScopeChange : ( ) => {
@@ -195,6 +222,7 @@ export function createApplicationGateway(
195222 connected : false ,
196223 reconnecting : everConnected && willRetry ,
197224 hello : null ,
225+ selfUser : null ,
198226 lastError : error ?. message ?? `disconnected (${ code } ): ${ reason || "no reason" } ` ,
199227 lastErrorCode : error ?. code ?? null ,
200228 } ) ;
@@ -222,6 +250,7 @@ export function createApplicationGateway(
222250 // recovery, banner "retry now") when a session already existed.
223251 reconnecting : everConnected ,
224252 hello : null ,
253+ selfUser : null ,
225254 sessionKey : nextSessionKey ,
226255 lastError : null ,
227256 lastErrorCode : null ,
@@ -264,6 +293,7 @@ export function createApplicationGateway(
264293 connected : false ,
265294 reconnecting : false ,
266295 hello : null ,
296+ selfUser : null ,
267297 lastError : null ,
268298 lastErrorCode : null ,
269299 } ) ;
@@ -285,6 +315,12 @@ export function createApplicationGateway(
285315 }
286316 } ;
287317 } ,
318+ updateSelfUser : ( patch ) => {
319+ if ( ! snapshot . selfUser ) {
320+ return ;
321+ }
322+ setSnapshot ( { ...snapshot , selfUser : { ...snapshot . selfUser , ...patch } } ) ;
323+ } ,
288324 } ;
289325 return gateway ;
290326}
0 commit comments