clean up approach to avoid polling
This commit is contained in:
parent
3461fc5012
commit
72321cc413
1 changed files with 34 additions and 17 deletions
|
|
@ -28,8 +28,6 @@ final class ChatScroll({
|
||||||
final anchorId = useState<String?>(null);
|
final anchorId = useState<String?>(null);
|
||||||
|
|
||||||
final anchorItemKey = useMemoized(GlobalKey.new, [anchorId.value]);
|
final anchorItemKey = useMemoized(GlobalKey.new, [anchorId.value]);
|
||||||
final anchorItemKeyRef = useRef(anchorItemKey);
|
|
||||||
anchorItemKeyRef.value = anchorItemKey;
|
|
||||||
|
|
||||||
final historyListController = useMemoized(ListController.new, [
|
final historyListController = useMemoized(ListController.new, [
|
||||||
anchorId.value,
|
anchorId.value,
|
||||||
|
|
@ -41,6 +39,7 @@ final class ChatScroll({
|
||||||
final centerKey = useMemoized(GlobalKey.new);
|
final centerKey = useMemoized(GlobalKey.new);
|
||||||
|
|
||||||
final pendingAnchorTarget = useState<String?>(null);
|
final pendingAnchorTarget = useState<String?>(null);
|
||||||
|
final anchorMountedCompleter = useRef<Completer<BuildContext>?>(null);
|
||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
if (anchorId.value == null) {
|
if (anchorId.value == null) {
|
||||||
|
|
@ -70,13 +69,35 @@ final class ChatScroll({
|
||||||
false;
|
false;
|
||||||
|
|
||||||
if (found || controllerData is AsyncError) {
|
if (found || controllerData is AsyncError) {
|
||||||
if (found) anchorId.value = target;
|
if (found) {
|
||||||
|
anchorId.value = target;
|
||||||
|
} else {
|
||||||
|
anchorMountedCompleter.value?.completeError(
|
||||||
|
StateError("Failed to load context for $target"),
|
||||||
|
);
|
||||||
|
anchorMountedCompleter.value = null;
|
||||||
|
}
|
||||||
pendingAnchorTarget.value = null;
|
pendingAnchorTarget.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}, [controllerData, pendingAnchorTarget.value]);
|
}, [controllerData, pendingAnchorTarget.value]);
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
final completer = anchorMountedCompleter.value;
|
||||||
|
if (completer == null) return null;
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
final context = anchorItemKey.currentContext;
|
||||||
|
if (context != null && context.mounted) {
|
||||||
|
anchorMountedCompleter.value?.complete(context);
|
||||||
|
anchorMountedCompleter.value = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}, [anchorId.value]);
|
||||||
|
|
||||||
final ({IList<Event> history, IList<Event> live}) split = useMemoized(() {
|
final ({IList<Event> history, IList<Event> live}) split = useMemoized(() {
|
||||||
final items = controllerData.value?.timeline;
|
final items = controllerData.value?.timeline;
|
||||||
final anchor = anchorId.value;
|
final anchor = anchorId.value;
|
||||||
|
|
@ -157,24 +178,20 @@ final class ChatScroll({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final completer = Completer<BuildContext>();
|
||||||
|
anchorMountedCompleter.value = completer;
|
||||||
pendingAnchorTarget.value = itemId;
|
pendingAnchorTarget.value = itemId;
|
||||||
setContextualEvent(itemId);
|
setContextualEvent(itemId);
|
||||||
|
|
||||||
for (var i = 0; i < 60; i++) {
|
final context = await completer.future;
|
||||||
if (anchorId.value == itemId) {
|
|
||||||
final context = anchorItemKeyRef.value.currentContext;
|
|
||||||
if (context != null && context.mounted) {
|
|
||||||
await Scrollable.ensureVisible(
|
|
||||||
context,
|
|
||||||
alignment: 0.5,
|
|
||||||
duration: const Duration(milliseconds: 700),
|
|
||||||
curve: Curves.easeInOut,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await Future.delayed(const Duration(milliseconds: 16));
|
if (context.mounted) {
|
||||||
|
await Scrollable.ensureVisible(
|
||||||
|
context,
|
||||||
|
alignment: 0.5,
|
||||||
|
duration: const Duration(milliseconds: 700),
|
||||||
|
curve: Curves.easeInOut,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue