Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / docs-shared / lib / Doc / DocsAwareness.ts
blob89f709517e17cea8933a6f9beeaefa54b939c2d3
1 import { Awareness } from 'y-protocols/awareness'
2 import type { UserState } from '@lexical/yjs'
4 export type DocsUserState = UserState & {
5   // eslint-disable-next-line @typescript-eslint/no-explicit-any
6   awarenessData: Record<string, any>
7   // eslint-disable-next-line @typescript-eslint/no-explicit-any
8   [key: string]: any
11 export class DocsAwareness extends Awareness {
12   getLocalState(): DocsUserState | null {
13     return super.getLocalState() as DocsUserState
14   }
16   getStates(): Map<number, DocsUserState> {
17     return super.getStates() as Map<number, DocsUserState>
18   }
20   /**
21    * When a single client refreshes their page, they may not have the chance to propagate their own removal
22    * This means that when the user comes back to the page after the refresh, they will see their old user avatar.
23    * (Other users will also see the old avatar). This function looks for duplicates based on the username (email)
24    * and if there are more than one state entries for an email, it will delete the one that has the older lastUpdated.
25    */
26   removeDuplicateClients(): void {
27     const states = this.getStates()
29     const alreadyBrowsedEntries: Map<string, number> = new Map()
31     for (const [clientId, userState] of states) {
32       const username = userState.name
34       if (alreadyBrowsedEntries.has(username)) {
35         const previousClientId = alreadyBrowsedEntries.get(username) as number
37         const currentLastUpdated = this.meta.get(clientId)?.lastUpdated ?? 0
38         const previousLastUpdated = this.meta.get(previousClientId)?.lastUpdated ?? 0
40         if (currentLastUpdated > previousLastUpdated) {
41           this.states.delete(previousClientId)
42         } else if (currentLastUpdated < previousLastUpdated) {
43           this.states.delete(clientId)
44         }
45       }
47       alreadyBrowsedEntries.set(username, clientId)
48     }
49   }
51   getClientIds(): number[] {
52     return Array.from(this.getStates().keys())
53   }