message: Check for timeline in pre-join UISI path
  Somehow, live events can be missing a timeline, even though that should not
  happen... This restores previous version where we test for this case.
  Fixes
diff: @@ -1171,17 +1171,27 @@ const TimelinePanel = createReactClass({
  // get the user's membership at the last event by getting the timeline
  // that the event belongs to, and traversing the timeline looking for
  // that event, while keeping track of the user's membership
  - const lastEvent = events[events.length - 1];
  - const timeline = room.getTimelineForEvent(lastEvent.getId());
  + let i;
  + let userMembership = "leave";
  + for (i = events.length - 1; i >= 0; i--) {
  + const timeline = room.getTimelineForEvent(events[i].getId());
  + if (!timeline) {
  + // Somehow, it seems to be possible for live events to not have
  + // a timeline, even though that should not happen. :(
  + // https://github.com/vector-im/riot-web/issues/12120
  + console.warn(
  + `Event ${events[i].getId()} in room ${room.roomId} is live, ` +
  + `but it does not have a timeline`,
  + );
  + continue;
  + }
  const userMembershipEvent =
  timeline.getState(EventTimeline.FORWARDS).getMember(userId);
  - let userMembership = userMembershipEvent
  - ? userMembershipEvent.membership : "leave";
  + userMembership = userMembershipEvent ? userMembershipEvent.membership : "leave";
  const timelineEvents = timeline.getEvents();
  - for (let i = timelineEvents.length - 1; i >= 0; i--) {
  - const event = timelineEvents[i];
  - if (event.getId() === lastEvent.getId()) {
  - // found the last event, so we can stop looking through the timeline
  + for (let j = timelineEvents.length - 1; j >= 0; j--) {
  + const event = timelineEvents[j];
  + if (event.getId() === events[i].getId()) {
  break;
  } else if (event.getStateKey() === userId
  && event.getType() === "m.room.member") {
  @@ -1189,10 +1199,12 @@ const TimelinePanel = createReactClass({
  userMembership = prevContent.membership || "leave";
  }
  }
  + break;
  + }
  - // now go through the events that we have and find the first undecryptable
  + // now go through the rest of the events and find the first undecryptable
  // one that was sent when the user wasn't in the room
  - for (let i = events.length - 1; i >= 0; i--) {
  + for (; i >= 0; i--) {
  const event = events[i];
  if (event.getStateKey() === userId
  && event.getType() === "m.room.member") {
  