message: Use server capabilities to determine how to build thread list
diff: @@ -43,6 +43,10 @@ async function getThreadTimelineSet(
  room: Room,
  filterType = ThreadFilterType.All,
  ): Promise<EventTimelineSet> {
  + const capabilities = await client.getCapabilities();
  + const serverSupportsThreads = capabilities['io.element.thread']?.enabled;
  +
  + if (serverSupportsThreads) {
  const myUserId = client.getUserId();
  const filter = new Filter(myUserId);
  @@ -59,16 +63,12 @@ async function getThreadTimelineSet(
  }
  filter.setDefinition(definition);
  -
  - let timelineSet;
  -
  - try {
  const filterId = await client.getOrCreateFilter(
  `THREAD_PANEL_${room.roomId}_${filterType}`,
  filter,
  );
  filter.filterId = filterId;
  - timelineSet = room.getOrCreateFilteredTimelineSet(
  + const timelineSet = room.getOrCreateFilteredTimelineSet(
  filter,
  { prepopulateTimeline: false },
  );
  @@ -78,21 +78,21 @@ async function getThreadTimelineSet(
  timelineSet.getLiveTimeline(),
  { backwards: true, limit: 20 },
  );
  - } catch (e) {
  + return timelineSet;
  + } else {
  // Filter creation fails if HomeServer does not support the new relation
  // filter fields. We fallback to the threads that have been discovered in
  // the main timeline
  - timelineSet = new EventTimelineSet(room, {});
  + const timelineSet = new EventTimelineSet(room, {});
  for (const [, thread] of room.threads) {
  const isOwnEvent = thread.rootEvent.getSender() === client.getUserId();
  if (filterType !== ThreadFilterType.My || isOwnEvent) {
  - timelineSet.getLiveTimeline().addEvent(thread.rootEvent);
  + timelineSet.getLiveTimeline().addEvent(thread.rootEvent, false);
  }
  }
  - }
  -
  return timelineSet;
  }
  +}
  interface IProps {
  roomId: string;
  