@@ -1,8 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:stream_chat_flutter/src/attachment/attachment.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/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/stream_chat.dart';
|
||||||
import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart';
|
import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart';
|
||||||
import 'package:stream_chat_flutter/src/utils/utils.dart';
|
import 'package:stream_chat_flutter/src/utils/utils.dart';
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import 'package:contextmenu/contextmenu.dart';
|
import 'package:contextmenu/contextmenu.dart';
|
||||||
import 'package:dart_vlc/dart_vlc.dart';
|
import 'package:dart_vlc/dart_vlc.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:photo_view/photo_view.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/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/context_menu_items/download_menu_item.dart';
|
||||||
import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart';
|
import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart';
|
||||||
|
|||||||
@@ -38,61 +38,39 @@ class FloatingDateDivider extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Positioned(
|
final itemPositions = itemPositionListener.itemPositions;
|
||||||
top: 20,
|
return ValueListenableBuilder(
|
||||||
left: 0,
|
valueListenable: itemPositions,
|
||||||
right: 0,
|
builder: (context, positions, child) {
|
||||||
child: BetterStreamBuilder<Iterable<ItemPosition>>(
|
if (positions.isEmpty || messages.isEmpty) {
|
||||||
initialData: itemPositionListener.itemPositions.value,
|
return const Offstage();
|
||||||
stream: valueListenableToStreamAdapter(
|
}
|
||||||
itemPositionListener.itemPositions,
|
|
||||||
),
|
int? index;
|
||||||
comparator: (a, b) {
|
if (reverse) {
|
||||||
if (a == null || b == null) {
|
index = getTopElementIndex(positions);
|
||||||
return false;
|
} 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) {
|
if (reverse) {
|
||||||
final aTop = getTopElementIndex(a);
|
index = itemCount - 4;
|
||||||
final bTop = getTopElementIndex(b);
|
|
||||||
return aTop == bTop;
|
|
||||||
} else {
|
} else {
|
||||||
final aBottom = getBottomElementIndex(a);
|
index = 2;
|
||||||
final bBottom = getBottomElementIndex(b);
|
|
||||||
return aBottom == bBottom;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
builder: (context, values) {
|
|
||||||
if (values.isEmpty || messages.isEmpty) {
|
|
||||||
return const Offstage();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int? index;
|
final message = messages[index - 2];
|
||||||
if (reverse) {
|
return dateDividerBuilder?.call(message.createdAt.toLocal()) ??
|
||||||
index = getTopElementIndex(values);
|
StreamDateDivider(dateTime: message.createdAt.toLocal());
|
||||||
} 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());
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -810,13 +810,18 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.showFloatingDateDivider)
|
if (widget.showFloatingDateDivider)
|
||||||
FloatingDateDivider(
|
Positioned(
|
||||||
itemCount: itemCount,
|
top: 20,
|
||||||
reverse: widget.reverse,
|
left: 0,
|
||||||
itemPositionListener: _itemPositionListener,
|
right: 0,
|
||||||
messages: messages,
|
child: FloatingDateDivider(
|
||||||
dateDividerBuilder: widget.dateDividerBuilder,
|
itemCount: itemCount,
|
||||||
isThreadConversation: _isThreadConversation,
|
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: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/scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.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) {
|
bool isInitialMessage(String id, StreamChannelState? channelState) {
|
||||||
return channelState!.initialMessageId == id;
|
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