Skip to content

Commit b560fc0

Browse files
committed
msglist: More compact rendering for edit state label.
By moving the edit state label to a Stack, we can render it over the list of reaction chips. If we stop here, the implementation works in most of the cases, but there will be an overlap when the reactions take exactly a full line. We fix that by adding an invisible copy of the `editStateLabel` widget to the end of the reaction chips list, that still occupies space during layout. It forces rewrap at the end of the list and always make space available for the actual edit state label. Signed-off-by: Zixuan James Li <[email protected]>
1 parent f7ab0ba commit b560fc0

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

lib/widgets/emoji_reaction.dart

+17-4
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,18 @@ class ReactionChipsList extends StatelessWidget {
109109
super.key,
110110
required this.messageId,
111111
required this.reactions,
112+
this.trailingPlaceholder,
112113
});
113114

114115
final int messageId;
115116
final Reactions reactions;
117+
/// A widget to force rewrapping at the end of the reaction chip list.
118+
///
119+
/// When given, it will be rendered without being visible.
120+
///
121+
/// This avoids potential overlap between the last reaction chip and the edit
122+
/// state label positioned at the bottom end of the message list.
123+
final Widget? trailingPlaceholder;
116124

117125
@override
118126
Widget build(BuildContext context) {
@@ -121,10 +129,15 @@ class ReactionChipsList extends StatelessWidget {
121129
final showNames = displayEmojiReactionUsers && reactions.total <= 3;
122130

123131
return Wrap(spacing: 4, runSpacing: 4, crossAxisAlignment: WrapCrossAlignment.center,
124-
children: reactions.aggregated.map((reactionVotes) => ReactionChip(
125-
showName: showNames,
126-
messageId: messageId, reactionWithVotes: reactionVotes),
127-
).toList());
132+
children: [
133+
...reactions.aggregated.map((reactionVotes) => ReactionChip(
134+
showName: showNames,
135+
messageId: messageId, reactionWithVotes: reactionVotes)),
136+
if (trailingPlaceholder != null)
137+
Visibility(visible: false,
138+
maintainSize: true, maintainAnimation: true, maintainState: true,
139+
child: trailingPlaceholder!),
140+
]);
128141
}
129142
}
130143

lib/widgets/message_list.dart

+26-14
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,15 @@ class MessageWithPossibleSender extends StatelessWidget {
12571257
case MessageEditState.none:
12581258
}
12591259

1260+
1261+
final editStateLabel = editStateText == null
1262+
? null
1263+
: Text(editStateText, textAlign: TextAlign.end, style: TextStyle(
1264+
color: designVariables.labelEdited,
1265+
fontSize: 12,
1266+
height: (12 / 12),
1267+
letterSpacing: proportionalLetterSpacing(
1268+
context, 0.05, baseFontSize: 12)));
12601269
return GestureDetector(
12611270
behavior: HitTestBehavior.translucent,
12621271
onLongPress: () => showMessageActionSheet(context: context, message: message),
@@ -1271,21 +1280,24 @@ class MessageWithPossibleSender extends StatelessWidget {
12711280
textBaseline: localizedTextBaseline(context),
12721281
children: [
12731282
const SizedBox(width: 16),
1274-
Expanded(child: Column(
1275-
crossAxisAlignment: CrossAxisAlignment.stretch,
1283+
Expanded(child: Stack(
12761284
children: [
1277-
MessageContent(message: message, content: item.content),
1278-
if ((message.reactions?.total ?? 0) > 0)
1279-
ReactionChipsList(messageId: message.id, reactions: message.reactions!),
1280-
if (editStateText != null)
1281-
Text(editStateText, textAlign: TextAlign.end,
1282-
style: TextStyle(
1283-
color: designVariables.labelEdited,
1284-
fontSize: 12,
1285-
height: (12 / 12),
1286-
letterSpacing: proportionalLetterSpacing(
1287-
context, 0.05, baseFontSize: 12))),
1288-
])),
1285+
Column(
1286+
crossAxisAlignment: CrossAxisAlignment.stretch,
1287+
children: [
1288+
MessageContent(message: message, content: item.content),
1289+
if ((message.reactions?.total ?? 0) > 0)
1290+
ReactionChipsList(
1291+
messageId: message.id,
1292+
reactions: message.reactions!,
1293+
// This copy of `editStateLabel` is invisible.
1294+
// See docs for more details.
1295+
trailingPlaceholder: editStateLabel),
1296+
]),
1297+
if (editStateLabel != null)
1298+
PositionedDirectional(bottom: 0, end: 0, child: editStateLabel),
1299+
],
1300+
)),
12891301
SizedBox(width: 16,
12901302
child: message.flags.contains(MessageFlag.starred)
12911303
? Icon(ZulipIcons.star_filled, size: 16, color: designVariables.star)

0 commit comments

Comments
 (0)