Skip to content

Commit 45f91aa

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 49131a2 commit 45f91aa

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

Diff for: lib/widgets/emoji_reaction.dart

+18-4
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,19 @@ 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
122+
/// visible counterpart of this widget positioned at the bottom end of the
123+
/// message list.
124+
final Widget? trailingPlaceholder;
116125

117126
@override
118127
Widget build(BuildContext context) {
@@ -121,10 +130,15 @@ class ReactionChipsList extends StatelessWidget {
121130
final showNames = displayEmojiReactionUsers && reactions.total <= 3;
122131

123132
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());
133+
children: [
134+
...reactions.aggregated.map((reactionVotes) => ReactionChip(
135+
showName: showNames,
136+
messageId: messageId, reactionWithVotes: reactionVotes)),
137+
if (trailingPlaceholder != null)
138+
Visibility(visible: false,
139+
maintainSize: true, maintainAnimation: true, maintainState: true,
140+
child: trailingPlaceholder!),
141+
]);
128142
}
129143
}
130144

Diff for: lib/widgets/message_list.dart

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

1260+
final editStateLabel = editStateText == null ? null : Text(editStateText,
1261+
textAlign: TextAlign.end,
1262+
style: TextStyle(
1263+
color: designVariables.labelEdited,
1264+
fontSize: 12,
1265+
height: (12 / 12),
1266+
letterSpacing: proportionalLetterSpacing(context, 0.05, baseFontSize: 12)));
1267+
12601268
return GestureDetector(
12611269
behavior: HitTestBehavior.translucent,
12621270
onLongPress: () => showMessageActionSheet(context: context, message: message),
@@ -1271,21 +1279,24 @@ class MessageWithPossibleSender extends StatelessWidget {
12711279
textBaseline: localizedTextBaseline(context),
12721280
children: [
12731281
const SizedBox(width: 16),
1274-
Expanded(child: Column(
1275-
crossAxisAlignment: CrossAxisAlignment.stretch,
1282+
Expanded(child: Stack(
12761283
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-
])),
1284+
Column(
1285+
crossAxisAlignment: CrossAxisAlignment.stretch,
1286+
children: [
1287+
MessageContent(message: message, content: item.content),
1288+
if ((message.reactions?.total ?? 0) > 0)
1289+
ReactionChipsList(
1290+
messageId: message.id,
1291+
reactions: message.reactions!,
1292+
// This copy of `editStateLabel` is invisible.
1293+
// See docs for more details.
1294+
trailingPlaceholder: editStateLabel),
1295+
]),
1296+
if (editStateLabel != null)
1297+
PositionedDirectional(bottom: 0, end: 0, child: editStateLabel),
1298+
],
1299+
)),
12891300
SizedBox(width: 16,
12901301
child: message.flags.contains(MessageFlag.starred)
12911302
? Icon(ZulipIcons.star_filled, size: 16, color: designVariables.star)

0 commit comments

Comments
 (0)