polfan-server-js-client 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/workspace.xml +57 -235
- package/build/index.cjs.js +10 -2
- package/build/index.cjs.js.map +1 -1
- package/build/index.umd.js.map +1 -1
- package/build/types/types/src/index.d.ts +9 -1
- package/build/types/types/src/schemes/Message.d.ts +5 -1
- package/build/types/types/src/schemes/MessagePoll.d.ts +10 -0
- package/build/types/types/src/schemes/Reaction.d.ts +13 -0
- package/build/types/types/src/schemes/commands/CreateMessage.d.ts +3 -0
- package/build/types/types/src/schemes/commands/GetMessages.d.ts +5 -0
- package/build/types/types/src/schemes/commands/GetReactionDetails.d.ts +8 -0
- package/build/types/types/src/schemes/commands/React.d.ts +6 -0
- package/build/types/types/src/schemes/commands/Unreact.d.ts +6 -0
- package/build/types/types/src/schemes/events/Messages.d.ts +3 -0
- package/build/types/types/src/schemes/events/Reacted.d.ts +9 -0
- package/build/types/types/src/schemes/events/ReactionDetails.d.ts +11 -0
- package/build/types/types/src/schemes/events/ReactionUpdated.d.ts +8 -0
- package/package.json +43 -43
- package/src/index.ts +31 -31
- package/src/state-tracker/UsersManager.ts +51 -51
- package/src/types/src/index.ts +333 -313
- package/src/types/src/schemes/Message.ts +5 -1
- package/src/types/src/schemes/MessagePoll.ts +12 -0
- package/src/types/src/schemes/Reaction.ts +16 -0
- package/src/types/src/schemes/commands/CreateMessage.ts +3 -0
- package/src/types/src/schemes/commands/GetMessages.ts +5 -0
- package/src/types/src/schemes/commands/GetReactionDetails.ts +9 -0
- package/src/types/src/schemes/commands/React.ts +7 -0
- package/src/types/src/schemes/commands/Unreact.ts +7 -0
- package/src/types/src/schemes/events/Messages.ts +3 -0
- package/src/types/src/schemes/events/Reacted.ts +10 -0
- package/src/types/src/schemes/events/ReactionDetails.ts +12 -0
- package/src/types/src/schemes/events/ReactionUpdated.ts +9 -0
|
@@ -145,4 +145,12 @@ import { Uninvite } from "./schemes/commands/Uninvite";
|
|
|
145
145
|
import { GetInvited } from "./schemes/commands/GetInvited";
|
|
146
146
|
import { Invited } from "./schemes/events/Invited";
|
|
147
147
|
import { TopicUnfollowed } from "./schemes/events/TopicUnfollowed";
|
|
148
|
-
|
|
148
|
+
import { MessageReaction, ReactionType, ToggledReaction, UserReaction } from "./schemes/Reaction";
|
|
149
|
+
import { MessagePoll, MessagePollOption } from "./schemes/MessagePoll";
|
|
150
|
+
import { React } from "./schemes/commands/React";
|
|
151
|
+
import { Unreact } from "./schemes/commands/Unreact";
|
|
152
|
+
import { GetReactionDetails } from "./schemes/commands/GetReactionDetails";
|
|
153
|
+
import { ReactionUpdated } from "./schemes/events/ReactionUpdated";
|
|
154
|
+
import { Reacted } from "./schemes/events/Reacted";
|
|
155
|
+
import { ReactionDetails } from "./schemes/events/ReactionDetails";
|
|
156
|
+
export { Envelope, Message, MessageType, MessageAuthor, Role, Room, RoomType, RoomStream, RoomStreamType, RoomHistory, RoomHistoryMode, RoomMember, RoomSummary, RoomSummaryExtras, Space, SpaceMember, Topic, FollowedTopic, NotificationLevel, User, UserStatus, UserState, PermissionOverwritesValue, ChatLocation, SpaceSummary, SpaceDiscoverable, Emoticon, PermissionOverwritesTarget, BanObject, LeaveReason, UserRelationship, UserRelationshipType, CreateTopicInitialMessage, UserInformation, SessionPush, SessionData, SessionPlatform, UserData, PrivateMessagePolicy, ReactionType, MessageReaction, UserReaction, ToggledReaction, MessagePoll, MessagePollOption, Bye, Error, Messages, NewMessage, NewRole, NewRoom, NewTopic, TopicFollowed, TopicUnfollowed, FollowedTopics, FollowedTopicUpdated, ComputedPermissions, PermissionOverwrites, PermissionOverwritesUpdated, RoleDeleted, RoleUpdated, RoomDeleted, RoomUpdated, RoomJoined, RoomLeft, RoomMembersJoined, RoomMemberLeft, RoomMembers, RoomMemberUpdated, UserUpdated, Session, SpaceDeleted, SpaceUpdated, SpaceJoined, SpaceLeft, SpaceMemberJoined, SpaceMemberLeft, SpaceMembers, SpaceMemberUpdated, SpaceRooms, TopicDeleted, TopicUpdated, PermissionOverwriteTargets, Owners, Ok, DiscoverableSpaces, Emoticons, EmoticonDeleted, NewEmoticon, Bans, ClientData, SpaceSummaryEvent, RoomSummaryEvent, NewRelationship, RelationshipDeleted, Relationships, RoomSummaryUpdated, Pong, MessagesRedacted, UserInfo, Invited, ReactionUpdated, Reacted, ReactionDetails, AssignRole, GetMessages, CreateMessage, Ack, CreateRole, CreateRoom, CreateSpace, CreateTopic, FollowTopic, UnfollowTopic, UpdateFollowedTopic, GetFollowedTopics, DeassignRole, DeleteRole, DeleteRoom, DeleteSpace, DeleteTopic, SetPermissionOverwrites, GetPermissionOverwrites, GetComputedPermissions, GetRoomMembers, GetSession, GetSpaceMembers, GetSpaceRooms, JoinRoom, JoinSpace, LeaveRoom, LeaveSpace, UpdateRole, UpdateSpace, UpdateRoom, UpdateTopic, GetPermissionOverwriteTargets, CreateOwner, DeleteOwner, GetOwners, Topics, GetTopics, GetDiscoverableSpaces, GetEmoticons, CreateEmoticon, DeleteEmoticon, Ban, Unban, GetBans, Kick, GetClientData, SetClientData, GetSpaceSummary, GetRoomSummary, UpdateSpaceMember, CreateRelationship, DeleteRelationship, GetRelationships, UpdateRoomMember, Ping, ReportAbuse, RedactMessages, GetUserInfo, SetSessionData, GetSessionData, SetUserData, GetUserData, Invite, Uninvite, GetInvited, React, Unreact, GetReactionDetails, };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { User } from "./User";
|
|
2
2
|
import { ChatLocation } from "./ChatLocation";
|
|
3
|
-
|
|
3
|
+
import { MessageReaction } from "./Reaction";
|
|
4
|
+
import { MessagePoll } from "./MessagePoll";
|
|
5
|
+
export type MessageType = 'Text' | 'RoomJoin' | 'RoomMemberAdd' | 'RoomLeave' | 'SpaceJoin' | 'SpaceLeave' | 'TopicChange' | 'CustomNickChange' | 'Ephemeral' | 'Poll';
|
|
4
6
|
export interface MessageAuthor {
|
|
5
7
|
user: User;
|
|
6
8
|
customNick?: string;
|
|
@@ -15,4 +17,6 @@ export interface Message {
|
|
|
15
17
|
content?: string;
|
|
16
18
|
topicRef: string | null;
|
|
17
19
|
attachments: string[] | null;
|
|
20
|
+
reactions: MessageReaction[];
|
|
21
|
+
poll?: MessagePoll;
|
|
18
22
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type ReactionType = 'Emoji' | 'Emoticon';
|
|
2
|
+
export interface MessageReaction {
|
|
3
|
+
type: ReactionType;
|
|
4
|
+
value: string;
|
|
5
|
+
count: number;
|
|
6
|
+
}
|
|
7
|
+
export interface UserReaction {
|
|
8
|
+
type: ReactionType;
|
|
9
|
+
value: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ToggledReaction extends UserReaction {
|
|
12
|
+
isAdded: boolean;
|
|
13
|
+
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { ChatLocation } from "../ChatLocation";
|
|
2
|
+
import { MessagePoll } from "../MessagePoll";
|
|
2
3
|
export interface CreateMessage {
|
|
3
4
|
location: ChatLocation;
|
|
4
5
|
content: string;
|
|
5
6
|
attachments?: string[];
|
|
6
7
|
customNick?: string;
|
|
7
8
|
customColor?: string;
|
|
9
|
+
/** Turns the message into a poll; its content becomes the question. */
|
|
10
|
+
poll?: MessagePoll;
|
|
8
11
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { ChatLocation } from "../ChatLocation";
|
|
2
2
|
import { Message } from "../Message";
|
|
3
|
+
import { UserReaction } from "../Reaction";
|
|
3
4
|
export interface Messages {
|
|
4
5
|
location: ChatLocation;
|
|
5
6
|
messages: Message[];
|
|
7
|
+
/** Message id => reactions of the asking user; present only when requested. */
|
|
8
|
+
myReactions?: Record<string, UserReaction[]>;
|
|
6
9
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ToggledReaction } from "../Reaction";
|
|
2
|
+
/**
|
|
3
|
+
* Sent to every client of the voting user, so all of their devices know what they
|
|
4
|
+
* voted for without refetching the message history.
|
|
5
|
+
*/
|
|
6
|
+
export interface Reacted {
|
|
7
|
+
messageId: string;
|
|
8
|
+
reaction: ToggledReaction;
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ReactionType } from "../Reaction";
|
|
2
|
+
/**
|
|
3
|
+
* Who reacted, oldest vote first. Only the ids travel - the nicks are already
|
|
4
|
+
* known from the room members collection.
|
|
5
|
+
*/
|
|
6
|
+
export interface ReactionDetails {
|
|
7
|
+
messageId: string;
|
|
8
|
+
type: ReactionType;
|
|
9
|
+
value: string;
|
|
10
|
+
userIds: string[];
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "polfan-server-js-client",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "JavaScript client library for handling communication with Polfan chat server.",
|
|
5
|
-
"author": "Jarosław Żak",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"main": "build/index.cjs.js",
|
|
8
|
-
"browser": "build/index.umd.js",
|
|
9
|
-
"types": "build/types/index.d.ts",
|
|
10
|
-
"exports": {
|
|
11
|
-
".": {
|
|
12
|
-
"types": "./build/types/index.d.ts",
|
|
13
|
-
"require": "./build/index.cjs.js",
|
|
14
|
-
"browser": "./build/index.umd.js",
|
|
15
|
-
"default": "./build/index.cjs.js"
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "npm run build:node && npm run build:browser && tsc",
|
|
20
|
-
"build:node": "webpack --config webpack.config.node.js",
|
|
21
|
-
"build:browser": "webpack --config webpack.config.browser.js",
|
|
22
|
-
"test": "jest",
|
|
23
|
-
"coverage": "npm run test -- --coverage",
|
|
24
|
-
"trypublish": "npm publish || true"
|
|
25
|
-
},
|
|
26
|
-
"devDependencies": {
|
|
27
|
-
"@babel/cli": "^7.28.3",
|
|
28
|
-
"@babel/core": "^7.28.5",
|
|
29
|
-
"@babel/preset-env": "^7.28.5",
|
|
30
|
-
"@babel/preset-typescript": "^7.28.5",
|
|
31
|
-
"@types/jest": "^29.5.14",
|
|
32
|
-
"babel-loader": "^9.2.1",
|
|
33
|
-
"file-loader": "^6.2.0",
|
|
34
|
-
"jest": "^29.7.0",
|
|
35
|
-
"ts-node": "^10.9.2",
|
|
36
|
-
"typescript": "^4.9.5",
|
|
37
|
-
"webpack": "^5.103.0",
|
|
38
|
-
"webpack-cli": "^5.1.4"
|
|
39
|
-
},
|
|
40
|
-
"dependencies": {
|
|
41
|
-
"terser-webpack-plugin": "^5.3.14"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "polfan-server-js-client",
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "JavaScript client library for handling communication with Polfan chat server.",
|
|
5
|
+
"author": "Jarosław Żak",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "build/index.cjs.js",
|
|
8
|
+
"browser": "build/index.umd.js",
|
|
9
|
+
"types": "build/types/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./build/types/index.d.ts",
|
|
13
|
+
"require": "./build/index.cjs.js",
|
|
14
|
+
"browser": "./build/index.umd.js",
|
|
15
|
+
"default": "./build/index.cjs.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "npm run build:node && npm run build:browser && tsc",
|
|
20
|
+
"build:node": "webpack --config webpack.config.node.js",
|
|
21
|
+
"build:browser": "webpack --config webpack.config.browser.js",
|
|
22
|
+
"test": "jest",
|
|
23
|
+
"coverage": "npm run test -- --coverage",
|
|
24
|
+
"trypublish": "npm publish || true"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@babel/cli": "^7.28.3",
|
|
28
|
+
"@babel/core": "^7.28.5",
|
|
29
|
+
"@babel/preset-env": "^7.28.5",
|
|
30
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
31
|
+
"@types/jest": "^29.5.14",
|
|
32
|
+
"babel-loader": "^9.2.1",
|
|
33
|
+
"file-loader": "^6.2.0",
|
|
34
|
+
"jest": "^29.7.0",
|
|
35
|
+
"ts-node": "^10.9.2",
|
|
36
|
+
"typescript": "^4.9.5",
|
|
37
|
+
"webpack": "^5.103.0",
|
|
38
|
+
"webpack-cli": "^5.1.4"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"terser-webpack-plugin": "^5.3.14"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import {WebSocketChatClient} from "./WebSocketChatClient";
|
|
2
|
-
import {WebApiChatClient} from "./WebApiChatClient";
|
|
3
|
-
import {
|
|
4
|
-
IndexedCollection,
|
|
5
|
-
IndexedObjectCollection,
|
|
6
|
-
ObservableIndexedCollection,
|
|
7
|
-
ObservableIndexedObjectCollection
|
|
8
|
-
} from "./IndexedObjectCollection";
|
|
9
|
-
import {FilesClient, File} from "./FilesClient";
|
|
10
|
-
import { Permissions, PermissionDefinition, Layer } from "./Permissions";
|
|
11
|
-
import * as ChatTypes from './types/src';
|
|
12
|
-
import {UserStatus} from './types/src';
|
|
13
|
-
import {extractUserFromMember} from "./state-tracker/functions";
|
|
14
|
-
import {AbstractRestClient} from "./AbstractRestClient";
|
|
15
|
-
import {UnreadSummary} from "./state-tracker/FollowedTopicsManager";
|
|
16
|
-
|
|
17
|
-
export {
|
|
18
|
-
IndexedCollection, ObservableIndexedCollection,
|
|
19
|
-
IndexedObjectCollection, ObservableIndexedObjectCollection,
|
|
20
|
-
Permissions, PermissionDefinition, Layer,
|
|
21
|
-
WebSocketChatClient, WebApiChatClient,
|
|
22
|
-
FilesClient,
|
|
23
|
-
AbstractRestClient,
|
|
24
|
-
extractUserFromMember,
|
|
25
|
-
UserStatus,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export type {
|
|
29
|
-
ChatTypes,
|
|
30
|
-
File,
|
|
31
|
-
UnreadSummary,
|
|
1
|
+
import {WebSocketChatClient} from "./WebSocketChatClient";
|
|
2
|
+
import {WebApiChatClient} from "./WebApiChatClient";
|
|
3
|
+
import {
|
|
4
|
+
IndexedCollection,
|
|
5
|
+
IndexedObjectCollection,
|
|
6
|
+
ObservableIndexedCollection,
|
|
7
|
+
ObservableIndexedObjectCollection
|
|
8
|
+
} from "./IndexedObjectCollection";
|
|
9
|
+
import {FilesClient, File} from "./FilesClient";
|
|
10
|
+
import { Permissions, PermissionDefinition, Layer } from "./Permissions";
|
|
11
|
+
import * as ChatTypes from './types/src';
|
|
12
|
+
import {UserStatus} from './types/src';
|
|
13
|
+
import {extractUserFromMember} from "./state-tracker/functions";
|
|
14
|
+
import {AbstractRestClient} from "./AbstractRestClient";
|
|
15
|
+
import {UnreadSummary} from "./state-tracker/FollowedTopicsManager";
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
IndexedCollection, ObservableIndexedCollection,
|
|
19
|
+
IndexedObjectCollection, ObservableIndexedObjectCollection,
|
|
20
|
+
Permissions, PermissionDefinition, Layer,
|
|
21
|
+
WebSocketChatClient, WebApiChatClient,
|
|
22
|
+
FilesClient,
|
|
23
|
+
AbstractRestClient,
|
|
24
|
+
extractUserFromMember,
|
|
25
|
+
UserStatus,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type {
|
|
29
|
+
ChatTypes,
|
|
30
|
+
File,
|
|
31
|
+
UnreadSummary,
|
|
32
32
|
};
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import {ChatStateTracker} from "./ChatStateTracker";
|
|
2
|
-
import {ObservableIndexedObjectCollection} from "../IndexedObjectCollection";
|
|
3
|
-
import {RoomMember, Session, SpaceMember, User} from "../types/src";
|
|
4
|
-
import {extractUserFromMember} from "./functions";
|
|
5
|
-
import {EventTarget} from "../EventTarget";
|
|
6
|
-
|
|
7
|
-
export class UsersManager {
|
|
8
|
-
public readonly onlineStatus = new EventTarget<{ change: User }>();
|
|
9
|
-
|
|
10
|
-
private readonly users: ObservableIndexedObjectCollection<User> = new ObservableIndexedObjectCollection('id');
|
|
11
|
-
|
|
12
|
-
public constructor(private tracker: ChatStateTracker) {
|
|
13
|
-
// RoomMemberUpdated & SpaceMemberUpdated events are not contains user object
|
|
14
|
-
tracker.client.on('UserUpdated', event => this.handleUsers([event.user]));
|
|
15
|
-
tracker.client.on('RoomMembersJoined', event => this.handleMembers(event.members));
|
|
16
|
-
tracker.client.on('SpaceMemberJoined', event => this.handleMembers([event.member]));
|
|
17
|
-
tracker.client.on('SpaceMembers', event => this.handleMembers(event.members));
|
|
18
|
-
tracker.client.on('RoomMembers', event => this.handleMembers(event.members));
|
|
19
|
-
tracker.client.on('Messages', event => this.handleUsers(event.messages.map(message => message.author.user)));
|
|
20
|
-
tracker.client.on('NewMessage', event => this.handleUsers([event.message.author.user]));
|
|
21
|
-
tracker.client.on('Session', event => this.handleSession(event));
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Get all available (cached) user objects at once.
|
|
26
|
-
*/
|
|
27
|
-
public async getAvailable(): Promise<ObservableIndexedObjectCollection<User>> {
|
|
28
|
-
return this.users;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
private handleMembers(members: (RoomMember | SpaceMember)[]): void {
|
|
32
|
-
this.handleUsers(members.map(extractUserFromMember));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
private handleSession(session: Session): void {
|
|
36
|
-
// Keep the "seen users" cache across reconnects so bound user lists do
|
|
37
|
-
// not blank out; just ensure our own user is present/updated. Stale
|
|
38
|
-
// entries are refreshed as member/message collections refetch.
|
|
39
|
-
this.handleUsers([session.user]);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private handleUsers(users: User[]): void {
|
|
43
|
-
users.forEach(newUser => {
|
|
44
|
-
const oldUser = this.users.get(newUser.id);
|
|
45
|
-
if (oldUser && oldUser.status !== newUser.status) {
|
|
46
|
-
this.onlineStatus.emit('change', newUser);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
this.users.set(...users);
|
|
51
|
-
}
|
|
1
|
+
import {ChatStateTracker} from "./ChatStateTracker";
|
|
2
|
+
import {ObservableIndexedObjectCollection} from "../IndexedObjectCollection";
|
|
3
|
+
import {RoomMember, Session, SpaceMember, User} from "../types/src";
|
|
4
|
+
import {extractUserFromMember} from "./functions";
|
|
5
|
+
import {EventTarget} from "../EventTarget";
|
|
6
|
+
|
|
7
|
+
export class UsersManager {
|
|
8
|
+
public readonly onlineStatus = new EventTarget<{ change: User }>();
|
|
9
|
+
|
|
10
|
+
private readonly users: ObservableIndexedObjectCollection<User> = new ObservableIndexedObjectCollection('id');
|
|
11
|
+
|
|
12
|
+
public constructor(private tracker: ChatStateTracker) {
|
|
13
|
+
// RoomMemberUpdated & SpaceMemberUpdated events are not contains user object
|
|
14
|
+
tracker.client.on('UserUpdated', event => this.handleUsers([event.user]));
|
|
15
|
+
tracker.client.on('RoomMembersJoined', event => this.handleMembers(event.members));
|
|
16
|
+
tracker.client.on('SpaceMemberJoined', event => this.handleMembers([event.member]));
|
|
17
|
+
tracker.client.on('SpaceMembers', event => this.handleMembers(event.members));
|
|
18
|
+
tracker.client.on('RoomMembers', event => this.handleMembers(event.members));
|
|
19
|
+
tracker.client.on('Messages', event => this.handleUsers(event.messages.map(message => message.author.user)));
|
|
20
|
+
tracker.client.on('NewMessage', event => this.handleUsers([event.message.author.user]));
|
|
21
|
+
tracker.client.on('Session', event => this.handleSession(event));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get all available (cached) user objects at once.
|
|
26
|
+
*/
|
|
27
|
+
public async getAvailable(): Promise<ObservableIndexedObjectCollection<User>> {
|
|
28
|
+
return this.users;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private handleMembers(members: (RoomMember | SpaceMember)[]): void {
|
|
32
|
+
this.handleUsers(members.map(extractUserFromMember));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private handleSession(session: Session): void {
|
|
36
|
+
// Keep the "seen users" cache across reconnects so bound user lists do
|
|
37
|
+
// not blank out; just ensure our own user is present/updated. Stale
|
|
38
|
+
// entries are refreshed as member/message collections refetch.
|
|
39
|
+
this.handleUsers([session.user]);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private handleUsers(users: User[]): void {
|
|
43
|
+
users.forEach(newUser => {
|
|
44
|
+
const oldUser = this.users.get(newUser.id);
|
|
45
|
+
if (oldUser && oldUser.status !== newUser.status) {
|
|
46
|
+
this.onlineStatus.emit('change', newUser);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
this.users.set(...users);
|
|
51
|
+
}
|
|
52
52
|
}
|