feat: setting product infinity scroll

This commit is contained in:
efrilm
2025-08-05 20:00:58 +07:00
parent 7ca96d19db
commit f0ff078e0e
5 changed files with 551 additions and 199 deletions
@@ -19,6 +19,7 @@ class ProductPage extends StatefulWidget {
}
class _ProductPageState extends State<ProductPage> {
ScrollController scrollController = ScrollController();
@override
void initState() {
context.read<GetProductsBloc>().add(const GetProductsEvent.fetch());
@@ -64,48 +65,66 @@ class _ProductPageState extends State<ProductPage> {
Expanded(
child: BlocBuilder<GetProductsBloc, GetProductsState>(
builder: (context, state) {
return state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, success: (products) {
return GridView.builder(
padding: EdgeInsets.all(16),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
mainAxisSpacing: 30,
crossAxisSpacing: 30,
childAspectRatio: 0.85,
),
itemCount: products.length,
itemBuilder: (BuildContext context, int index) {
final item = products[index];
return MenuProductItem(
data: item,
onTapEdit: () {
showDialog(
context: context,
builder: (context) => MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => UpdateProductBloc(
ProductRemoteDatasource()),
),
BlocProvider.value(
value: context.read<SyncProductBloc>(),
),
BlocProvider.value(
value: context.read<GetProductsBloc>(),
),
],
child: FormProductDialog(product: item),
),
);
},
);
},
);
});
return NotificationListener<ScrollNotification>(
onNotification: (notification) {
return state.maybeWhen(
orElse: () => false,
success: (products, hasReachedMax, currentPage, _) {
if (notification is ScrollEndNotification &&
scrollController.position.extentAfter == 0) {
context
.read<GetProductsBloc>()
.add(const GetProductsEvent.loadMore());
return true;
}
return true;
});
},
child: state.maybeWhen(orElse: () {
return const Center(
child: CircularProgressIndicator(),
);
}, success: (products, hasReachedMax, currentPage, _) {
return GridView.builder(
padding: EdgeInsets.all(16),
controller: scrollController,
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
mainAxisSpacing: 30,
crossAxisSpacing: 30,
childAspectRatio: 0.85,
),
itemCount: products.length,
itemBuilder: (BuildContext context, int index) {
final item = products[index];
return MenuProductItem(
data: item,
onTapEdit: () {
showDialog(
context: context,
builder: (context) => MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => UpdateProductBloc(
ProductRemoteDatasource()),
),
BlocProvider.value(
value: context.read<SyncProductBloc>(),
),
BlocProvider.value(
value: context.read<GetProductsBloc>(),
),
],
child: FormProductDialog(product: item),
),
);
},
);
},
);
}),
);
},
),
),