fix floatingDate, messageWidgetBuilder index
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
@@ -396,6 +396,12 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
|
|
||||||
_messageListLength = newMessagesListLength;
|
_messageListLength = newMessagesListLength;
|
||||||
|
|
||||||
|
final itemCount = messages.length + // total messages
|
||||||
|
2 + // top + bottom loading indicator
|
||||||
|
2 + // header + footer
|
||||||
|
1 // parent message
|
||||||
|
;
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
@@ -416,12 +422,6 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
final itemCount = messages.length + // total messages
|
|
||||||
2 + // top + bottom loading indicator
|
|
||||||
2 + // header + footer
|
|
||||||
1 // parent message
|
|
||||||
;
|
|
||||||
|
|
||||||
return InfoTile(
|
return InfoTile(
|
||||||
showMessage: widget.showConnectionStateTile && showStatus,
|
showMessage: widget.showConnectionStateTile && showStatus,
|
||||||
tileAnchor: Alignment.topCenter,
|
tileAnchor: Alignment.topCenter,
|
||||||
@@ -470,15 +470,15 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
// ParentMessage -> 7 (count-1)
|
// ParentMessage -> 7 (count-1)
|
||||||
// Separator(ThreadSeparator) -> 6 (count-2)
|
// Separator(ThreadSeparator) -> 6 (count-2)
|
||||||
// Header -> 6 (count-2)
|
// Header -> 6 (count-2)
|
||||||
// Separator(Header -> 8??52) -> 5 (count-3)
|
// Separator(Header -> 8??T -> 0||52) -> 5 (count-3)
|
||||||
// TopLoader -> 5 (count-3)
|
// TopLoader -> 5 (count-3)
|
||||||
// Separator(2||8) -> 4 (count-4)
|
// Separator(0) -> 4 (count-4)
|
||||||
// Message -> 4 (count-4)
|
// Message -> 4 (count-4)
|
||||||
// Separator(2||8) -> 3 (count-5)
|
// Separator(2||8) -> 3 (count-5)
|
||||||
// Message -> 3 (count-5)
|
// Message -> 3 (count-5)
|
||||||
// Separator(2||8) -> 2 (count-6)
|
// Separator(2||8) -> 2 (count-6)
|
||||||
// Message -> 2 (count-6)
|
// Message -> 2 (count-6)
|
||||||
// Separator(2||8) -> 1 (count-7)
|
// Separator(0) -> 1 (count-7)
|
||||||
// BottomLoader -> 1 (count-7)
|
// BottomLoader -> 1 (count-7)
|
||||||
// Separator(Footer -> 8??30) -> 0 (count-8)
|
// Separator(Footer -> 8??30) -> 0 (count-8)
|
||||||
// Footer -> 0 (count-8)
|
// Footer -> 0 (count-8)
|
||||||
@@ -492,6 +492,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
}
|
}
|
||||||
if (i == itemCount - 3) {
|
if (i == itemCount - 3) {
|
||||||
if (widget.headerBuilder == null) {
|
if (widget.headerBuilder == null) {
|
||||||
|
if (_isThreadConversation) return const Offstage();
|
||||||
return const SizedBox(height: 52);
|
return const SizedBox(height: 52);
|
||||||
}
|
}
|
||||||
return const SizedBox(height: 8);
|
return const SizedBox(height: 8);
|
||||||
@@ -505,8 +506,8 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
|
|
||||||
if (i == 1 || i == itemCount - 4) return const Offstage();
|
if (i == 1 || i == itemCount - 4) return const Offstage();
|
||||||
|
|
||||||
final message = messages[i - 2];
|
final message = messages[i - 1];
|
||||||
final nextMessage = messages[i - 1];
|
final nextMessage = messages[i - 2];
|
||||||
if (!Jiffy(message.createdAt.toLocal()).isSame(
|
if (!Jiffy(message.createdAt.toLocal()).isSame(
|
||||||
nextMessage.createdAt.toLocal(),
|
nextMessage.createdAt.toLocal(),
|
||||||
Units.DAY,
|
Units.DAY,
|
||||||
@@ -575,8 +576,9 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
const Offstage();
|
const Offstage();
|
||||||
}
|
}
|
||||||
|
|
||||||
final topMessageIndex = itemCount - 4;
|
final topMessageIndex = itemCount -
|
||||||
const bottomMessageIndex = 2;
|
4; // 7 -> parent // 6 -> header // 5 -> loader
|
||||||
|
const bottomMessageIndex = 2; // 1 -> loader // 0 -> footer
|
||||||
|
|
||||||
final message = messages[i - 2];
|
final message = messages[i - 2];
|
||||||
Widget messageWidget;
|
Widget messageWidget;
|
||||||
@@ -587,6 +589,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
message,
|
message,
|
||||||
messages,
|
messages,
|
||||||
streamChannel,
|
streamChannel,
|
||||||
|
i,
|
||||||
);
|
);
|
||||||
} else if (i == bottomMessageIndex) {
|
} else if (i == bottomMessageIndex) {
|
||||||
messageWidget = _buildBottomMessage(
|
messageWidget = _buildBottomMessage(
|
||||||
@@ -594,6 +597,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
message,
|
message,
|
||||||
messages,
|
messages,
|
||||||
streamChannel!,
|
streamChannel!,
|
||||||
|
i,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (widget.messageBuilder != null) {
|
if (widget.messageBuilder != null) {
|
||||||
@@ -621,7 +625,8 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (widget.showScrollToBottom) _buildScrollToBottom(),
|
if (widget.showScrollToBottom) _buildScrollToBottom(),
|
||||||
if (widget.showFloatingDateDivider) _buildFloatingDateDivider(),
|
if (widget.showFloatingDateDivider)
|
||||||
|
_buildFloatingDateDivider(itemCount),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -647,42 +652,34 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Positioned _buildFloatingDateDivider() => Positioned(
|
Positioned _buildFloatingDateDivider(int itemCount) => Positioned(
|
||||||
top: 20,
|
top: 20,
|
||||||
child: BetterStreamBuilder<Iterable<ItemPosition>>(
|
child: BetterStreamBuilder<Iterable<ItemPosition>>(
|
||||||
initialData: _itemPositionListener.itemPositions.value,
|
initialData: _itemPositionListener.itemPositions.value,
|
||||||
stream: _itemPositionStream,
|
stream: _itemPositionStream,
|
||||||
comparator: (a, b) {
|
comparator: (a, b) {
|
||||||
if (a == null) {
|
if (a == null || b == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final aTop = _getTopElement(a)?.index;
|
final aTop = _getTopElementIndex(a);
|
||||||
final bTop = _getTopElement(b)?.index;
|
final bTop = _getTopElementIndex(b);
|
||||||
return aTop == bTop;
|
return aTop == bTop;
|
||||||
},
|
},
|
||||||
builder: (context, values) {
|
builder: (context, values) {
|
||||||
final items = _itemPositionListener.itemPositions.value;
|
if (values.isEmpty || messages.isEmpty) {
|
||||||
if (items.isEmpty || messages.isEmpty) {
|
return const Offstage();
|
||||||
return const SizedBox();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var index = _getTopElement(values)?.index;
|
final index = _getTopElementIndex(values);
|
||||||
|
|
||||||
if (index == null || index > messages.length) {
|
if (index == null || index <= 2 || index >= itemCount - 3) {
|
||||||
return const SizedBox();
|
return const Offstage();
|
||||||
}
|
|
||||||
|
|
||||||
if (index == messages.length) {
|
|
||||||
index = max(index - 1, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final message = messages[index - 2];
|
||||||
return widget.dateDividerBuilder != null
|
return widget.dateDividerBuilder != null
|
||||||
? widget.dateDividerBuilder!(
|
? widget.dateDividerBuilder!(message.createdAt.toLocal())
|
||||||
messages[index].createdAt.toLocal(),
|
: DateDivider(dateTime: message.createdAt.toLocal());
|
||||||
)
|
|
||||||
: DateDivider(
|
|
||||||
dateTime: messages[index].createdAt.toLocal(),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -691,16 +688,13 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
StreamChannelState? channel, QueryDirection direction) =>
|
StreamChannelState? channel, QueryDirection direction) =>
|
||||||
_messageListController.paginateData!(direction: direction);
|
_messageListController.paginateData!(direction: direction);
|
||||||
|
|
||||||
ItemPosition? _getTopElement(Iterable<ItemPosition> values) {
|
int? _getTopElementIndex(Iterable<ItemPosition> values) {
|
||||||
final inView =
|
final inView = values.where((position) => position.itemLeadingEdge < 1);
|
||||||
values.where((ItemPosition position) => position.itemLeadingEdge < 0.9);
|
if (inView.isEmpty) return null;
|
||||||
|
return inView
|
||||||
if (inView.isEmpty) {
|
.reduce((max, position) =>
|
||||||
return null;
|
position.itemLeadingEdge > max.itemLeadingEdge ? position : max)
|
||||||
}
|
.index;
|
||||||
|
|
||||||
return inView.reduce((ItemPosition max, ItemPosition position) =>
|
|
||||||
position.itemLeadingEdge > max.itemLeadingEdge ? position : max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildScrollToBottom() => StreamBuilder<Tuple2<bool, int>>(
|
Widget _buildScrollToBottom() => StreamBuilder<Tuple2<bool, int>>(
|
||||||
@@ -796,6 +790,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
Message message,
|
Message message,
|
||||||
List<Message> messages,
|
List<Message> messages,
|
||||||
StreamChannelState? streamChannel,
|
StreamChannelState? streamChannel,
|
||||||
|
int index,
|
||||||
) {
|
) {
|
||||||
Widget messageWidget;
|
Widget messageWidget;
|
||||||
if (widget.messageBuilder != null) {
|
if (widget.messageBuilder != null) {
|
||||||
@@ -813,7 +808,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
messageWidget = buildMessage(message, messages, messages.length - 1);
|
messageWidget = buildMessage(message, messages, index);
|
||||||
}
|
}
|
||||||
return messageWidget;
|
return messageWidget;
|
||||||
}
|
}
|
||||||
@@ -823,6 +818,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
Message message,
|
Message message,
|
||||||
List<Message> messages,
|
List<Message> messages,
|
||||||
StreamChannelState streamChannel,
|
StreamChannelState streamChannel,
|
||||||
|
int index,
|
||||||
) {
|
) {
|
||||||
Widget messageWidget;
|
Widget messageWidget;
|
||||||
if (widget.messageBuilder != null) {
|
if (widget.messageBuilder != null) {
|
||||||
@@ -840,7 +836,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
messageWidget = buildMessage(message, messages, 0);
|
messageWidget = buildMessage(message, messages, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return VisibilityDetector(
|
return VisibilityDetector(
|
||||||
@@ -952,7 +948,7 @@ class _MessageListViewState extends State<MessageListView> {
|
|||||||
|
|
||||||
final userId = StreamChat.of(context).user!.id;
|
final userId = StreamChat.of(context).user!.id;
|
||||||
final isMyMessage = message.user!.id == userId;
|
final isMyMessage = message.user!.id == userId;
|
||||||
final nextMessage = index - 2 >= 0 ? messages[index - 2] : null;
|
final nextMessage = index - 3 >= 0 ? messages[index - 3] : null;
|
||||||
final isNextUserSame =
|
final isNextUserSame =
|
||||||
nextMessage != null && message.user!.id == nextMessage.user!.id;
|
nextMessage != null && message.user!.id == nextMessage.user!.id;
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class BetterStreamBuilder<T> extends StatefulWidget {
|
|||||||
final T initialData;
|
final T initialData;
|
||||||
|
|
||||||
/// Comparator used to check if the new data is different than the last one
|
/// Comparator used to check if the new data is different than the last one
|
||||||
final bool Function(T?, T)? comparator;
|
final bool Function(T?, T?)? comparator;
|
||||||
|
|
||||||
/// Builder that builds based on the new snapshot
|
/// Builder that builds based on the new snapshot
|
||||||
final Widget Function(BuildContext context, T data) builder;
|
final Widget Function(BuildContext context, T data) builder;
|
||||||
@@ -96,9 +96,8 @@ class _BetterStreamBuilderState<T> extends State<BetterStreamBuilder<T>> {
|
|||||||
|
|
||||||
void _onEvent(T event) {
|
void _onEvent(T event) {
|
||||||
_lastError = null;
|
_lastError = null;
|
||||||
final isEqual = widget.comparator != null
|
final isEqual =
|
||||||
? widget.comparator!(_lastEvent, event)
|
widget.comparator?.call(_lastEvent, event) ?? event == _lastEvent;
|
||||||
: event == _lastEvent;
|
|
||||||
if (!isEqual) {
|
if (!isEqual) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|||||||
Reference in New Issue
Block a user