@towns-protocol/sdk
Version:
For more details, visit the following resources:
188 lines • 7.63 kB
JavaScript
import { MembershipOp, } from '@towns-protocol/proto';
import { StreamStateView_AbstractContent } from './streamStateView_AbstractContent';
import { bin_toHexString, check } from '@towns-protocol/dlog';
import { logNever } from './check';
import { streamIdFromBytes } from './id';
import { utils } from 'ethers';
export class StreamStateView_User extends StreamStateView_AbstractContent {
userStreamsView;
streamId;
get streamMemberships() {
return this.userStreamModel.streamMemberships;
}
get tipsSent() {
return this.userStreamModel.tipsSent;
}
get tipsReceived() {
return this.userStreamModel.tipsReceived;
}
get tipsSentCount() {
return this.userStreamModel.tipsSentCount;
}
get tipsReceivedCount() {
return this.userStreamModel.tipsReceivedCount;
}
get tokenTransfers() {
return this.userStreamModel.tokenTransfers;
}
get userStreamModel() {
return this.userStreamsView.get(this.streamId);
}
constructor(streamId, userStreamsView) {
super();
this.userStreamsView = userStreamsView;
this.streamId = streamId;
}
applySnapshot(snapshot, content, encryptionEmitter) {
// initialize memberships
for (const payload of content.memberships) {
this.addUserPayload_userMembership(payload, encryptionEmitter);
}
this.userStreamsView.setTips(this.streamId, {
tipsSent: { ...content.tipsSent },
tipsReceived: { ...content.tipsReceived },
tipsSentCount: { ...content.tipsSentCount },
tipsReceivedCount: { ...content.tipsReceivedCount },
});
}
prependEvent(event, _cleartext, _encryptionEmitter, _stateEmitter) {
check(event.remoteEvent.event.payload.case === 'userPayload');
const payload = event.remoteEvent.event.payload.value;
switch (payload.content.case) {
case 'inception':
break;
case 'userMembership':
// memberships are handled in the snapshot
break;
case 'userMembershipAction':
break;
case 'blockchainTransaction':
{
const transactionContent = payload.content.value.content;
switch (transactionContent?.case) {
case 'tokenTransfer':
this.userStreamsView.prependTokenTransfer(this.streamId, transactionContent.value);
break;
default:
break;
}
}
break;
case 'receivedBlockchainTransaction':
break;
case undefined:
break;
default:
logNever(payload.content);
}
}
appendEvent(event, cleartext, _encryptionEmitter, stateEmitter) {
check(event.remoteEvent.event.payload.case === 'userPayload');
const payload = event.remoteEvent.event.payload.value;
switch (payload.content.case) {
case 'inception':
break;
case 'userMembership':
this.addUserPayload_userMembership(payload.content.value, stateEmitter);
break;
case 'userMembershipAction':
break;
case 'blockchainTransaction': {
const transactionContent = payload.content.value.content;
switch (transactionContent?.case) {
case undefined:
break;
case 'tip': {
const event = transactionContent.value.event;
if (!event) {
return;
}
const currency = utils.getAddress(bin_toHexString(event.currency));
this.userStreamsView.appendTipSent(this.streamId, currency, event.amount);
stateEmitter?.emit('userTipSent', this.streamId, currency, event.amount);
break;
}
case 'tokenTransfer':
this.userStreamsView.appendTokenTransfer(this.streamId, transactionContent.value);
break;
case 'spaceReview': {
// user left a review on a space
break;
}
default:
logNever(transactionContent);
break;
}
break;
}
case 'receivedBlockchainTransaction': {
const transactionContent = payload.content.value.transaction?.content;
switch (transactionContent?.case) {
case undefined:
break;
case 'tip': {
const event = transactionContent.value.event;
if (!event) {
return;
}
const currency = utils.getAddress(bin_toHexString(event.currency));
this.userStreamsView.appendTipReceived(this.streamId, currency, event.amount);
stateEmitter?.emit('userTipReceived', this.streamId, currency, event.amount);
break;
}
case 'tokenTransfer':
break;
case 'spaceReview': {
// user left a review on a space
break;
}
default:
logNever(transactionContent);
break;
}
break;
}
case undefined:
break;
default:
logNever(payload.content);
}
}
addUserPayload_userMembership(payload, emitter) {
const { op, streamId: inStreamId } = payload;
const streamId = streamIdFromBytes(inStreamId);
const wasInvited = this.streamMemberships[streamId]?.op === MembershipOp.SO_INVITE;
const wasJoined = this.streamMemberships[streamId]?.op === MembershipOp.SO_JOIN;
this.userStreamsView.setMembership(this.streamId, streamId, payload);
switch (op) {
case MembershipOp.SO_INVITE:
emitter?.emit('userInvitedToStream', streamId);
emitter?.emit('userStreamMembershipChanged', streamId, payload);
break;
case MembershipOp.SO_JOIN:
emitter?.emit('userJoinedStream', streamId);
emitter?.emit('userStreamMembershipChanged', streamId, payload);
break;
case MembershipOp.SO_LEAVE:
if (wasInvited || wasJoined) {
emitter?.emit('userLeftStream', streamId);
emitter?.emit('userStreamMembershipChanged', streamId, payload);
}
break;
case MembershipOp.SO_UNSPECIFIED:
break;
default:
logNever(op);
}
}
getMembership(streamId) {
return this.streamMemberships[streamId];
}
isMember(streamId, membership) {
return this.getMembership(streamId)?.op === membership;
}
isJoined(streamId) {
return this.isMember(streamId, MembershipOp.SO_JOIN);
}
}
//# sourceMappingURL=streamStateView_User.js.map