diff --git a/lib/src/cast/widgets/queue_list/MyPaginatedList.dart b/lib/src/cast/widgets/queue_list/MyPaginatedList.dart new file mode 100644 index 0000000..67a4a33 --- /dev/null +++ b/lib/src/cast/widgets/queue_list/MyPaginatedList.dart @@ -0,0 +1,87 @@ +import 'package:flutter/widgets.dart'; + +extension MyExtendedList on List { + T? lastOrNull() { + return this.isNotEmpty ? this.last : null; + } +} + +typedef ItemWidgetBuilder = Widget Function(Item item); + +/// When this return null, the pagination stops +typedef FutureItemsCallback = Future> Function( + Item? lastLoadedItem); +typedef ItemCallback = void Function(Item item); + +class MyPaginatedList extends StatefulWidget { + final ItemWidgetBuilder widgetBuilder; + final FutureItemsCallback loadMore; + + const MyPaginatedList({ + Key? key, + required this.widgetBuilder, + required this.loadMore, + }) : super(key: key); + + @override + _MyPaginatedListState createState() => _MyPaginatedListState(); +} + +class _MyPaginatedListState extends State> { + List items = []; + bool shouldTryToLoadMore = true; + + @override + void initState() { + super.initState(); + waitOnItems(); // FIXME: this should be before initstate + } + + void waitOnItems() async { + try { + final items = await widget.loadMore(this.items.lastOrNull()); + this.shouldTryToLoadMore = items.isNotEmpty; + setState(() { + this.items.addAll(items); + }); + } catch (error) { + print(error); // FIXME: this should call a callback + } + } + + @override + Widget build(BuildContext context) { + if (items.isEmpty) { + return buildLoadingProgress(); + } else { + //TODO: show progress bar at the bottom if loading more + return buildList(); + } + } + + Widget buildLoadingProgress() { + return Center( + child: Text("Loading..."), + ); + } + + Widget buildList() { + return ListView.builder( + itemCount: shouldTryToLoadMore ? null : items.length, + itemBuilder: (context, index) { + if (shouldTryToLoadMore && index == items.length - 1) { + waitOnItems(); + return SizedBox.shrink(); + } else if (index >= items.length) { + return SizedBox.shrink(); + // } else if (widget.onItemSelected != null) { + // return InkWell( + // onTap: () => {widget.onItemSelected(items[index])}, + // child: widget.widgetBuilder(items[index]), + // ); + } else { + return widget.widgetBuilder(items[index]); + } + }); + } +} diff --git a/lib/src/cast/widgets/queue_list/QueueList.dart b/lib/src/cast/widgets/queue_list/QueueList.dart new file mode 100644 index 0000000..3e9400e --- /dev/null +++ b/lib/src/cast/widgets/queue_list/QueueList.dart @@ -0,0 +1,43 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_cast_framework/cast.dart'; +import 'package:flutter_cast_framework/src/cast/widgets/queue_list/MyPaginatedList.dart'; + +class QueueList extends StatefulWidget { + final FlutterCastFramework flutterCastFramework; + final ItemWidgetBuilder? widgetBuilder; + + const QueueList({ + Key? key, + required this.flutterCastFramework, + this.widgetBuilder, + }) : super(key: key); + + @override + _QueueListState createState() => _QueueListState(); +} + +class _QueueListState extends State { + Widget widgetBuilder(MediaQueueItem item) { + // TODO complete this method + return SizedBox.shrink(); + } + + Future> loadMore(MediaQueueItem? lastLoadedItem) async { + // TODO complete this method + if (lastLoadedItem == null) { + //first load request + return []; + } else { + //subsequent load request(s) + return []; + } + } + + @override + Widget build(BuildContext context) { + return MyPaginatedList( + widgetBuilder: this.widget.widgetBuilder ?? widgetBuilder, + loadMore: loadMore, + ); + } +}