fix rebuild message list view
This commit is contained in:
@@ -70,8 +70,11 @@ class Channel {
|
||||
true;
|
||||
|
||||
/// Returns true if the channel is muted as a stream
|
||||
Stream<bool>? get isMutedStream => _client.state.userStream.map((event) =>
|
||||
event!.channelMutes.any((element) => element.channel.cid == cid) == true);
|
||||
Stream<bool>? get isMutedStream => _client.state.userStream
|
||||
.map((event) =>
|
||||
event!.channelMutes.any((element) => element.channel.cid == cid) ==
|
||||
true)
|
||||
.distinct();
|
||||
|
||||
/// True if the channel is a group
|
||||
bool get isGroup => memberCount != 2;
|
||||
@@ -1604,7 +1607,7 @@ class ChannelClientState {
|
||||
/// Channel message list as a stream
|
||||
Stream<List<Message>?> get messagesStream => channelStateStream
|
||||
.map((cs) => cs.messages)
|
||||
.distinct((prev, next) => const ListEquality().equals(prev, next));
|
||||
.distinct(const ListEquality().equals);
|
||||
|
||||
/// Channel pinned message list
|
||||
List<Message>? get pinnedMessages => _channelState.pinnedMessages.toList();
|
||||
@@ -1634,7 +1637,7 @@ class ChannelClientState {
|
||||
_channel.client.state.usersStream,
|
||||
(members, users) =>
|
||||
members!.map((e) => e!.copyWith(user: users[e.user!.id])).toList(),
|
||||
);
|
||||
).distinct(const ListEquality().equals);
|
||||
|
||||
/// Channel watcher count
|
||||
int? get watcherCount => _channelState.watcherCount;
|
||||
@@ -1804,7 +1807,9 @@ class ChannelClientState {
|
||||
List<User> get typingEvents => _typingEventsController.value;
|
||||
|
||||
/// Channel related typing users stream
|
||||
Stream<List<User>> get typingEventsStream => _typingEventsController.stream;
|
||||
Stream<List<User>> get typingEventsStream =>
|
||||
_typingEventsController.stream.distinct(const ListEquality().equals);
|
||||
|
||||
final BehaviorSubject<List<User>> _typingEventsController =
|
||||
BehaviorSubject.seeded([]);
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ class StreamChatClient {
|
||||
/// This notifies the connection status of the websocket connection.
|
||||
/// Listen to this to get notified when the websocket tries to reconnect.
|
||||
Stream<ConnectionStatus> get wsConnectionStatusStream =>
|
||||
_wsConnectionStatusController.stream;
|
||||
_wsConnectionStatusController.stream.distinct();
|
||||
|
||||
/// The current user token
|
||||
String? token;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:stream_chat/src/models/user.dart';
|
||||
|
||||
@@ -6,7 +7,7 @@ part 'member.g.dart';
|
||||
/// The class that contains the information about the user membership
|
||||
/// in a channel
|
||||
@JsonSerializable()
|
||||
class Member {
|
||||
class Member extends Equatable {
|
||||
/// Constructor used for json serialization
|
||||
Member({
|
||||
this.user,
|
||||
@@ -98,4 +99,19 @@ class Member {
|
||||
|
||||
/// Serialize to json
|
||||
Map<String, dynamic> toJson() => _$MemberToJson(this);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
user,
|
||||
inviteAcceptedAt,
|
||||
inviteRejectedAt,
|
||||
invited,
|
||||
role,
|
||||
userId,
|
||||
isModerator,
|
||||
banned,
|
||||
shadowBanned,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:stream_chat/src/models/serialization.dart';
|
||||
|
||||
@@ -5,7 +6,7 @@ part 'user.g.dart';
|
||||
|
||||
/// The class that defines the user model
|
||||
@JsonSerializable()
|
||||
class User {
|
||||
class User extends Equatable {
|
||||
/// Constructor used for json serialization
|
||||
User({
|
||||
required this.id,
|
||||
@@ -125,4 +126,17 @@ class User {
|
||||
banned: banned ?? this.banned,
|
||||
teams: teams ?? this.teams,
|
||||
);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
id,
|
||||
role,
|
||||
teams,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
lastActive,
|
||||
online,
|
||||
banned,
|
||||
extraData,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ analyzer:
|
||||
- extension-methods
|
||||
exclude:
|
||||
- lib/**/*.g.dart
|
||||
- example/**
|
||||
# - example/**
|
||||
- lib/src/emoji
|
||||
- lib/**/*.freezed.dart
|
||||
- test/**
|
||||
# - test/**
|
||||
|
||||
linter:
|
||||
rules:
|
||||
|
||||
@@ -27,7 +27,6 @@ class ChannelInfo extends StatelessWidget {
|
||||
final client = StreamChat.of(context).client;
|
||||
return StreamBuilder<List<Member>>(
|
||||
stream: channel.state?.membersStream,
|
||||
initialData: channel.state?.members,
|
||||
builder: (context, snapshot) => ConnectionStatusBuilder(
|
||||
statusBuilder: (context, status) {
|
||||
switch (status) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
|
||||
@@ -39,7 +40,6 @@ class ConnectionStatusBuilder extends StatelessWidget {
|
||||
final stream = connectionStatusStream ??
|
||||
StreamChat.of(context).client.wsConnectionStatusStream;
|
||||
return StreamBuilder<ConnectionStatus>(
|
||||
initialData: initialStatus,
|
||||
stream: stream,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
|
||||
@@ -690,7 +690,7 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
? streamChannel.queryTopMessages
|
||||
: streamChannel.queryBottomMessages;
|
||||
return StreamBuilder<bool>(
|
||||
key: const Key('LOADING-INDICATOR'),
|
||||
key: Key('LOADING-INDICATOR $direction'),
|
||||
stream: stream,
|
||||
initialData: false,
|
||||
builder: (context, snapshot) {
|
||||
@@ -789,7 +789,9 @@ class _MessageListViewState extends State<MessageListView> {
|
||||
}
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() => _showScrollToBottom = !isVisible);
|
||||
if (_showScrollToBottom == isVisible) {
|
||||
setState(() => _showScrollToBottom = !isVisible);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: messageWidget,
|
||||
|
||||
@@ -33,8 +33,15 @@ class TypingIndicator extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final channelState =
|
||||
channel?.state ?? StreamChannel.of(context).channel.state!;
|
||||
|
||||
final altWidget = Align(
|
||||
key: const Key('alternative'),
|
||||
alignment: alignment,
|
||||
child: Container(
|
||||
child: alternativeWidget ?? const Offstage(),
|
||||
),
|
||||
);
|
||||
return StreamBuilder<List<User>>(
|
||||
initialData: channelState.typingEvents,
|
||||
stream: channelState.typingEventsStream,
|
||||
builder: (context, snapshot) => AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
@@ -62,13 +69,7 @@ class TypingIndicator extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
)
|
||||
: Align(
|
||||
key: const Key('alternative'),
|
||||
alignment: alignment,
|
||||
child: Container(
|
||||
child: alternativeWidget ?? const Offstage(),
|
||||
),
|
||||
),
|
||||
: altWidget,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -135,10 +135,12 @@ class MessageListCoreState extends State<MessageListCore> {
|
||||
}
|
||||
|
||||
return StreamBuilder<List<Message>?>(
|
||||
stream: messagesStream?.map((messages) =>
|
||||
messages?.where(widget.messageFilter ?? defaultFilter).toList(
|
||||
growable: false,
|
||||
)),
|
||||
stream: messagesStream?.map(
|
||||
(messages) =>
|
||||
messages?.where(widget.messageFilter ?? defaultFilter).toList(
|
||||
growable: false,
|
||||
),
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
return widget.errorWidgetBuilder(context, snapshot.error!);
|
||||
|
||||
Reference in New Issue
Block a user