fixup! refactor chatview to have two sliver lists
This commit is contained in:
parent
110caff170
commit
856072e0b0
2 changed files with 31 additions and 45 deletions
|
|
@ -11,9 +11,6 @@ final class ChatScroll<T>({
|
||||||
required final ListController historyListController,
|
required final ListController historyListController,
|
||||||
required final ListController liveListController,
|
required final ListController liveListController,
|
||||||
required final ScrollController scrollController,
|
required final ScrollController scrollController,
|
||||||
required final bool hasMore,
|
|
||||||
required final bool isLoadingOlder,
|
|
||||||
required final Future<void> Function() loadOlder,
|
|
||||||
required final Future<void> Function(String id) jumpToId,
|
required final Future<void> Function(String id) jumpToId,
|
||||||
}) {
|
}) {
|
||||||
static ChatScroll<T> use<T>({
|
static ChatScroll<T> use<T>({
|
||||||
|
|
@ -28,8 +25,6 @@ final class ChatScroll<T>({
|
||||||
final centerKey = useMemoized(GlobalKey.new);
|
final centerKey = useMemoized(GlobalKey.new);
|
||||||
|
|
||||||
final anchorId = useState<String?>(null);
|
final anchorId = useState<String?>(null);
|
||||||
final hasMore = useState(true);
|
|
||||||
final isLoadingOlder = useState(false);
|
|
||||||
|
|
||||||
final anchorIdValue = anchorId.value;
|
final anchorIdValue = anchorId.value;
|
||||||
|
|
||||||
|
|
@ -65,17 +60,40 @@ final class ChatScroll<T>({
|
||||||
}, [controllerData, anchorIdValue]);
|
}, [controllerData, anchorIdValue]);
|
||||||
|
|
||||||
Future<void> loadOlderItems() async {
|
Future<void> loadOlderItems() async {
|
||||||
if (!hasMore.value || isLoadingOlder.value) return;
|
if (controllerData.isLoading) return;
|
||||||
|
|
||||||
isLoadingOlder.value = true;
|
await loadOlder();
|
||||||
|
|
||||||
try {
|
|
||||||
hasMore.value = await loadOlder();
|
|
||||||
} finally {
|
|
||||||
isLoadingOlder.value = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
const loadThreshold = 500.0;
|
||||||
|
const bottomThreshold = 50.0;
|
||||||
|
|
||||||
|
void checkPosition() {
|
||||||
|
if (!scrollController.hasClients) return;
|
||||||
|
|
||||||
|
final position = scrollController.position;
|
||||||
|
|
||||||
|
if (position.extentAfter <= loadThreshold) {
|
||||||
|
loadOlderItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position.extentBefore <= bottomThreshold) {
|
||||||
|
onReachedBottom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollController.addListener(checkPosition);
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
checkPosition();
|
||||||
|
});
|
||||||
|
|
||||||
|
return () {
|
||||||
|
scrollController.removeListener(checkPosition);
|
||||||
|
};
|
||||||
|
}, [scrollController, controllerData, loadOlder, onReachedBottom]);
|
||||||
|
|
||||||
Future<void> jumpToId(String itemId) async {
|
Future<void> jumpToId(String itemId) async {
|
||||||
if (!scrollController.hasClients) return;
|
if (!scrollController.hasClients) return;
|
||||||
|
|
||||||
|
|
@ -108,35 +126,6 @@ final class ChatScroll<T>({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() {
|
|
||||||
const loadThreshold = 500.0;
|
|
||||||
const bottomThreshold = 50.0;
|
|
||||||
|
|
||||||
void checkPosition() {
|
|
||||||
if (!scrollController.hasClients) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final position = scrollController.position;
|
|
||||||
|
|
||||||
if (position.extentAfter <= loadThreshold) {
|
|
||||||
if (hasMore.value && !isLoadingOlder.value) {
|
|
||||||
loadOlderItems();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position.extentBefore <= bottomThreshold) {
|
|
||||||
onReachedBottom();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollController.addListener(checkPosition);
|
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => checkPosition());
|
|
||||||
|
|
||||||
return () => scrollController.removeListener(checkPosition);
|
|
||||||
}, [scrollController, onReachedBottom]);
|
|
||||||
|
|
||||||
return .new(
|
return .new(
|
||||||
historyItems: split.history,
|
historyItems: split.history,
|
||||||
liveItems: split.live,
|
liveItems: split.live,
|
||||||
|
|
@ -144,9 +133,6 @@ final class ChatScroll<T>({
|
||||||
historyListController: historyListController.value,
|
historyListController: historyListController.value,
|
||||||
liveListController: liveListController.value,
|
liveListController: liveListController.value,
|
||||||
scrollController: scrollController,
|
scrollController: scrollController,
|
||||||
hasMore: hasMore.value,
|
|
||||||
isLoadingOlder: isLoadingOlder.value,
|
|
||||||
loadOlder: loadOlderItems,
|
|
||||||
jumpToId: jumpToId,
|
jumpToId: jumpToId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ class const ChatTimeline({
|
||||||
itemCount: scroll.historyItems.length,
|
itemCount: scroll.historyItems.length,
|
||||||
itemBuilder: (_, index) => eventRow(
|
itemBuilder: (_, index) => eventRow(
|
||||||
scroll.historyItems[index],
|
scroll.historyItems[index],
|
||||||
scroll.historyItems.getOrNull(index),
|
scroll.historyItems.getOrNull(index + 1),
|
||||||
jumpToId: jumpToId,
|
jumpToId: jumpToId,
|
||||||
getEventOptions: getEventOptions,
|
getEventOptions: getEventOptions,
|
||||||
highlightedEvent: highlightedEvent,
|
highlightedEvent: highlightedEvent,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue