feat(ui, localizations): add unread messages label

This commit is contained in:
Salvatore Giordano
2022-06-17 11:41:25 +02:00
parent 57d176a69c
commit f3ab200137
13 changed files with 163 additions and 7 deletions
@@ -59,5 +59,7 @@
<key>NSMicrophoneUsageDescription</key>
<string>Explain why your app uses the mic</string>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
</plist>
@@ -77,6 +77,10 @@ abstract class Translations {
/// contains a parent message
String threadSeparatorText(int replyCount);
/// The text for showing the unread messages count
/// in the [StreamMessageListView]
String unreadMessagesSeparatorText(int unreadCount);
/// The label for "connected" in [StreamConnectionStatusBuilder]
String get connectedLabel;
@@ -711,4 +715,12 @@ Attachment limit exceeded: it's not possible to add more than $limit attachments
@override
String get linkDisabledError => 'Links are disabled';
@override
String unreadMessagesSeparatorText(int unreadCount) {
if (unreadCount == 1) {
return '1 unread message';
}
return '$unreadCount unread messages';
}
}
@@ -200,6 +200,7 @@ class StreamMessageListView extends StatefulWidget {
this.onSystemMessageTap,
this.showFloatingDateDivider = true,
this.threadSeparatorBuilder,
this.unreadMessagesSeparatorBuilder,
this.messageListController,
this.reverse = true,
this.paginationLimit = 20,
@@ -337,6 +338,9 @@ class StreamMessageListView extends StatefulWidget {
/// Builder used to build the thread separator in case it's a thread view
final WidgetBuilder? threadSeparatorBuilder;
/// Builder used to build the unread message separator
final WidgetBuilder? unreadMessagesSeparatorBuilder;
/// A [MessageListController] allows pagination.
/// Use [ChannelListController.paginateData] pagination.
final MessageListController? messageListController;
@@ -363,6 +367,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
StreamChannelState? streamChannel;
late StreamChatThemeData _streamTheme;
late List<String> _userPermissions;
late int unreadCount;
int get _initialIndex {
final initialScrollIndex = widget.initialScrollIndex;
@@ -596,9 +601,12 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
return const SizedBox(height: 8);
}
if (i == 1 || i == itemCount - 4) return const Offstage();
if (i == 1 || i == itemCount - 4) {
return const Offstage();
}
late final Message message, nextMessage;
late Widget separator;
if (widget.reverse) {
message = messages[i - 1];
nextMessage = messages[i - 2];
@@ -611,7 +619,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
nextMessage.createdAt.toLocal(),
Units.DAY,
)) {
return _buildDateDivider(nextMessage);
separator = _buildDateDivider(nextMessage);
}
final timeDiff =
Jiffy(nextMessage.createdAt.toLocal()).diff(
@@ -644,13 +652,51 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
}
if (spacingRules.isNotEmpty) {
return widget.spacingWidgetBuilder
separator = widget.spacingWidgetBuilder
?.call(context, spacingRules) ??
const SizedBox(height: 8);
}
return widget.spacingWidgetBuilder
separator = widget.spacingWidgetBuilder
?.call(context, [SpacingType.defaultSpacing]) ??
const SizedBox(height: 2);
if (!isThread && unreadCount > 0 && unreadCount == i - 1) {
final unreadMessagesSeparator =
widget.unreadMessagesSeparatorBuilder?.call(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
separator,
unreadMessagesSeparator ??
Padding(
padding:
const EdgeInsets.symmetric(vertical: 8),
child: DecoratedBox(
decoration: BoxDecoration(
gradient:
_streamTheme.colorTheme.bgGradient,
),
child: Padding(
padding: const EdgeInsets.all(8),
child: Text(
context.translations
.unreadMessagesSeparatorText(
unreadCount,
),
textAlign: TextAlign.center,
style:
StreamChannelHeaderTheme.of(context)
.subtitleStyle,
),
),
),
),
],
);
}
return separator;
},
itemBuilder: (context, i) {
if (i == itemCount - 1) {
@@ -880,6 +926,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
}
Future<void> scrollToBottomDefaultTapAction(int unreadCount) async {
this.unreadCount = unreadCount;
if (unreadCount > 0) {
streamChannel!.channel.markRead();
}
@@ -890,11 +937,11 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
await streamChannel!.reloadChannel();
WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollController!.jumpTo(index: 0);
_scrollController!.jumpTo(index: unreadCount);
});
} else {
_scrollController!.scrollTo(
index: 0,
index: unreadCount,
duration: const Duration(seconds: 1),
curve: Curves.easeInOut,
);
@@ -1335,18 +1382,28 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
if (event.message?.parentId == widget.parentMessage?.id &&
event.message!.user!.id ==
streamChannel!.channel.client.state.currentUser!.id) {
setState(() {
unreadCount = 0;
});
WidgetsBinding.instance.addPostFrameCallback((_) {
_scrollController?.scrollTo(
index: 0,
duration: const Duration(seconds: 1),
);
});
} else if (streamChannel?.channel.state?.unreadCount != 0) {
setState(() {
unreadCount = unreadCount + 1;
});
}
});
if (_isThreadConversation) {
streamChannel!.getReplies(widget.parentMessage!.id);
}
unreadCount = streamChannel?.channel.state?.unreadCount ?? 0;
}
super.didChangeDependencies();