diff --git a/packages/stream_chat_flutter/example/ios/Runner/Info.plist b/packages/stream_chat_flutter/example/ios/Runner/Info.plist
index a74aeed0..299ebd4c 100644
--- a/packages/stream_chat_flutter/example/ios/Runner/Info.plist
+++ b/packages/stream_chat_flutter/example/ios/Runner/Info.plist
@@ -59,5 +59,7 @@
NSMicrophoneUsageDescription
Explain why your app uses the mic
+ CADisableMinimumFrameDurationOnPhone
+
diff --git a/packages/stream_chat_flutter/lib/src/localization/translations.dart b/packages/stream_chat_flutter/lib/src/localization/translations.dart
index 3f29704f..27094c80 100644
--- a/packages/stream_chat_flutter/lib/src/localization/translations.dart
+++ b/packages/stream_chat_flutter/lib/src/localization/translations.dart
@@ -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';
+ }
}
diff --git a/packages/stream_chat_flutter/lib/src/message_list_view.dart b/packages/stream_chat_flutter/lib/src/message_list_view.dart
index b2256190..2978df32 100644
--- a/packages/stream_chat_flutter/lib/src/message_list_view.dart
+++ b/packages/stream_chat_flutter/lib/src/message_list_view.dart
@@ -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 {
StreamChannelState? streamChannel;
late StreamChatThemeData _streamTheme;
late List _userPermissions;
+ late int unreadCount;
int get _initialIndex {
final initialScrollIndex = widget.initialScrollIndex;
@@ -596,9 +601,12 @@ class _StreamMessageListViewState extends State {
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 {
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 {
}
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 {
}
Future scrollToBottomDefaultTapAction(int unreadCount) async {
+ this.unreadCount = unreadCount;
if (unreadCount > 0) {
streamChannel!.channel.markRead();
}
@@ -890,11 +937,11 @@ class _StreamMessageListViewState extends State {
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 {
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();
diff --git a/packages/stream_chat_localizations/example/lib/add_new_lang.dart b/packages/stream_chat_localizations/example/lib/add_new_lang.dart
index 9becad2d..6ca047f1 100644
--- a/packages/stream_chat_localizations/example/lib/add_new_lang.dart
+++ b/packages/stream_chat_localizations/example/lib/add_new_lang.dart
@@ -405,6 +405,14 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations {
@override
String get viewLibrary => 'View library';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '1 unread message';
+ }
+ return '$unreadCount unread messages';
+ }
}
void main() async {
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart
index 71af15fa..0ad26f34 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_de.dart
@@ -381,4 +381,12 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations {
@override
String get viewLibrary => 'Bibliothek öffnen';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '1 ungelesene Nachricht';
+ }
+ return '$unreadCount ungelesene Nachrichten';
+ }
}
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart
index ead459fa..cf00e816 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_en.dart
@@ -381,4 +381,12 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations {
@override
String get viewLibrary => 'View library';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '1 unread message';
+ }
+ return '$unreadCount unread messages';
+ }
}
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart
index d26e033a..3e85123d 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_es.dart
@@ -387,4 +387,12 @@ No es posible añadir más de $limit archivos adjuntos
@override
String get linkDisabledError => 'Los enlaces están deshabilitados';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '1 mensaje no leído';
+ }
+ return '$unreadCount mensajes no leídos';
+ }
}
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart
index 5521ef57..c41547c3 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_fr.dart
@@ -386,4 +386,12 @@ Limite de pièces jointes dépassée : il n'est pas possible d'ajouter plus de $
@override
String get linkDisabledError => 'Les liens sont désactivés';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '1 message non lu';
+ }
+ return '$unreadCount messages non lus';
+ }
}
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart
index 20ae9db2..be1153e9 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_hi.dart
@@ -380,4 +380,12 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations {
@override
String get linkDisabledError => 'लिंक भेजना प्रतिबंधित';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '1 अपठित संदेश';
+ }
+ return '$unreadCount अपठित संदेश';
+ }
}
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart
index f8b21ed4..eb62d655 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_it.dart
@@ -40,7 +40,12 @@ class StreamChatLocalizationsIt extends GlobalStreamChatLocalizations {
String get onlyVisibleToYouText => 'Visible solo a te';
@override
- String threadReplyCountText(int count) => '$count risposte al thread';
+ String threadReplyCountText(int count) {
+ if (count == 1) {
+ return '1 risposta al thread';
+ }
+ return '$count risposte al thread';
+ }
@override
String attachmentsUploadProgressText({
@@ -383,4 +388,12 @@ Attenzione: il limite massimo di $limit file è stato superato.
@override
String get linkDisabledError => 'I links sono disattivati';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '1 messaggio non letto';
+ }
+ return '$unreadCount messaggi non letti';
+ }
}
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart
index 2faae6c4..3e5d5b37 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ja.dart
@@ -365,4 +365,12 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations {
@override
String get linkDisabledError => 'リンクが無効になっています';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '未読メッセージ1通';
+ }
+ return '$unreadCountつの未読メッセージ';
+ }
}
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart
index e541e529..519cd3cf 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_ko.dart
@@ -366,4 +366,12 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations {
@override
String get linkDisabledError => '링크가 비활성화되었습니다.';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '읽지 않은 메시지 1개';
+ }
+ return '읽지 않은 메시지 $unreadCount개';
+ }
}
diff --git a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart
index 74e9a1f4..d761a45b 100644
--- a/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart
+++ b/packages/stream_chat_localizations/lib/src/stream_chat_localizations_pt.dart
@@ -384,4 +384,12 @@ Não é possível adicionar mais de $limit arquivos de uma vez
@override
String get viewLibrary => 'Ver biblioteca';
+
+ @override
+ String unreadMessagesSeparatorText(int unreadCount) {
+ if (unreadCount == 1) {
+ return '1 mensagem não lida';
+ }
+ return '$unreadCount mensagens não lidas';
+ }
}