We could take the approach of gradually taking things over from the sync accumulator. We keep the sync accumulator (and the periodic storing) until the last thing it stores is ported over.
The natural thing to start with would be storing timeline events the way brawl does:
- have a store for timeline fragments (an area in the timeline where events are only prepended or appended, also storing pagination tokens)
- have a store for timeline events (linked to a fragment)
At first sight, the following code would be heavily affected by this change:
- EventTimelineSet
- EventTimeline
- TimelineWindow
Room
would gain an openTimeline()
method that returns a Timeline
object exposes an ObservableList
of timeline entries (both gaps and events). This is then passed to a collection that implements event grouping, event continuation, date separators ... and maps them to something an EventTile react view can render (see TilesCollection
in Brawl). Timeline
implements gap filling and pagination.
Are there any other parts of the app that depend heavily on the api of the EventTimeline(Set)?
We could keep the RoomState objects on the fragments that we keep in memory, and have the live RoomState on the Room object?
It would also make sense to introduce a more natural way to have local echos and relations between events in the timeline as well, or at least not make it hard to add it later during this step.
Perhaps it would be possible to keep using the TimelineWindow API to request loading more things, although it might be a small change to actually call to a method on the room or timeline object directly.
A next step could be to store pending events in their own store (would finally make riot not loose unsent messages when refreshing)
accumulate syncs into a room summary object storing:
- room name
- room alias(es)
- is dm?
- is encrypted?
- room member count
- own membership
this is the only part that needs to be loaded to display the room list
Brawl doesn't do much with room state events yet, but have some notes on how this could work.
We could use a non-react ListView as happens now in Brawl, and render a UIView
component for items that creates a container li
element, and mounts a react component into it with ReactDOM.render
. If the ListView receives an update for an item in the list, it calls update
on the child UIView
which calls ReactDOM.render
again to update it. On unmount, ReactDOM.unmountComponentAtNode()
is called. Efficient lists, and we get to keep react. As prop to the react component, we'd just pass the value? How do we ensure it is always updated? I think render
might always update, even if the props are identical. In the worst case we can pass a number as a prop that increases with every update...