271 lines
9.4 KiB
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,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|