Skip to content

Commit 9c52563

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 de1288f commit 9c52563

File tree

2 files changed

+42
-18
lines changed

2 files changed

+42
-18
lines changed

lib/widgets/emoji_reaction.dart

Lines changed: 17 additions & 4 deletions
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 for holding space at the end of the reaction chips list.
118+
///
119+
/// When given, it will be rendered invisibly, making the bottom end corner
120+
/// free of reaction chips. Using [Stack] and [PositionedDirectional], a
121+
/// visible copy of [trailingPlaceholder] can be rendered there without
122+
/// overlapping reaction chips.
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

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,14 @@ class MessageWithPossibleSender extends StatelessWidget {
12581258
case MessageEditState.none:
12591259
}
12601260

1261+
final editStateLabel = editStateText == null ? null : Text(editStateText,
1262+
textAlign: TextAlign.end,
1263+
style: TextStyle(
1264+
color: designVariables.labelEdited,
1265+
fontSize: 12,
1266+
height: (12 / 12),
1267+
letterSpacing: proportionalLetterSpacing(context, 0.05, baseFontSize: 12)));
1268+
12611269
return GestureDetector(
12621270
behavior: HitTestBehavior.translucent,
12631271
onLongPress: () => showMessageActionSheet(context: context, message: message),
@@ -1272,21 +1280,24 @@ class MessageWithPossibleSender extends StatelessWidget {
12721280
textBaseline: localizedTextBaseline(context),
12731281
children: [
12741282
const SizedBox(width: 16),
1275-
Expanded(child: Column(
1276-
crossAxisAlignment: CrossAxisAlignment.stretch,
1283+
Expanded(child: Stack(
12771284
children: [
1278-
MessageContent(message: message, content: item.content),
1279-
if ((message.reactions?.total ?? 0) > 0)
1280-
ReactionChipsList(messageId: message.id, reactions: message.reactions!),
1281-
if (editStateText != null)
1282-
Text(editStateText, textAlign: TextAlign.end,
1283-
style: TextStyle(
1284-
color: designVariables.labelEdited,
1285-
fontSize: 12,
1286-
height: (12 / 12),
1287-
letterSpacing: proportionalLetterSpacing(
1288-
context, 0.05, baseFontSize: 12))),
1289-
])),
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+
)),
12901301
SizedBox(width: 16,
12911302
child: message.flags.contains(MessageFlag.starred)
12921303
? Icon(ZulipIcons.star_filled, size: 16, color: designVariables.star)

0 commit comments

Comments
 (0)