@river-build/sdk
Version:
For more details, visit the following resources:
143 lines • 6.92 kB
JavaScript
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