UNPKG

@river-build/sdk

Version:

For more details, visit the following resources:

143 lines 6.92 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { check } from '@river-build/dlog'; import { isDefined } from '../../check'; import { PersistedObservable, persistedObservable } from '../../observable/persistedObservable'; import { Member } from './models/member'; import { isUserId } from '../../id'; import { Myself } from './models/myself'; import { MembershipOp } from '@river-build/proto'; let Members = class Members extends PersistedObservable { riverConnection; members; _myself; // better naming? me, myself, myProfile? constructor(streamId, riverConnection, store) { super({ id: streamId, userIds: [], initialized: false }, store); this.riverConnection = riverConnection; this.members = {}; } onLoaded() { this.riverConnection.registerView((client) => { if (client.streams.has(this.data.id) && client.streams.get(this.data.id)?.view.isInitialized) { this.onStreamInitialized(this.data.id); } client.on('streamInitialized', this.onStreamInitialized); client.on('streamNewUserJoined', this.onMemberJoin); client.on('streamNewUserInvited', this.onMemberInvite); client.on('streamUserLeft', this.onMemberLeave); client.on('streamUsernameUpdated', this.onStreamUsernameUpdated); client.on('streamPendingUsernameUpdated', this.onStreamUsernameUpdated); client.on('streamNftUpdated', this.onStreamNftUpdated); client.on('streamEnsAddressUpdated', this.onStreamEnsAddressUpdated); client.on('streamDisplayNameUpdated', this.onStreamDisplayNameUpdated); return () => { client.off('streamInitialized', this.onStreamInitialized); client.off('streamNewUserJoined', this.onMemberJoin); client.off('streamNewUserInvited', this.onMemberInvite); client.off('streamUserLeft', this.onMemberLeave); client.off('streamUsernameUpdated', this.onStreamUsernameUpdated); client.off('streamPendingUsernameUpdated', this.onStreamUsernameUpdated); client.off('streamNftUpdated', this.onStreamNftUpdated); client.off('streamEnsAddressUpdated', this.onStreamEnsAddressUpdated); client.off('streamDisplayNameUpdated', this.onStreamDisplayNameUpdated); }; }); } get myself() { if (this._myself) { return this._myself; } const member = this.get(this.riverConnection.userId); const my = new Myself(member, this.data.id, this.riverConnection); this._myself = my; return my; } get(userId) { check(isUserId(userId), 'invalid user id'); // Its possible to get a member that its not in the userIds array, if the user left the stream for example // We can get a member that left, to get the last snapshot of the member if (!this.members[userId]) { this.members[userId] = new Member(userId, this.data.id, this.riverConnection, this.store); this.members[userId].onStreamInitialized(this.data.id); } return this.members[userId]; } isUsernameAvailable(username) { const streamId = this.data.id; const streamView = this.riverConnection.client?.stream(streamId)?.view; check(isDefined(streamView), 'stream not found'); return streamView.getMemberMetadata().usernames.cleartextUsernameAvailable(username); } onStreamInitialized = (streamId) => { if (streamId !== this.data.id) return; const stream = this.riverConnection.client?.stream(streamId); check(isDefined(stream), 'stream is not defined'); const userIds = Array.from(stream.view.getMembers().joined.values()).map((member) => member.userId); for (const userId of userIds) { // prefetch the member this.get(userId); } this.setData({ initialized: true, userIds }); }; onMemberLeave = (streamId, userId) => { if (streamId !== this.data.id) return; // We dont remove the member from the members map, because we want to keep the member object around // so that we can still access the member's properties. // In the next sync, the member map will be reinitialized, cleaning up the map. // We remove the member from the userIds array, so that we don't try to access it later. this.setData({ userIds: this.data.userIds.filter((id) => id !== userId) }); if (this.members[userId]) { this.members[userId].onStreamMembershipUpdated(streamId, userId, MembershipOp.SO_LEAVE); } }; onMemberJoin = (streamId, userId) => { if (streamId !== this.data.id) return; this.setData({ userIds: [...this.data.userIds, userId] }); const member = this.get(userId); member.onStreamMembershipUpdated(streamId, userId, MembershipOp.SO_JOIN); }; onMemberInvite = (streamId, userId) => { if (streamId !== this.data.id) return; this.setData({ userIds: [...this.data.userIds, userId] }); const member = this.get(userId); member.onStreamMembershipUpdated(streamId, userId, MembershipOp.SO_INVITE); }; onStreamUsernameUpdated = (streamId, userId) => { if (streamId !== this.data.id) return; const member = this.get(userId); member.onStreamUsernameUpdated(streamId, userId); }; onStreamDisplayNameUpdated = (streamId, userId) => { if (streamId !== this.data.id) return; const member = this.get(userId); member.onStreamDisplayNameUpdated(streamId, userId); }; onStreamNftUpdated = (streamId, userId) => { if (streamId !== this.data.id) return; const member = this.get(userId); member.onStreamNftUpdated(streamId, userId); }; onStreamEnsAddressUpdated = (streamId, userId) => { if (streamId !== this.data.id) return; const member = this.get(userId); member.onStreamEnsAddressUpdated(streamId, userId); }; }; Members = __decorate([ persistedObservable({ tableName: 'members' }) ], Members); export { Members }; //# sourceMappingURL=members.js.map