diff --git a/lib/models/message.dart b/lib/models/message.dart index 866306b0..4c6956d3 100644 --- a/lib/models/message.dart +++ b/lib/models/message.dart @@ -32,7 +32,7 @@ const GroupConversationHandleLength = 32; abstract class Message { MessageMetadata getMetadata(); - Widget getWidget(BuildContext context); + Widget getWidget(BuildContext context, Key key); Widget getPreviewWidget(BuildContext context); } diff --git a/lib/models/messages/filemessage.dart b/lib/models/messages/filemessage.dart index e4d0bc7b..c68b24e5 100644 --- a/lib/models/messages/filemessage.dart +++ b/lib/models/messages/filemessage.dart @@ -18,7 +18,7 @@ class FileMessage extends Message { FileMessage(this.metadata, this.content); @override - Widget getWidget(BuildContext context) { + Widget getWidget(BuildContext context, Key key) { return ChangeNotifierProvider.value( value: this.metadata, builder: (bcontext, child) { @@ -42,7 +42,7 @@ class FileMessage extends Message { return MessageRow(MalformedBubble()); } - return MessageRow(FileBubble(nameSuggestion, rootHash, nonce, fileSize, isAuto: metadata.isAuto)); + return MessageRow(FileBubble(nameSuggestion, rootHash, nonce, fileSize, isAuto: metadata.isAuto), key: key); }); } diff --git a/lib/models/messages/invitemessage.dart b/lib/models/messages/invitemessage.dart index f1d1d18b..50a28806 100644 --- a/lib/models/messages/invitemessage.dart +++ b/lib/models/messages/invitemessage.dart @@ -17,7 +17,7 @@ class InviteMessage extends Message { InviteMessage(this.overlay, this.metadata, this.content); @override - Widget getWidget(BuildContext context) { + Widget getWidget(BuildContext context, Key key) { return ChangeNotifierProvider.value( value: this.metadata, builder: (bcontext, child) { @@ -39,7 +39,7 @@ class InviteMessage extends Message { return MessageRow(MalformedBubble()); } } - return MessageRow(InvitationBubble(overlay, inviteTarget, inviteNick, invite)); + return MessageRow(InvitationBubble(overlay, inviteTarget, inviteNick, invite), key: key); }); } diff --git a/lib/models/messages/malformedmessage.dart b/lib/models/messages/malformedmessage.dart index dc943fe1..0ebf2281 100644 --- a/lib/models/messages/malformedmessage.dart +++ b/lib/models/messages/malformedmessage.dart @@ -9,11 +9,11 @@ class MalformedMessage extends Message { MalformedMessage(this.metadata); @override - Widget getWidget(BuildContext context) { + Widget getWidget(BuildContext context, Key key) { return ChangeNotifierProvider.value( value: this.metadata, builder: (context, child) { - return MessageRow(MalformedBubble()); + return MessageRow(MalformedBubble(), key: key); }); } diff --git a/lib/models/messages/quotedmessage.dart b/lib/models/messages/quotedmessage.dart index 774c0c41..c43ac12c 100644 --- a/lib/models/messages/quotedmessage.dart +++ b/lib/models/messages/quotedmessage.dart @@ -48,7 +48,7 @@ class QuotedMessage extends Message { } @override - Widget getWidget(BuildContext context) { + Widget getWidget(BuildContext context, Key key) { try { dynamic message = jsonDecode(this.content); @@ -59,7 +59,7 @@ class QuotedMessage extends Message { return ChangeNotifierProvider.value( value: this.metadata, builder: (bcontext, child) { - return MessageRow(QuotedMessageBubble(message["body"], messageHandler(bcontext, metadata.profileOnion, metadata.conversationIdentifier, ByContentHash(message["quotedHash"])))); + return MessageRow(QuotedMessageBubble(message["body"], messageHandler(bcontext, metadata.profileOnion, metadata.conversationIdentifier, ByContentHash(message["quotedHash"]))), key: key); }); } catch (e) { return MalformedBubble(); diff --git a/lib/models/messages/textmessage.dart b/lib/models/messages/textmessage.dart index 00cd14f7..44f99510 100644 --- a/lib/models/messages/textmessage.dart +++ b/lib/models/messages/textmessage.dart @@ -29,12 +29,13 @@ class TextMessage extends Message { } @override - Widget getWidget(BuildContext context) { + Widget getWidget(BuildContext context, Key key) { return ChangeNotifierProvider.value( value: this.metadata, builder: (bcontext, child) { return MessageRow( MessageBubble(this.content), + key: key, ); }); } diff --git a/lib/widgets/messagelist.dart b/lib/widgets/messagelist.dart index e6f642b2..ec644504 100644 --- a/lib/widgets/messagelist.dart +++ b/lib/widgets/messagelist.dart @@ -87,7 +87,11 @@ class _MessageListState extends State { builder: (context, snapshot) { if (snapshot.hasData) { var message = snapshot.data as Message; - return message.getWidget(context); + // here we create an index key for the contact and assign it to the row. Indexes are unique so we can + // reliably use this without running into duplicate keys...it isn't ideal as it means keys need to be re-built + // when new messages are added...however it is better than the alternative of not having widget keys at all. + var key = Provider.of(outerContext, listen: false).getMessageKey(contactHandle, messageIndex); + return message.getWidget(context, key); } else { return MessageLoadingBubble(); }