diff --git a/android/build/reports/problems/problems-report.html b/android/build/reports/problems/problems-report.html
index 2e4e670..f85479d 100644
--- a/android/build/reports/problems/problems-report.html
+++ b/android/build/reports/problems/problems-report.html
@@ -650,7 +650,7 @@ code + .copy-button {
diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart
index 96d7fc3..b6eef99 100644
--- a/lib/pages/chat/chat.dart
+++ b/lib/pages/chat/chat.dart
@@ -380,14 +380,32 @@ class ChatController extends State
scrollUpBannerEventId = eventId;
});
- void updateView() {
+ Future updateView() async {
if (!mounted) return;
setReadMarker();
+ await updateThreads();
setState(() {});
}
+ Future updateThreads() async {
+ if (timeline?.events == null) return;
+ final lastEvent = timeline?.events[timeline!.events.length - 1];
+
+ if (lastEvent == null) return;
+ if (lastEvent.relationshipType == RelationshipTypes.thread &&
+ lastEvent.relationshipEventId != null) {
+ final thread = await room.client.database
+ .getThread(room.id, lastEvent.relationshipEventId!, room.client);
+ if (thread != null) {
+ setState(() {
+ threads?[lastEvent.eventId] = thread;
+ });
+ }
+ }
+ }
+
Future? loadTimelineFuture;
- Map? threads;
+ Map? threads = {};
int? animateInEventIndex;
@@ -437,9 +455,10 @@ class ChatController extends State
Logs().v("Thread timeline loaded");
} catch (e, s) {
Logs().w(
- 'Unable to load timeline on event ID $eventContextId (in thread)',
- e,
- s);
+ 'Unable to load timeline on event ID $eventContextId (in thread)',
+ e,
+ s,
+ );
if (!mounted) return;
timeline = await thread!.getTimeline(
onUpdate: updateView,
@@ -595,13 +614,15 @@ class ChatController extends State
}
// ignore: unawaited_futures
- room.sendTextEvent(sendController.text,
- inReplyTo: replyEvent,
- editEventId: editEvent?.eventId,
- parseCommands: parseCommands,
- threadRootEventId: thread?.rootEvent.eventId,
- threadLastEventId:
- thread?.lastEvent?.eventId ?? thread?.rootEvent.eventId);
+ room.sendTextEvent(
+ sendController.text,
+ inReplyTo: replyEvent,
+ editEventId: editEvent?.eventId,
+ parseCommands: parseCommands,
+ threadRootEventId: thread?.rootEvent.eventId,
+ threadLastEventId:
+ thread?.lastEvent?.eventId ?? thread?.rootEvent.eventId,
+ );
sendController.value = TextEditingValue(
text: pendingText,
selection: const TextSelection.collapsed(offset: 0),
@@ -821,7 +842,8 @@ class ChatController extends State
final reports = await mx.client.getEventReports();
final report = reports.firstWhere(
- (rep) => rep['room_id'] == roomId && rep['event_id'] == event.eventId);
+ (rep) => rep['room_id'] == roomId && rep['event_id'] == event.eventId,
+ );
final recoveredEvent = await mx.client.getReportedEvent(report['id']);
if (recoveredEvent == null) {
@@ -831,15 +853,17 @@ class ChatController extends State
return;
}
- Navigator.of(context).push(MaterialPageRoute(
- builder: (BuildContext ctx) {
- return RecoveredEventDialog(
- event: recoveredEvent,
- timeline: timeline!,
- );
- },
- fullscreenDialog: true,
- ));
+ Navigator.of(context).push(
+ MaterialPageRoute(
+ builder: (BuildContext ctx) {
+ return RecoveredEventDialog(
+ event: recoveredEvent,
+ timeline: timeline!,
+ );
+ },
+ fullscreenDialog: true,
+ ),
+ );
}
void translateEventAction() async {
@@ -854,7 +878,9 @@ class ChatController extends State
final content = {...event.content};
try {
text = await Translator.translate(
- text, PlatformDispatcher.instance.locale.languageCode);
+ text,
+ PlatformDispatcher.instance.locale.languageCode,
+ );
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).errorTranslatingMessage)),
@@ -867,19 +893,24 @@ class ChatController extends State
content['body'] = text;
}
content['xyz.extera.translated'] = true;
- Navigator.of(context).push(new MaterialPageRoute(
+ Navigator.of(context).push(
+ new MaterialPageRoute(
builder: (BuildContext ctx) {
return TranslatedEventDialog(
- event: new Event(
- content: content,
- type: 'm.room.message',
- eventId: event.eventId,
- senderId: event.senderId,
- originServerTs: event.originServerTs,
- room: room),
- timeline: timeline!);
+ event: new Event(
+ content: content,
+ type: 'm.room.message',
+ eventId: event.eventId,
+ senderId: event.senderId,
+ originServerTs: event.originServerTs,
+ room: room,
+ ),
+ timeline: timeline!,
+ );
},
- fullscreenDialog: true));
+ fullscreenDialog: true,
+ ),
+ );
}
void reportEventAction() async {
diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart
index 178dc72..f807fd4 100644
--- a/lib/pages/chat/chat_event_list.dart
+++ b/lib/pages/chat/chat_event_list.dart
@@ -39,6 +39,7 @@ class ChatEventList extends StatelessWidget {
final events = timeline.events.filterByVisibleInGui().filterByThreaded(controller.thread != null);
final animateInEventIndex = controller.animateInEventIndex;
+ final threads = controller.room.threads;
// create a map of eventId --> index to greatly improve performance of
// ListView's findChildIndexCallback
@@ -121,8 +122,8 @@ class ChatEventList extends StatelessWidget {
timeline.events.length > animateInEventIndex &&
event == timeline.events[animateInEventIndex];
- final thread = (controller.threads?.containsKey(event.eventId) ?? false)
- ? controller.threads![event.eventId]
+ final thread = threads.containsKey(event.eventId)
+ ? threads[event.eventId]
: null;
return AutoScrollTag(
diff --git a/lib/pages/chat/events/poll_content.dart b/lib/pages/chat/events/poll_content.dart
index 579f63e..33fb26b 100644
--- a/lib/pages/chat/events/poll_content.dart
+++ b/lib/pages/chat/events/poll_content.dart
@@ -58,8 +58,12 @@ class PollWidgetState extends State {
final rel = await Matrix.of(context)
.client
- .getRelatingEventsWithRelTypeAndEventType(room.id, widget.event.eventId,
- "m.reference", "org.matrix.msc3381.poll.response");
+ .getRelatingEventsWithRelTypeAndEventType(
+ room.id,
+ widget.event.eventId,
+ "m.reference",
+ "org.matrix.msc3381.poll.response",
+ );
// Get all poll response events for this poll
final responses = rel.chunk;
@@ -90,8 +94,12 @@ class PollWidgetState extends State {
final rel = await Matrix.of(context)
.client
- .getRelatingEventsWithRelTypeAndEventType(room.id, pollEventId,
- "m.reference", "org.matrix.msc3381.poll.response");
+ .getRelatingEventsWithRelTypeAndEventType(
+ room.id,
+ pollEventId,
+ "m.reference",
+ "org.matrix.msc3381.poll.response",
+ );
// Get all poll response events for this poll
final responses = rel.chunk;
@@ -124,15 +132,18 @@ class PollWidgetState extends State {
final room = widget.event.room;
// Send poll response event
- await room.sendEvent({
- 'm.relates_to': {
- 'rel_type': 'm.reference',
- 'event_id': widget.event.eventId,
+ await room.sendEvent(
+ {
+ 'm.relates_to': {
+ 'rel_type': 'm.reference',
+ 'event_id': widget.event.eventId,
+ },
+ 'org.matrix.msc3381.poll.response': {
+ 'answers': answers,
+ },
},
- 'org.matrix.msc3381.poll.response': {
- 'answers': answers,
- },
- }, type: 'org.matrix.msc3381.poll.response');
+ type: 'org.matrix.msc3381.poll.response',
+ );
setState(() {
selectedAnswers = answers;
@@ -369,9 +380,11 @@ class PollWidgetState extends State {
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
)
- : Text(hasVoted
- ? L10n.of(context).changeVote
- : L10n.of(context).vote),
+ : Text(
+ hasVoted
+ ? L10n.of(context).changeVote
+ : L10n.of(context).vote,
+ ),
),
const Spacer(),