import 'package:flutter/material.dart'; import 'package:localization/localization.dart'; import 'package:loris/partials/thread.dart'; import '../../business_logic/timeline/timeline.dart' as tl; class Timeline extends StatefulWidget { const Timeline({Key? key}) : super(key: key); @override State createState() => _TimelineState(); } class _TimelineState extends State { String? id; final controller = ScrollController(); List children = []; bool loading = false; @override void initState() { super.initState(); fetchMore(); controller.addListener(() { if (controller.position.maxScrollExtent <= controller.offset && !loading) { fetchMore(); } }); } Future fetchMore() async { loading = true; final model = await tl.getTimelineFromServer(id); id = model.posts[model.posts.length - 1].id; setState(() { if (children.isNotEmpty) { children.removeAt(children.length - 1); } children.addAll([ Thread( model: model, ) ]); children.add( Row( mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton.icon( onPressed: () { fetchMore(); }, icon: const Icon(Icons.more_horiz), label: Text("load-more".i18n()), ) ], ), ); loading = false; }); } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return ListView.separated( physics: const AlwaysScrollableScrollPhysics(), controller: controller, itemBuilder: (context, index) { return children[index]; }, separatorBuilder: (context, index) { return const Divider( color: Colors.transparent, ); }, itemCount: children.length, padding: const EdgeInsets.fromLTRB(24, 0, 24, 64), addAutomaticKeepAlives: false, ); } }