didvan-app/lib/views/home/media/widgets/banner_grid_view.dart

271 lines
9.4 KiB
Dart

import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/views/home/infography/infography_screen_state.dart';
import 'package:didvan/views/home/main/widgets/infography_item.dart';
import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
import 'package:didvan/views/widgets/shimmer_placeholder.dart';
import 'package:didvan/views/widgets/didvan/card.dart';
import 'package:didvan/views/widgets/didvan/divider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
class BannerGridView extends StatefulWidget {
const BannerGridView({super.key});
@override
State<BannerGridView> createState() => _BannerGridViewState();
}
class _BannerGridViewState extends State<BannerGridView> {
int _visibleItemCount = 4;
final ScrollController _scrollController = ScrollController();
int pageNumber = 1;
@override
void initState() {
super.initState();
Future.microtask(() {
context.read<InfographyScreenState>().init();
});
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Consumer<InfographyScreenState>(
builder: (context, state, child) {
return StateHandler<InfographyScreenState>(
placeholder: Column(
children: [
_buildPlaceholder(),
const SizedBox(height: 8.0),
_buildPlaceholder(),
],
),
topPadding: 0,
onRetry: () => state.init(),
state: state,
builder: (context, state) {
final contents = state.contents;
final itemsToShow = _visibleItemCount > contents.length
? contents.length
: _visibleItemCount;
final hasMoreItems = itemsToShow < contents.length;
return Column(
children: [
_buildCategoryFilters(state),
const SizedBox(height: 16),
ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.all(8.0),
itemCount: itemsToShow,
separatorBuilder: (context, index) =>
const SizedBox(height: 8.0),
itemBuilder: (context, index) {
final item = contents[index];
return InfographyItem(
id: item.id,
onMarkChanged: (id, value, _) =>
state.changeMark(id, value),
image: item.image,
category: item.category,
createdAt: item.createdAt,
title: item.title,
tag: item.tags,
marked: item.marked,
liked: item.liked,
onLikedChanged: (id, value, _) =>
state.changeLiked(id, value),
likes: item.likes,
);
},
),
if (hasMoreItems)
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: GestureDetector(
onTap: () {
setState(() {
_visibleItemCount += 4;
});
},
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 50.0,
vertical: 12.0,
),
decoration: BoxDecoration(
color: const Color.fromARGB(255, 0, 126, 167),
borderRadius: BorderRadius.circular(15),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
'lib/assets/icons/element-plus.svg',
),
const SizedBox(width: 8),
const Text(
'بارگذاری بیشتر',
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
],
);
},
);
},
);
}
Widget _buildCategoryFilters(InfographyScreenState state) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: FilterChip(
label: const Padding(
padding: EdgeInsets.all(1.0),
child: Text('همه'),
),
selected: state.selectedCats.isEmpty,
onSelected: (selected) {
if (selected) {
state.selectedCats.clear();
state.getInfographyContent(page: 1);
setState(() {
_visibleItemCount = 4;
});
}
},
selectedColor: const Color.fromARGB(255, 200, 224, 244),
backgroundColor: state.selectedCats.isEmpty
? DesignConfig.isDark
? const Color.fromARGB(255, 30, 30, 30)
: const Color.fromARGB(255, 200, 224, 244)
: DesignConfig.isDark
? const Color.fromARGB(255, 61, 61, 61)
: const Color.fromARGB(255, 224, 224, 224),
labelStyle: TextStyle(
color: state.selectedCats.isEmpty
? const Color.fromARGB(255, 0, 115, 153)
: Theme.of(context).colorScheme.caption,
fontWeight: state.selectedCats.isEmpty
? FontWeight.bold
: FontWeight.normal,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
showCheckmark: false,
),
),
...state.categories.map((category) {
final isSelected = state.selectedCats.contains(category);
return Padding(
padding: const EdgeInsets.only(left: 8.0),
child: FilterChip(
label: Padding(
padding: const EdgeInsets.all(1.0),
child: Text(category.label),
),
selected: isSelected,
onSelected: (selected) {
if (selected) {
state.selectedCats.add(category);
} else {
state.selectedCats.remove(category);
}
state.getInfographyContent(page: 1);
setState(() {
_visibleItemCount = 4;
});
},
selectedColor: const Color.fromARGB(255, 200, 224, 244),
backgroundColor: isSelected
? DesignConfig.isDark
? const Color.fromARGB(255, 30, 30, 30)
: const Color.fromARGB(255, 200, 224, 244)
: DesignConfig.isDark
? const Color.fromARGB(255, 61, 61, 61)
: const Color.fromARGB(255, 224, 224, 224),
labelStyle: TextStyle(
color: isSelected
? const Color.fromARGB(255, 0, 115, 153)
: Theme.of(context).colorScheme.caption,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
showCheckmark: false,
),
);
}).toList(),
],
),
);
}
Widget _buildPlaceholder() {
return const DidvanCard(
padding: EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ShimmerPlaceholder(
height: 16,
width: 240,
),
],
),
SizedBox(height: 12),
ShimmerPlaceholder(height: 200, width: 400),
SizedBox(height: 12),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ShimmerPlaceholder(
height: 32,
width: 100,
),
],
),
DidvanDivider(
verticalPadding: 12,
),
ShimmerPlaceholder(
height: 16,
width: double.infinity,
),
],
),
);
}
}