@towns-protocol/sdk
Version:
For more details, visit the following resources:
116 lines • 4.64 kB
JavaScript
import { FullyReadMarkersSchema, UserSettingsPayload_Snapshot_UserBlocks_BlockSchema, } from '@towns-protocol/proto';
import { check, dlog } from '@towns-protocol/dlog';
import { logNever } from './check';
import { StreamStateView_AbstractContent } from './streamStateView_AbstractContent';
import { create, fromJsonString } from '@bufbuild/protobuf';
import { streamIdFromBytes, userIdFromAddress } from './id';
const log = dlog('csb:stream');
export class StreamStateView_UserSettings extends StreamStateView_AbstractContent {
userSettingsStreamsView;
streamId;
get fullyReadMarkers() {
return this.userSettingsStreamModel.fullyReadMarkers;
}
get userBlocks() {
return this.userSettingsStreamModel.userBlocks;
}
get userSettingsStreamModel() {
return this.userSettingsStreamsView.get(this.streamId);
}
constructor(streamId, userSettingsStreamsView) {
super();
this.userSettingsStreamsView = userSettingsStreamsView;
this.streamId = streamId;
}
applySnapshot(snapshot, content) {
// iterate over content.fullyReadMarkers
for (const payload of content.fullyReadMarkers) {
this.fullyReadMarkerUpdate(payload);
}
for (const userBlocks of content.userBlocksList) {
const userId = userIdFromAddress(userBlocks.userId);
this.userSettingsStreamsView.setUserBlocks(this.streamId, userId, userBlocks);
}
}
prependEvent(event, _cleartext, _encryptionEmitter, _stateEmitter) {
check(event.remoteEvent.event.payload.case === 'userSettingsPayload');
const payload = event.remoteEvent.event.payload.value;
switch (payload.content.case) {
case 'inception':
break;
case 'fullyReadMarkers':
// handled in snapshot
break;
case 'userBlock':
// handled in snapshot
break;
case undefined:
break;
default:
logNever(payload.content);
}
}
appendEvent(event, _cleartext, _encryptionEmitter, stateEmitter) {
check(event.remoteEvent.event.payload.case === 'userSettingsPayload');
const payload = event.remoteEvent.event.payload.value;
switch (payload.content.case) {
case 'inception':
break;
case 'fullyReadMarkers':
this.fullyReadMarkerUpdate(payload.content.value, stateEmitter);
break;
case 'userBlock':
this.userBlockUpdate(payload.content.value, stateEmitter);
break;
case undefined:
break;
default:
logNever(payload.content);
}
}
fullyReadMarkerUpdate(payload, emitter) {
const { content } = payload;
log('$ fullyReadMarkerUpdate', { content });
if (content === undefined) {
log('$ Content with FullyReadMarkers is undefined');
return;
}
const streamId = streamIdFromBytes(payload.streamId);
const fullyReadMarkersContent = fromJsonString(FullyReadMarkersSchema, content.data);
this.userSettingsStreamsView.setFullyReadMarkers(this.streamId, streamId, fullyReadMarkersContent.markers);
emitter?.emit('fullyReadMarkersUpdated', streamId, fullyReadMarkersContent.markers);
}
userBlockUpdate(payload, emitter) {
const userId = userIdFromAddress(payload.userId);
const userBlock = create(UserSettingsPayload_Snapshot_UserBlocks_BlockSchema, {
eventNum: payload.eventNum,
isBlocked: payload.isBlocked,
});
this.userSettingsStreamsView.updateUserBlock(this.streamId, userId, userBlock);
emitter?.emit('userBlockUpdated', payload);
}
isUserBlocked(userId) {
const latestBlock = this.getLastBlock(userId);
if (latestBlock === undefined) {
return false;
}
return latestBlock.isBlocked;
}
isUserBlockedAt(userId, eventNum) {
let isBlocked = false;
for (const block of this.userBlocks[userId]?.blocks ?? []) {
if (eventNum >= block.eventNum) {
isBlocked = block.isBlocked;
}
}
return isBlocked;
}
getLastBlock(userId) {
const blocks = this.userBlocks[userId]?.blocks;
if (!blocks || blocks.length === 0) {
return undefined;
}
return blocks[blocks.length - 1];
}
}
//# sourceMappingURL=streamStateView_UserSettings.js.map