UNPKG

@towns-protocol/sdk

Version:

For more details, visit the following resources:

107 lines 4.41 kB
import { Observable } from '../../observable/observable'; import { RiverTimelineEvent } from '../models/timelineTypes'; import { makeTimelinesViewInterface, } from './timelinesModel'; import { toDecryptedContentErrorEvent, toDecryptedEvent, toEvent } from '../models/timelineEvent'; import { isEqual } from 'lodash-es'; import { isDMChannelStreamId } from '../../id'; export class TimelinesView extends Observable { userId; delegate; eventFilter; streamIds = new Set(); setState; // todo invert this so we don't have to pass the whole client constructor(userId, delegate, eventFilter = new Set([ RiverTimelineEvent.Fulfillment, RiverTimelineEvent.KeySolicitation, ])) { super({ timelines: {}, replacedEvents: {}, pendingReplacedEvents: {}, threadsStats: {}, threads: {}, reactions: {}, tips: {}, lastestEventByUser: {}, }); this.userId = userId; this.delegate = delegate; this.eventFilter = eventFilter; this.setState = makeTimelinesViewInterface((fn) => { this.setValue(fn(this.value)); }); } streamInitialized(streamId, messages) { this.streamIds.add(streamId); const timelineEvents = messages .map((event) => toEvent(event, this.userId)) .filter((event) => this.filterFn(streamId, event)); this.setState.appendEvents(timelineEvents, this.userId, streamId, 'initializeStream'); } streamUpdated(streamId, change) { const { prepended, appended, updated, confirmed } = change; this.streamIds.add(streamId); if (prepended) { const events = prepended .map((event) => toEvent(event, this.userId)) .filter((event) => this.filterFn(streamId, event)); this.setState.prependEvents(events, this.userId, streamId); } if (appended) { const events = appended .map((event) => toEvent(event, this.userId)) .filter((event) => this.filterFn(streamId, event)); this.setState.appendEvents(events, this.userId, streamId); } if (updated) { const events = updated .map((event) => toEvent(event, this.userId)) .filter((event) => this.filterFn(streamId, event)); this.setState.updateEvents(events, this.userId, streamId); } if (confirmed) { const confirmations = confirmed.map((event) => ({ eventId: event.hashStr, confirmedInBlockNum: event.miniblockNum, confirmedEventNum: event.confirmedEventNum, })); this.setState.confirmEvents(confirmations, streamId); } } streamEventDecrypted(streamId, eventId, decryptedContent) { const prevEvent = this.value.timelines[streamId].find((event) => event.eventId === eventId); if (prevEvent) { const newEvent = toDecryptedEvent(prevEvent, decryptedContent, this.userId); if (!isEqual(newEvent, prevEvent)) { this.setState.updateEvent(newEvent, this.userId, streamId, eventId); } return newEvent; } return undefined; } streamEventDecryptedContentError(streamId, eventId, error) { const prevEvent = this.value.timelines[streamId].find((event) => event.eventId === eventId); if (prevEvent) { const newEvent = toDecryptedContentErrorEvent(prevEvent, error); if (newEvent !== prevEvent) { this.setState.updateEvent(newEvent, this.userId, streamId, eventId); } } } streamLocalEventUpdated(streamId, localEventId, localEvent) { this.streamIds.add(streamId); const event = toEvent(localEvent, this.userId); if (this.filterFn(streamId, event)) { this.setState.updateEvent(event, this.userId, streamId, localEventId); } } filterFn(streamId, event) { if (isDMChannelStreamId(streamId) && this.delegate?.isDMMessageEventBlocked(event) === true) { return false; } return (!this.eventFilter || !event.content?.kind || !this.eventFilter.has(event.content.kind)); } } //# sourceMappingURL=timelines.js.map