mirror of
https://github.com/simon-ding/polaris.git
synced 2026-06-09 11:39:46 +08:00
infinite scroll
This commit is contained in:
@@ -29,9 +29,8 @@ final movieWatchlistDataProvider = FutureProvider.autoDispose((ref) async {
|
|||||||
return favList;
|
return favList;
|
||||||
});
|
});
|
||||||
|
|
||||||
var searchPageDataProvider =
|
var searchPageDataProvider = AsyncNotifierProvider.autoDispose
|
||||||
AsyncNotifierProvider.autoDispose.family<SearchPageData, List<SearchResult>, String>(
|
.family<SearchPageData, List<SearchResult>, String>(SearchPageData.new);
|
||||||
SearchPageData.new);
|
|
||||||
|
|
||||||
var movieTorrentsDataProvider = AsyncNotifierProvider.autoDispose
|
var movieTorrentsDataProvider = AsyncNotifierProvider.autoDispose
|
||||||
.family<MovieTorrentResource, List<TorrentResource>, String>(
|
.family<MovieTorrentResource, List<TorrentResource>, String>(
|
||||||
@@ -40,28 +39,41 @@ var movieTorrentsDataProvider = AsyncNotifierProvider.autoDispose
|
|||||||
class SearchPageData
|
class SearchPageData
|
||||||
extends AutoDisposeFamilyAsyncNotifier<List<SearchResult>, String> {
|
extends AutoDisposeFamilyAsyncNotifier<List<SearchResult>, String> {
|
||||||
List<SearchResult> list = List.empty(growable: true);
|
List<SearchResult> list = List.empty(growable: true);
|
||||||
|
String? q;
|
||||||
|
int page = 1;
|
||||||
@override
|
@override
|
||||||
FutureOr<List<SearchResult>> build(String arg) async {
|
FutureOr<List<SearchResult>> build(String arg) async {
|
||||||
|
q = arg;
|
||||||
if (isBlank(arg)) {
|
if (isBlank(arg)) {
|
||||||
return List.empty();
|
return List.empty();
|
||||||
}
|
}
|
||||||
list = List.empty(growable: true);
|
return query(arg, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FutureOr<List<SearchResult>> query(String q, int page) async {
|
||||||
final dio = await APIs.getDio();
|
final dio = await APIs.getDio();
|
||||||
var resp = await dio.get(APIs.searchUrl, queryParameters: {"query": arg});
|
var resp = await dio
|
||||||
|
.get(APIs.searchUrl, queryParameters: {"query": q, "page": page});
|
||||||
|
|
||||||
var rsp = ServerResponse.fromJson(resp.data as Map<String, dynamic>);
|
var rsp = ServerResponse.fromJson(resp.data as Map<String, dynamic>);
|
||||||
if (rsp.code != 0) {
|
if (rsp.code != 0) {
|
||||||
throw rsp.message;
|
throw rsp.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = rsp.data as Map<String, dynamic>;
|
var sp = SearchResponse.fromJson(rsp.data);
|
||||||
var results = data["results"] as List<dynamic>;
|
return sp.results ?? List.empty();
|
||||||
for (final r in results) {
|
}
|
||||||
var res = SearchResult.fromJson(r);
|
|
||||||
list.add(res);
|
FutureOr<void> queryNextPage() async {
|
||||||
}
|
//state = const AsyncLoading();
|
||||||
return list;
|
final newState = await AsyncValue.guard(
|
||||||
|
() async {
|
||||||
|
page++;
|
||||||
|
final awaiteddata = await query(q!, page);
|
||||||
|
return [...?state.value, ...awaiteddata];
|
||||||
|
},
|
||||||
|
);
|
||||||
|
state = newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> submit2Watchlist(
|
Future<void> submit2Watchlist(
|
||||||
@@ -92,6 +104,25 @@ class SearchPageData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SearchResponse {
|
||||||
|
int? page;
|
||||||
|
int? totalResults;
|
||||||
|
int? totalPage;
|
||||||
|
List<SearchResult>? results;
|
||||||
|
|
||||||
|
SearchResponse({this.page, this.totalResults, this.totalPage, this.results});
|
||||||
|
|
||||||
|
factory SearchResponse.fromJson(Map<String, dynamic> json) {
|
||||||
|
return SearchResponse(
|
||||||
|
page: json["page"],
|
||||||
|
totalPage: json["total_page"],
|
||||||
|
totalResults: json["total_results"],
|
||||||
|
results: (json["results"] as List)
|
||||||
|
.map((v) => SearchResult.fromJson(v))
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MediaDetail {
|
class MediaDetail {
|
||||||
int? id;
|
int? id;
|
||||||
int? tmdbId;
|
int? tmdbId;
|
||||||
|
|||||||
@@ -21,10 +21,9 @@ class SearchPage extends ConsumerStatefulWidget {
|
|||||||
class _SearchPageState extends ConsumerState<SearchPage> {
|
class _SearchPageState extends ConsumerState<SearchPage> {
|
||||||
List<dynamic> list = List.empty();
|
List<dynamic> list = List.empty();
|
||||||
|
|
||||||
Future<void>? _pendingFuture;
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final q = widget.query??"";
|
final q = widget.query ?? "";
|
||||||
var searchList = ref.watch(searchPageDataProvider(q));
|
var searchList = ref.watch(searchPageDataProvider(q));
|
||||||
|
|
||||||
List<Widget> res = searchList.when(
|
List<Widget> res = searchList.when(
|
||||||
@@ -96,18 +95,18 @@ class _SearchPageState extends ConsumerState<SearchPage> {
|
|||||||
error: (err, trace) => [Text("$err")],
|
error: (err, trace) => [Text("$err")],
|
||||||
loading: () => [const MyProgressIndicator()]);
|
loading: () => [const MyProgressIndicator()]);
|
||||||
|
|
||||||
var f = FutureBuilder(
|
var f = NotificationListener(
|
||||||
// We listen to the pending operation, to update the UI accordingly.
|
onNotification: (ScrollNotification scrollInfo) {
|
||||||
future: _pendingFuture,
|
if (scrollInfo is ScrollEndNotification &&
|
||||||
builder: (context, snapshot) {
|
scrollInfo.metrics.axisDirection == AxisDirection.down &&
|
||||||
if (snapshot.connectionState != ConnectionState.done &&
|
scrollInfo.metrics.pixels >= scrollInfo.metrics.maxScrollExtent) {
|
||||||
snapshot.connectionState != ConnectionState.none) {
|
ref.read(searchPageDataProvider(q).notifier).queryNextPage();
|
||||||
return const MyProgressIndicator();
|
|
||||||
}
|
}
|
||||||
return ListView(
|
return true;
|
||||||
children: res,
|
},
|
||||||
);
|
child: ListView(
|
||||||
});
|
children: res,
|
||||||
|
));
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
@@ -194,7 +193,8 @@ class _SearchPageState extends ConsumerState<SearchPage> {
|
|||||||
child: const Text('确定'),
|
child: const Text('确定'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
ref
|
ref
|
||||||
.read(searchPageDataProvider(widget.query??"").notifier)
|
.read(searchPageDataProvider(widget.query ?? "")
|
||||||
|
.notifier)
|
||||||
.submit2Watchlist(item.id!, storageSelected,
|
.submit2Watchlist(item.id!, storageSelected,
|
||||||
resSelected, item.mediaType!);
|
resSelected, item.mediaType!);
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
|
|||||||
Reference in New Issue
Block a user