Queue List widget initial implementation

This commit is contained in:
gianlucaparadise 2022-02-11 06:25:15 +01:00
parent 7937df603a
commit 11c94186e7
2 changed files with 130 additions and 0 deletions

View file

@ -0,0 +1,87 @@
import 'package:flutter/widgets.dart';
extension MyExtendedList<T> on List<T> {
T? lastOrNull() {
return this.isNotEmpty ? this.last : null;
}
}
typedef ItemWidgetBuilder<Item> = Widget Function(Item item);
/// When this return null, the pagination stops
typedef FutureItemsCallback<Item> = Future<List<Item>> Function(
Item? lastLoadedItem);
typedef ItemCallback<Item> = void Function(Item item);
class MyPaginatedList<Item> extends StatefulWidget {
final ItemWidgetBuilder<Item> widgetBuilder;
final FutureItemsCallback<Item> loadMore;
const MyPaginatedList({
Key? key,
required this.widgetBuilder,
required this.loadMore,
}) : super(key: key);
@override
_MyPaginatedListState createState() => _MyPaginatedListState();
}
class _MyPaginatedListState<Item> extends State<MyPaginatedList<Item>> {
List<Item> 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]);
}
});
}
}

View file

@ -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<MediaQueueItem>? widgetBuilder;
const QueueList({
Key? key,
required this.flutterCastFramework,
this.widgetBuilder,
}) : super(key: key);
@override
_QueueListState createState() => _QueueListState();
}
class _QueueListState extends State<QueueList> {
Widget widgetBuilder(MediaQueueItem item) {
// TODO complete this method
return SizedBox.shrink();
}
Future<List<MediaQueueItem>> 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<MediaQueueItem>(
widgetBuilder: this.widget.widgetBuilder ?? widgetBuilder,
loadMore: loadMore,
);
}
}