@@ -1,8 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/attachment.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/gallery_attachment.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/thumbnail/media_attachment_thumbnail.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/url_attachment.dart';
|
||||
import 'package:stream_chat_flutter/src/stream_chat.dart';
|
||||
import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart';
|
||||
import 'package:stream_chat_flutter/src/utils/utils.dart';
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import 'package:contextmenu/contextmenu.dart';
|
||||
import 'package:dart_vlc/dart_vlc.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart';
|
||||
import 'package:stream_chat_flutter/src/attachment/thumbnail/media_attachment_thumbnail.dart';
|
||||
import 'package:stream_chat_flutter/src/context_menu_items/download_menu_item.dart';
|
||||
import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart';
|
||||
|
||||
@@ -38,61 +38,39 @@ class FloatingDateDivider extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
top: 20,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: BetterStreamBuilder<Iterable<ItemPosition>>(
|
||||
initialData: itemPositionListener.itemPositions.value,
|
||||
stream: valueListenableToStreamAdapter(
|
||||
itemPositionListener.itemPositions,
|
||||
),
|
||||
comparator: (a, b) {
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
final itemPositions = itemPositionListener.itemPositions;
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: itemPositions,
|
||||
builder: (context, positions, child) {
|
||||
if (positions.isEmpty || messages.isEmpty) {
|
||||
return const Offstage();
|
||||
}
|
||||
|
||||
int? index;
|
||||
if (reverse) {
|
||||
index = getTopElementIndex(positions);
|
||||
} else {
|
||||
index = getBottomElementIndex(positions);
|
||||
}
|
||||
|
||||
if ((index == null) ||
|
||||
(!isThreadConversation && index == itemCount - 2) ||
|
||||
(isThreadConversation && index == itemCount - 1)) {
|
||||
return const Offstage();
|
||||
}
|
||||
|
||||
if (index <= 2 || index >= itemCount - 3) {
|
||||
if (reverse) {
|
||||
final aTop = getTopElementIndex(a);
|
||||
final bTop = getTopElementIndex(b);
|
||||
return aTop == bTop;
|
||||
index = itemCount - 4;
|
||||
} else {
|
||||
final aBottom = getBottomElementIndex(a);
|
||||
final bBottom = getBottomElementIndex(b);
|
||||
return aBottom == bBottom;
|
||||
}
|
||||
},
|
||||
builder: (context, values) {
|
||||
if (values.isEmpty || messages.isEmpty) {
|
||||
return const Offstage();
|
||||
index = 2;
|
||||
}
|
||||
}
|
||||
|
||||
int? index;
|
||||
if (reverse) {
|
||||
index = getTopElementIndex(values);
|
||||
} else {
|
||||
index = getBottomElementIndex(values);
|
||||
}
|
||||
|
||||
if ((index == null) ||
|
||||
(!isThreadConversation && index == itemCount - 2) ||
|
||||
(isThreadConversation && index == itemCount - 1)) {
|
||||
return const Offstage();
|
||||
}
|
||||
|
||||
if (index <= 2 || index >= itemCount - 3) {
|
||||
if (reverse) {
|
||||
index = itemCount - 4;
|
||||
} else {
|
||||
index = 2;
|
||||
}
|
||||
}
|
||||
|
||||
final message = messages[index - 2];
|
||||
return dateDividerBuilder != null
|
||||
? dateDividerBuilder!(message.createdAt.toLocal())
|
||||
: StreamDateDivider(dateTime: message.createdAt.toLocal());
|
||||
},
|
||||
),
|
||||
final message = messages[index - 2];
|
||||
return dateDividerBuilder?.call(message.createdAt.toLocal()) ??
|
||||
StreamDateDivider(dateTime: message.createdAt.toLocal());
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -810,13 +810,18 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
||||
),
|
||||
),
|
||||
if (widget.showFloatingDateDivider)
|
||||
FloatingDateDivider(
|
||||
itemCount: itemCount,
|
||||
reverse: widget.reverse,
|
||||
itemPositionListener: _itemPositionListener,
|
||||
messages: messages,
|
||||
dateDividerBuilder: widget.dateDividerBuilder,
|
||||
isThreadConversation: _isThreadConversation,
|
||||
Positioned(
|
||||
top: 20,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: FloatingDateDivider(
|
||||
itemCount: itemCount,
|
||||
reverse: widget.reverse,
|
||||
itemPositionListener: _itemPositionListener,
|
||||
messages: messages,
|
||||
dateDividerBuilder: widget.dateDividerBuilder,
|
||||
isThreadConversation: _isThreadConversation,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:stream_chat_flutter/scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||
|
||||
@@ -74,29 +71,3 @@ int? getBottomElementIndex(Iterable<ItemPosition> values) {
|
||||
bool isInitialMessage(String id, StreamChannelState? channelState) {
|
||||
return channelState!.initialMessageId == id;
|
||||
}
|
||||
|
||||
/// Converts a [ValueListenable] to a [Stream].
|
||||
Stream<T> valueListenableToStreamAdapter<T>(ValueListenable<T> listenable) {
|
||||
late StreamController<T> _controller;
|
||||
|
||||
void listener() {
|
||||
_controller.add(listenable.value);
|
||||
}
|
||||
|
||||
void start() {
|
||||
listenable.addListener(listener);
|
||||
}
|
||||
|
||||
void end() {
|
||||
listenable.removeListener(listener);
|
||||
}
|
||||
|
||||
_controller = StreamController<T>(
|
||||
onListen: start,
|
||||
onPause: end,
|
||||
onResume: start,
|
||||
onCancel: end,
|
||||
);
|
||||
|
||||
return _controller.stream;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user