Typed Event Emitter class which can act as a Base Model for all our model and communication events. This makes it much easier for us to distinguish between events, as we now need to properly type this, so that our events are not stringly-based and prone to silly typos.

Type parameters:

  • Events - List of all events emitted by this TypedEventEmitter. Normally an enum type.
  • Arguments - A ListenerMap type providing mappings from event names to listener types.
  • SuperclassArguments - TODO: not really sure. Alternative listener mappings, I think? But only honoured for .emit?

Hierarchy (View Summary)

Constructors

Properties

client: MatrixClient
id: string
initialEventsFetched: boolean = !Thread.hasServerSideSupport

Whether or not we need to fetch the initial set of events for the thread. We can only do this if the server has support for it, so if it doesn't we just pretend that we've already fetched them.

replayEvents: null | MatrixEvent[] = []

An array of events to add to the timeline once the thread has been initialised with server suppport.

room: Room
rootEvent: undefined | MatrixEvent
timelineSet: EventTimelineSet

A reference to all the events ID at the bottom of the threads

hasServerSideFwdPaginationSupport: FeatureSupport = FeatureSupport.None
hasServerSideListSupport: FeatureSupport = FeatureSupport.None
hasServerSideSupport: FeatureSupport = FeatureSupport.None

Accessors

  • get length(): number
  • The number of messages in the thread Only count rel_type=m.thread as we want to exclude annotations from that number

    Returns number

  • get replyToEvent(): Optional<MatrixEvent>
  • A getter for the last event of the thread. This might be a synthesized event, if so, it will not emit any events to listeners.

    Returns Optional<MatrixEvent>

  • get timeline(): MatrixEvent[]
  • The live event timeline for this thread.

    Returns MatrixEvent[]

    The live event timeline for this thread.

    Present for backwards compatibility. Use this.events instead

Methods

  • Add an event to the thread and updates the tail/root references if needed Will fire "Thread.update"

    Parameters

    • event: MatrixEvent

      The event to add

    • toStartOfTimeline: boolean

      whether the event is being added to the start (and not the end) of the timeline.

    • emit: boolean = true

      whether to emit the Update event if the thread was updated or not.

    Returns void

  • Add a temporary local-echo receipt to the room to reflect in the client the fact that we've sent one.

    Parameters

    • userId: string

      The user ID if the receipt sender

    • e: MatrixEvent

      The event that is to be acknowledged

    • receiptType: ReceiptType

      The type of receipt

    • unthreaded: boolean = false

      the receipt is unthreaded

    Returns void

  • This issue should also be addressed on synapse's side and is tracked as part of https://github.com/matrix-org/synapse/issues/14837

    Retrieves the read receipt for the logged in user and checks if it matches the last event in the room and whether that event originated from the logged in user. Under those conditions we can consider the context as read. This is useful because we never send read receipts against our own events

    Parameters

    • userId: string

      the logged in user

    Returns void

  • Get the ID of the event that a given user has read up to within this thread, or null if we have received no read receipt (at all) from them.

    Parameters

    • userId: string

      The user ID to get read receipt event ID for

    • OptionalignoreSynthesized: boolean

      If true, return only receipts that have been sent by the server, not implicit ones generated by the JS SDK.

    Returns null | string

    ID of the latest event that the given user has read, or null.

  • Returns the most recent unthreaded receipt for a given user

    Parameters

    • userId: string

      the MxID of the User

    Returns undefined | Receipt

    an unthreaded Receipt. Can be undefined if receipts have been disabled or a user chooses to use private read receipts (or we have simply not received a receipt from this user yet).

  • Gets the latest receipt for a given user in the room

    Parameters

    • userId: string

      The id of the user for which we want the receipt

    • ignoreSynthesized: boolean = false

      Whether to ignore synthesized receipts or not

    • receiptType: ReceiptType = ReceiptType.Read

      Optional. The type of the receipt we want to get

    Returns null | WrappedReceipt

    the latest receipts of the chosen type for the chosen user

  • Determine if the given user has read a particular event.

    It is invalid to call this method with an event that is not part of this thread.

    This is not a definitive check as it only checks the events that have been loaded client-side at the time of execution.

    Parameters

    • userId: string

      The user ID to check the read state of.

    • eventId: string

      The event ID to check if the user read.

    Returns boolean

    True if the user has read the event, false otherwise.

  • Internal

    TEMPORARY. Only call this when MSC3981 is not available, and we have some late-arriving events to insert, because we recursively found them as part of populating a thread. When we have MSC3981 we won't need it, because they will all be supplied by the homeserver in one request, and they will already be in the right order in that response. This is a copy of addEventToTimeline above, modified to call insertEventIntoTimeline so this event is inserted into our best guess of the right place based on timestamp. (We should be using Sync Order but we don't have it.)

    Parameters

    Returns void

  • Reset the live timeline of all timelineSets, and start new ones.

    This is used when /sync returns a 'limited' timeline. 'Limited' means that there's a gap between the messages /sync returned, and the last known message in our timeline. In such a case, our live timeline isn't live anymore and has to be replaced by a new one. To make sure we can continue paginating our timelines correctly, we have to set new pagination tokens on the old and the new timeline.

    Parameters

    • OptionalbackPaginationToken: null | string

      token for back-paginating the new timeline

    • OptionalforwardPaginationToken: null | string

      token for forward-paginating the old live timeline, if absent or null, all timelines are reset, removing old ones (including the previous live timeline which would otherwise be unable to paginate forwards without this token). Removing just the old live timeline whilst preserving previous ones is not supported.

    Returns Promise<void>