update thread card

This commit is contained in:
OfficialDakari 2025-10-26 20:58:25 +05:00
parent 22209b03f2
commit 1c5a632d2a
4 changed files with 96 additions and 51 deletions

File diff suppressed because one or more lines are too long

View File

@ -380,14 +380,32 @@ class ChatController extends State<ChatPageWithRoom>
scrollUpBannerEventId = eventId; scrollUpBannerEventId = eventId;
}); });
void updateView() { Future<void> updateView() async {
if (!mounted) return; if (!mounted) return;
setReadMarker(); setReadMarker();
await updateThreads();
setState(() {}); setState(() {});
} }
Future<void> 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<void>? loadTimelineFuture; Future<void>? loadTimelineFuture;
Map<String, Thread>? threads; Map<String, Thread>? threads = {};
int? animateInEventIndex; int? animateInEventIndex;
@ -439,7 +457,8 @@ class ChatController extends State<ChatPageWithRoom>
Logs().w( Logs().w(
'Unable to load timeline on event ID $eventContextId (in thread)', 'Unable to load timeline on event ID $eventContextId (in thread)',
e, e,
s); s,
);
if (!mounted) return; if (!mounted) return;
timeline = await thread!.getTimeline( timeline = await thread!.getTimeline(
onUpdate: updateView, onUpdate: updateView,
@ -595,13 +614,15 @@ class ChatController extends State<ChatPageWithRoom>
} }
// ignore: unawaited_futures // ignore: unawaited_futures
room.sendTextEvent(sendController.text, room.sendTextEvent(
sendController.text,
inReplyTo: replyEvent, inReplyTo: replyEvent,
editEventId: editEvent?.eventId, editEventId: editEvent?.eventId,
parseCommands: parseCommands, parseCommands: parseCommands,
threadRootEventId: thread?.rootEvent.eventId, threadRootEventId: thread?.rootEvent.eventId,
threadLastEventId: threadLastEventId:
thread?.lastEvent?.eventId ?? thread?.rootEvent.eventId); thread?.lastEvent?.eventId ?? thread?.rootEvent.eventId,
);
sendController.value = TextEditingValue( sendController.value = TextEditingValue(
text: pendingText, text: pendingText,
selection: const TextSelection.collapsed(offset: 0), selection: const TextSelection.collapsed(offset: 0),
@ -821,7 +842,8 @@ class ChatController extends State<ChatPageWithRoom>
final reports = await mx.client.getEventReports(); final reports = await mx.client.getEventReports();
final report = reports.firstWhere( 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']); final recoveredEvent = await mx.client.getReportedEvent(report['id']);
if (recoveredEvent == null) { if (recoveredEvent == null) {
@ -831,7 +853,8 @@ class ChatController extends State<ChatPageWithRoom>
return; return;
} }
Navigator.of(context).push(MaterialPageRoute( Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext ctx) { builder: (BuildContext ctx) {
return RecoveredEventDialog( return RecoveredEventDialog(
event: recoveredEvent, event: recoveredEvent,
@ -839,7 +862,8 @@ class ChatController extends State<ChatPageWithRoom>
); );
}, },
fullscreenDialog: true, fullscreenDialog: true,
)); ),
);
} }
void translateEventAction() async { void translateEventAction() async {
@ -854,7 +878,9 @@ class ChatController extends State<ChatPageWithRoom>
final content = {...event.content}; final content = {...event.content};
try { try {
text = await Translator.translate( text = await Translator.translate(
text, PlatformDispatcher.instance.locale.languageCode); text,
PlatformDispatcher.instance.locale.languageCode,
);
} catch (e) { } catch (e) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(L10n.of(context).errorTranslatingMessage)), SnackBar(content: Text(L10n.of(context).errorTranslatingMessage)),
@ -867,7 +893,8 @@ class ChatController extends State<ChatPageWithRoom>
content['body'] = text; content['body'] = text;
} }
content['xyz.extera.translated'] = true; content['xyz.extera.translated'] = true;
Navigator.of(context).push(new MaterialPageRoute( Navigator.of(context).push(
new MaterialPageRoute(
builder: (BuildContext ctx) { builder: (BuildContext ctx) {
return TranslatedEventDialog( return TranslatedEventDialog(
event: new Event( event: new Event(
@ -876,10 +903,14 @@ class ChatController extends State<ChatPageWithRoom>
eventId: event.eventId, eventId: event.eventId,
senderId: event.senderId, senderId: event.senderId,
originServerTs: event.originServerTs, originServerTs: event.originServerTs,
room: room), room: room,
timeline: timeline!); ),
timeline: timeline!,
);
}, },
fullscreenDialog: true)); fullscreenDialog: true,
),
);
} }
void reportEventAction() async { void reportEventAction() async {

View File

@ -39,6 +39,7 @@ class ChatEventList extends StatelessWidget {
final events = timeline.events.filterByVisibleInGui().filterByThreaded(controller.thread != null); final events = timeline.events.filterByVisibleInGui().filterByThreaded(controller.thread != null);
final animateInEventIndex = controller.animateInEventIndex; final animateInEventIndex = controller.animateInEventIndex;
final threads = controller.room.threads;
// create a map of eventId --> index to greatly improve performance of // create a map of eventId --> index to greatly improve performance of
// ListView's findChildIndexCallback // ListView's findChildIndexCallback
@ -121,8 +122,8 @@ class ChatEventList extends StatelessWidget {
timeline.events.length > animateInEventIndex && timeline.events.length > animateInEventIndex &&
event == timeline.events[animateInEventIndex]; event == timeline.events[animateInEventIndex];
final thread = (controller.threads?.containsKey(event.eventId) ?? false) final thread = threads.containsKey(event.eventId)
? controller.threads![event.eventId] ? threads[event.eventId]
: null; : null;
return AutoScrollTag( return AutoScrollTag(

View File

@ -58,8 +58,12 @@ class PollWidgetState extends State<PollWidget> {
final rel = await Matrix.of(context) final rel = await Matrix.of(context)
.client .client
.getRelatingEventsWithRelTypeAndEventType(room.id, widget.event.eventId, .getRelatingEventsWithRelTypeAndEventType(
"m.reference", "org.matrix.msc3381.poll.response"); room.id,
widget.event.eventId,
"m.reference",
"org.matrix.msc3381.poll.response",
);
// Get all poll response events for this poll // Get all poll response events for this poll
final responses = rel.chunk; final responses = rel.chunk;
@ -90,8 +94,12 @@ class PollWidgetState extends State<PollWidget> {
final rel = await Matrix.of(context) final rel = await Matrix.of(context)
.client .client
.getRelatingEventsWithRelTypeAndEventType(room.id, pollEventId, .getRelatingEventsWithRelTypeAndEventType(
"m.reference", "org.matrix.msc3381.poll.response"); room.id,
pollEventId,
"m.reference",
"org.matrix.msc3381.poll.response",
);
// Get all poll response events for this poll // Get all poll response events for this poll
final responses = rel.chunk; final responses = rel.chunk;
@ -124,7 +132,8 @@ class PollWidgetState extends State<PollWidget> {
final room = widget.event.room; final room = widget.event.room;
// Send poll response event // Send poll response event
await room.sendEvent({ await room.sendEvent(
{
'm.relates_to': { 'm.relates_to': {
'rel_type': 'm.reference', 'rel_type': 'm.reference',
'event_id': widget.event.eventId, 'event_id': widget.event.eventId,
@ -132,7 +141,9 @@ class PollWidgetState extends State<PollWidget> {
'org.matrix.msc3381.poll.response': { 'org.matrix.msc3381.poll.response': {
'answers': answers, 'answers': answers,
}, },
}, type: 'org.matrix.msc3381.poll.response'); },
type: 'org.matrix.msc3381.poll.response',
);
setState(() { setState(() {
selectedAnswers = answers; selectedAnswers = answers;
@ -369,9 +380,11 @@ class PollWidgetState extends State<PollWidget> {
height: 16, height: 16,
child: CircularProgressIndicator(strokeWidth: 2), child: CircularProgressIndicator(strokeWidth: 2),
) )
: Text(hasVoted : Text(
hasVoted
? L10n.of(context).changeVote ? L10n.of(context).changeVote
: L10n.of(context).vote), : L10n.of(context).vote,
),
), ),
const Spacer(), const Spacer(),