import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:solian/models/pagination.dart'; import 'package:solian/models/post.dart'; import 'package:solian/utils/service_url.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:http/http.dart' as http; import 'package:solian/widgets/posts/item.dart'; import 'package:solian/widgets/wrapper.dart'; class ExploreScreen extends StatefulWidget { const ExploreScreen({super.key}); @override State createState() => _ExploreScreenState(); } class _ExploreScreenState extends State { final PagingController _pagingController = PagingController(firstPageKey: 0); final http.Client _client = http.Client(); Future fetchFeed(int pageKey) async { final offset = pageKey; const take = 5; var uri = getRequestUri('interactive', '/api/feed?take=$take&offset=$offset'); var res = await _client.get(uri); if (res.statusCode == 200) { final result = PaginationResult.fromJson(jsonDecode(utf8.decode(res.bodyBytes))); final items = result.data?.map((x) => Post.fromJson(x)).toList() ?? List.empty(); final isLastPage = (result.count - pageKey) < take; if (isLastPage || result.data == null) { _pagingController.appendLastPage(items); } else { final nextPageKey = pageKey + items.length; _pagingController.appendPage(items, nextPageKey); } } else { _pagingController.error = utf8.decode(res.bodyBytes); } } @override void initState() { super.initState(); _pagingController.addPageRequestListener((pageKey) => fetchFeed(pageKey)); } @override Widget build(BuildContext context) { return LayoutWrapper( title: AppLocalizations.of(context)!.explore, child: RefreshIndicator( onRefresh: () => Future.sync( () => _pagingController.refresh(), ), child: Center( child: Container( constraints: const BoxConstraints(maxWidth: 720), child: PagedListView.separated( pagingController: _pagingController, separatorBuilder: (context, index) => const Divider(thickness: 0.3), builderDelegate: PagedChildBuilderDelegate( itemBuilder: (context, item, index) => PostItem(item: item), ), ), ), ), ), ); } }