statistics basic skeletun
This commit is contained in:
parent
dc7a26c644
commit
bba9e2d364
|
|
@ -1,8 +1,9 @@
|
||||||
class CategoryData {
|
class CategoryData {
|
||||||
final int id;
|
final int id;
|
||||||
final String label;
|
final String label;
|
||||||
|
String? asset;
|
||||||
|
|
||||||
const CategoryData({required this.id, required this.label});
|
CategoryData({required this.id, required this.label, this.asset});
|
||||||
|
|
||||||
factory CategoryData.fromJson(Map<String, dynamic> json) => CategoryData(
|
factory CategoryData.fromJson(Map<String, dynamic> json) => CategoryData(
|
||||||
id: json['id'],
|
id: json['id'],
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
class RadarCategory {
|
|
||||||
final int id;
|
|
||||||
final String title;
|
|
||||||
final String asset;
|
|
||||||
|
|
||||||
RadarCategory({required this.id, required this.title, required this.asset});
|
|
||||||
}
|
|
||||||
|
|
@ -24,6 +24,7 @@ import 'package:didvan/views/home/settings/direct_list/direct_list_state.dart';
|
||||||
import 'package:didvan/views/home/settings/general_settings/settings.dart';
|
import 'package:didvan/views/home/settings/general_settings/settings.dart';
|
||||||
import 'package:didvan/views/home/settings/general_settings/settings_state.dart';
|
import 'package:didvan/views/home/settings/general_settings/settings_state.dart';
|
||||||
import 'package:didvan/views/home/settings/profile/profile.dart';
|
import 'package:didvan/views/home/settings/profile/profile.dart';
|
||||||
|
import 'package:didvan/views/home/statistics/statistics_state.dart';
|
||||||
import 'package:didvan/views/home/studio/studio_details/studio_details.mobile.dart'
|
import 'package:didvan/views/home/studio/studio_details/studio_details.mobile.dart'
|
||||||
if (dart.library.io) 'package:didvan/views/home/studio/studio_details/studio_details.mobile.dart'
|
if (dart.library.io) 'package:didvan/views/home/studio/studio_details/studio_details.mobile.dart'
|
||||||
if (dart.library.html) 'package:didvan/views/home/studio/studio_details/studio_details.web.dart';
|
if (dart.library.html) 'package:didvan/views/home/studio/studio_details/studio_details.web.dart';
|
||||||
|
|
@ -64,6 +65,9 @@ class RouteGenerator {
|
||||||
ChangeNotifierProvider<StudioState>(
|
ChangeNotifierProvider<StudioState>(
|
||||||
create: (context) => StudioState(),
|
create: (context) => StudioState(),
|
||||||
),
|
),
|
||||||
|
ChangeNotifierProvider<StatisticsState>(
|
||||||
|
create: (context) => StatisticsState(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
child: const Home(),
|
child: const Home(),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
children: const [
|
children: const [
|
||||||
News(),
|
News(),
|
||||||
Statictics(),
|
Statistics(),
|
||||||
Radar(),
|
Radar(),
|
||||||
Studio(),
|
Studio(),
|
||||||
Settings(),
|
Settings(),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
import 'package:didvan/models/enums.dart';
|
|
||||||
import 'package:didvan/models/requests/news.dart';
|
import 'package:didvan/models/requests/news.dart';
|
||||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
|
|
@ -11,8 +10,7 @@ import 'package:didvan/views/home/widgets/logo_app_bar.dart';
|
||||||
import 'package:didvan/views/home/widgets/overview/news.dart';
|
import 'package:didvan/views/home/widgets/overview/news.dart';
|
||||||
import 'package:didvan/views/home/widgets/search_field.dart';
|
import 'package:didvan/views/home/widgets/search_field.dart';
|
||||||
import 'package:didvan/views/widgets/item_title.dart';
|
import 'package:didvan/views/widgets/item_title.dart';
|
||||||
import 'package:didvan/views/widgets/state_handlers/empty_result.dart';
|
import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
|
||||||
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
|
@ -34,57 +32,55 @@ class _NewsState extends State<News> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final state = context.watch<NewsState>();
|
return Consumer<NewsState>(
|
||||||
return CustomScrollView(
|
builder: (context, state, child) => StateHandler<NewsState>(
|
||||||
slivers: [
|
|
||||||
const SliverToBoxAdapter(child: LogoAppBar()),
|
|
||||||
if (state.appState != AppState.failed)
|
|
||||||
SliverPadding(
|
|
||||||
padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
|
||||||
sliver: SliverToBoxAdapter(
|
|
||||||
child: SearchField(
|
|
||||||
focusNode: _focusNode,
|
|
||||||
title: 'اخبار',
|
|
||||||
onChanged: _onChanged,
|
|
||||||
onFilterButtonPressed: _showFilterBottomSheet,
|
|
||||||
isFiltered: state.isFiltering,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SliverStateHandler<NewsState>(
|
|
||||||
onRetry: () => state.getNews(page: state.page),
|
onRetry: () => state.getNews(page: state.page),
|
||||||
state: state,
|
state: state,
|
||||||
builder: (context, state, index) {
|
builder: (context, state) => ListView.builder(
|
||||||
index += 2;
|
cacheExtent: 1000,
|
||||||
if (index % 15 == 0 && state.lastPage != state.page) {
|
itemBuilder: (context, index) {
|
||||||
state.getNews(page: state.page + 1);
|
if (index == 0) {
|
||||||
}
|
return const LogoAppBar();
|
||||||
index -= 2;
|
}
|
||||||
if (index >= state.news.length) {
|
if (index == 1) {
|
||||||
return NewsOverview.placeholder;
|
return Padding(
|
||||||
}
|
padding: const EdgeInsets.only(
|
||||||
final news = state.news[index];
|
left: 16,
|
||||||
return NewsOverview(
|
right: 16,
|
||||||
news: news,
|
bottom: 16,
|
||||||
onMarkChanged: state.onMarkChanged,
|
),
|
||||||
newsRequestArgs: NewsRequestArgs(
|
child: SearchField(
|
||||||
page: state.page,
|
focusNode: _focusNode,
|
||||||
endDate: state.endDate,
|
title: 'اخبار',
|
||||||
startDate: state.startDate,
|
onChanged: _onChanged,
|
||||||
search: state.search,
|
onFilterButtonPressed: _showFilterBottomSheet,
|
||||||
),
|
isFiltered: state.isFiltering,
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
enableEmptyState: state.news.isEmpty,
|
}
|
||||||
emptyState: EmptyResult(
|
index -= 2;
|
||||||
onNewSearch: () => _focusNode.requestFocus(),
|
index += 2;
|
||||||
),
|
if (index % 15 == 0 && state.lastPage != state.page) {
|
||||||
childCount:
|
state.getNews(page: state.page + 1);
|
||||||
state.news.length + (state.lastPage == state.page ? 0 : 3),
|
}
|
||||||
itemPadding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
index -= 2;
|
||||||
placeholder: NewsOverview.placeholder,
|
if (index >= state.news.length) {
|
||||||
),
|
return NewsOverview.placeholder;
|
||||||
],
|
}
|
||||||
|
final news = state.news[index];
|
||||||
|
return NewsOverview(
|
||||||
|
news: news,
|
||||||
|
onMarkChanged: state.onMarkChanged,
|
||||||
|
newsRequestArgs: NewsRequestArgs(
|
||||||
|
page: state.page,
|
||||||
|
endDate: state.endDate,
|
||||||
|
startDate: state.startDate,
|
||||||
|
search: state.search,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: state.news.length + 2,
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
// ignore_for_file: prefer_const_constructors
|
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/app_icons.dart';
|
import 'package:didvan/constants/app_icons.dart';
|
||||||
|
import 'package:didvan/models/category.dart';
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
import 'package:didvan/models/requests/radar.dart';
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||||
import 'package:didvan/views/home/radar/radar_state.dart';
|
import 'package:didvan/views/home/radar/radar_state.dart';
|
||||||
import 'package:didvan/views/home/radar/widgets/categories_gird.dart';
|
import 'package:didvan/views/home/widgets/categories_gird.dart';
|
||||||
import 'package:didvan/views/home/radar/widgets/categories_list.dart';
|
import 'package:didvan/views/home/widgets/categories_list.dart';
|
||||||
import 'package:didvan/views/home/widgets/date_picker_button.dart';
|
import 'package:didvan/views/home/widgets/date_picker_button.dart';
|
||||||
import 'package:didvan/views/home/widgets/logo_app_bar.dart';
|
import 'package:didvan/views/home/widgets/logo_app_bar.dart';
|
||||||
import 'package:didvan/utils/action_sheet.dart';
|
import 'package:didvan/utils/action_sheet.dart';
|
||||||
|
|
@ -162,17 +161,46 @@ class _RadarState extends State<Radar> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (state.appState != AppState.failed) CategoriesRow1(),
|
if (state.appState != AppState.failed)
|
||||||
if (state.appState != AppState.failed) CategoriesRow2(),
|
CategoriesRow1(
|
||||||
|
topPadding: 300,
|
||||||
|
onSelected: _onCategorySelected,
|
||||||
|
categories: state.categories,
|
||||||
|
isColapsed:
|
||||||
|
state.isColapsed || state.searching || state.filtering,
|
||||||
|
),
|
||||||
|
if (state.appState != AppState.failed)
|
||||||
|
CategoriesRow2(
|
||||||
|
categories: state.categories,
|
||||||
|
isColapsed:
|
||||||
|
state.isColapsed || state.searching || state.filtering,
|
||||||
|
onSelected: _onCategorySelected,
|
||||||
|
),
|
||||||
if (state.appState != AppState.failed &&
|
if (state.appState != AppState.failed &&
|
||||||
!state.searching &&
|
!state.searching &&
|
||||||
!state.filtering)
|
!state.filtering)
|
||||||
CategoriesList(),
|
CategoriesList(
|
||||||
|
isRadar: true,
|
||||||
|
categories: state.categories,
|
||||||
|
isColapsed:
|
||||||
|
state.isColapsed || state.searching || state.filtering,
|
||||||
|
onSelected: () => state.getRadars(page: 1),
|
||||||
|
selectedCats: state.selectedCats,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onCategorySelected(CategoryData category) {
|
||||||
|
final state = context.read<RadarState>();
|
||||||
|
state.selectedCats.clear();
|
||||||
|
if (category.id != 0) {
|
||||||
|
state.selectedCats.add(category);
|
||||||
|
}
|
||||||
|
state.getRadars(page: 1);
|
||||||
|
}
|
||||||
|
|
||||||
void _onChanged(String value) {
|
void _onChanged(String value) {
|
||||||
final state = context.read<RadarState>();
|
final state = context.read<RadarState>();
|
||||||
if (value.length < 4 && value.isNotEmpty || state.lastSearch == value) {
|
if (value.length < 4 && value.isNotEmpty || state.lastSearch == value) {
|
||||||
|
|
@ -268,7 +296,7 @@ class _RadarState extends State<Radar> {
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||||||
child: DidvanCheckbox(
|
child: DidvanCheckbox(
|
||||||
title: state.categories[i].title,
|
title: state.categories[i].label,
|
||||||
value: state.selectedCats.contains(state.categories[i]),
|
value: state.selectedCats.contains(state.categories[i]),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:didvan/constants/assets.dart';
|
import 'package:didvan/constants/assets.dart';
|
||||||
|
import 'package:didvan/models/category.dart';
|
||||||
import 'package:didvan/models/enums.dart';
|
import 'package:didvan/models/enums.dart';
|
||||||
import 'package:didvan/models/overview_data.dart';
|
import 'package:didvan/models/overview_data.dart';
|
||||||
import 'package:didvan/models/requests/radar.dart';
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
import 'package:didvan/models/view/radar_category.dart';
|
|
||||||
import 'package:didvan/providers/core.dart';
|
import 'package:didvan/providers/core.dart';
|
||||||
import 'package:didvan/services/network/request.dart';
|
import 'package:didvan/services/network/request.dart';
|
||||||
import 'package:didvan/services/network/request_helper.dart';
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
|
|
@ -16,8 +16,8 @@ class RadarState extends CoreProvier {
|
||||||
int lastPage = 1;
|
int lastPage = 1;
|
||||||
bool isScrolled = false;
|
bool isScrolled = false;
|
||||||
bool shouldColapse = false;
|
bool shouldColapse = false;
|
||||||
final List<RadarCategory> selectedCats = [];
|
final List<CategoryData> selectedCats = [];
|
||||||
List<RadarCategory> categories = [];
|
List<CategoryData> categories = [];
|
||||||
final List<OverviewData> radars = [];
|
final List<OverviewData> radars = [];
|
||||||
|
|
||||||
bool get filtering =>
|
bool get filtering =>
|
||||||
|
|
@ -99,34 +99,34 @@ class RadarState extends CoreProvier {
|
||||||
getRadars(page: 1);
|
getRadars(page: 1);
|
||||||
});
|
});
|
||||||
categories = [
|
categories = [
|
||||||
RadarCategory(
|
CategoryData(
|
||||||
id: 1,
|
id: 1,
|
||||||
title: 'اقتصادی',
|
label: 'اقتصادی',
|
||||||
asset: Assets.economicCategoryIcon,
|
asset: Assets.economicCategoryIcon,
|
||||||
),
|
),
|
||||||
RadarCategory(
|
CategoryData(
|
||||||
id: 2,
|
id: 2,
|
||||||
title: 'سیاسی',
|
label: 'سیاسی',
|
||||||
asset: Assets.politicalCategoryIcon,
|
asset: Assets.politicalCategoryIcon,
|
||||||
),
|
),
|
||||||
RadarCategory(
|
CategoryData(
|
||||||
id: 3,
|
id: 3,
|
||||||
title: 'فناوری',
|
label: 'فناوری',
|
||||||
asset: Assets.techCategoryIcon,
|
asset: Assets.techCategoryIcon,
|
||||||
),
|
),
|
||||||
RadarCategory(
|
CategoryData(
|
||||||
id: 4,
|
id: 4,
|
||||||
title: 'کسب و کار',
|
label: 'کسب و کار',
|
||||||
asset: Assets.businessCategoryIcon,
|
asset: Assets.businessCategoryIcon,
|
||||||
),
|
),
|
||||||
RadarCategory(
|
CategoryData(
|
||||||
id: 5,
|
id: 5,
|
||||||
title: 'زیست محیطی',
|
label: 'زیست محیطی',
|
||||||
asset: Assets.enviromentalCategoryIcon,
|
asset: Assets.enviromentalCategoryIcon,
|
||||||
),
|
),
|
||||||
RadarCategory(
|
CategoryData(
|
||||||
id: 6,
|
id: 6,
|
||||||
title: 'اجتماعی',
|
label: 'اجتماعی',
|
||||||
asset: Assets.socialCategoryIcon,
|
asset: Assets.socialCategoryIcon,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,196 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/constants/assets.dart';
|
import 'package:didvan/constants/assets.dart';
|
||||||
|
import 'package:didvan/models/category.dart';
|
||||||
|
import 'package:didvan/models/enums.dart';
|
||||||
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
|
import 'package:didvan/views/home/statistics/statistics_state.dart';
|
||||||
|
import 'package:didvan/views/home/widgets/categories_gird.dart';
|
||||||
|
import 'package:didvan/views/home/widgets/categories_list.dart';
|
||||||
import 'package:didvan/views/home/widgets/logo_app_bar.dart';
|
import 'package:didvan/views/home/widgets/logo_app_bar.dart';
|
||||||
|
import 'package:didvan/views/home/widgets/overview/radar.dart';
|
||||||
|
import 'package:didvan/views/widgets/animated_visibility.dart';
|
||||||
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
|
import 'package:didvan/views/widgets/state_handlers/empty_state.dart';
|
||||||
|
import 'package:didvan/views/widgets/state_handlers/sliver_state_handler.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class Statictics extends StatelessWidget {
|
class Statistics extends StatefulWidget {
|
||||||
const Statictics({Key? key}) : super(key: key);
|
const Statistics({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<Statistics> createState() => _RadarState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RadarState extends State<Statistics> {
|
||||||
|
final ScrollController _scrollController = ScrollController();
|
||||||
|
|
||||||
|
bool _isAnimating = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_scrollController.addListener(() {
|
||||||
|
_handleAnimations();
|
||||||
|
});
|
||||||
|
final state = context.read<StatisticsState>();
|
||||||
|
state.addListener(() {
|
||||||
|
if (state.shouldColapse && mounted) {
|
||||||
|
_handleAnimations(true);
|
||||||
|
state.shouldColapse = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
state.init();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(
|
return Consumer<StatisticsState>(
|
||||||
children: [
|
builder: (context, state, child) => Stack(
|
||||||
const LogoAppBar(),
|
children: [
|
||||||
Expanded(
|
CustomScrollView(
|
||||||
child: EmptyState(
|
physics: _isAnimating
|
||||||
asset: Assets.emptyChart,
|
? const NeverScrollableScrollPhysics()
|
||||||
title: 'قیمتها و شاخصهای اقتصادی',
|
: const ClampingScrollPhysics(),
|
||||||
subtitle: 'به زودی...',
|
controller: _scrollController,
|
||||||
titleColor: Theme.of(context).colorScheme.title,
|
slivers: [
|
||||||
|
const SliverToBoxAdapter(child: LogoAppBar()),
|
||||||
|
if (state.appState != AppState.failed)
|
||||||
|
const SliverToBoxAdapter(
|
||||||
|
child: SizedBox(height: 156),
|
||||||
|
),
|
||||||
|
if (state.appState != AppState.failed)
|
||||||
|
SliverPadding(
|
||||||
|
padding: const EdgeInsets.only(right: 16, bottom: 20),
|
||||||
|
sliver: SliverToBoxAdapter(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerRight,
|
||||||
|
child: AnimatedVisibility(
|
||||||
|
isVisible: !state.isColapsed,
|
||||||
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
|
child: DidvanText(
|
||||||
|
'شاخصهای منتخب',
|
||||||
|
style: Theme.of(context).textTheme.subtitle1,
|
||||||
|
color: Theme.of(context).colorScheme.title,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverStateHandler<StatisticsState>(
|
||||||
|
onRetry: () => state.getStatistics(page: state.page),
|
||||||
|
state: state,
|
||||||
|
itemPadding: const EdgeInsets.only(
|
||||||
|
bottom: 20,
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
),
|
||||||
|
enableEmptyState: state.statistics.isEmpty,
|
||||||
|
emptyState: Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 120),
|
||||||
|
child: EmptyState(
|
||||||
|
asset: Assets.emptyResult,
|
||||||
|
title: 'موردی برای نمایش وجود ندارد.',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
placeholder: RadarOverview.placeholder,
|
||||||
|
builder: (context, state, index) {
|
||||||
|
index += 2;
|
||||||
|
if (index % 15 == 0 && state.lastPage != state.page) {
|
||||||
|
state.getStatistics(page: state.page + 1);
|
||||||
|
}
|
||||||
|
index -= 2;
|
||||||
|
if (index >= state.statistics.length) {
|
||||||
|
return RadarOverview.placeholder;
|
||||||
|
}
|
||||||
|
final radar = state.statistics[index];
|
||||||
|
return RadarOverview(
|
||||||
|
radar: radar,
|
||||||
|
onMarkChanged: state.changeMark,
|
||||||
|
onCommentsChanged: (id, count) => {},
|
||||||
|
radarRequestArgs: RadarRequestArgs(
|
||||||
|
page: state.page,
|
||||||
|
categories:
|
||||||
|
List.from(state.selectedCats.map((cat) => cat.id)),
|
||||||
|
isSingleItem: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount: state.statistics.length +
|
||||||
|
(state.lastPage == state.page ? 0 : 3),
|
||||||
|
),
|
||||||
|
if (state.statistics.length == 1)
|
||||||
|
const SliverToBoxAdapter(
|
||||||
|
child: SizedBox(height: 320),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
if (state.appState != AppState.failed)
|
||||||
],
|
CategoriesRow1(
|
||||||
|
onSelected: _onCategorySelected,
|
||||||
|
categories: state.categories,
|
||||||
|
isColapsed: state.isColapsed,
|
||||||
|
topPadding: 120,
|
||||||
|
),
|
||||||
|
if (state.appState != AppState.failed)
|
||||||
|
CategoriesList(
|
||||||
|
isRadar: false,
|
||||||
|
categories: state.categories,
|
||||||
|
isColapsed: state.isColapsed,
|
||||||
|
onSelected: () => state.getStatistics(page: 1),
|
||||||
|
selectedCats: state.selectedCats,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onCategorySelected(CategoryData category) {
|
||||||
|
final state = context.read<StatisticsState>();
|
||||||
|
state.selectedCats.clear();
|
||||||
|
if (category.id != 0) {
|
||||||
|
state.selectedCats.add(category);
|
||||||
|
}
|
||||||
|
state.getStatistics(page: 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleAnimations([bool forceAnimate = false]) async {
|
||||||
|
final state = context.read<StatisticsState>();
|
||||||
|
if (_isAnimating) return;
|
||||||
|
final double position = _scrollController.offset;
|
||||||
|
if (position > 5 && !state.isColapsed || forceAnimate) {
|
||||||
|
state.isScrolled = true;
|
||||||
|
_isAnimating = true;
|
||||||
|
setState(() {});
|
||||||
|
await _scrollController.animateTo(
|
||||||
|
200,
|
||||||
|
duration: DesignConfig.mediumAnimationDuration,
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
);
|
||||||
|
_isAnimating = false;
|
||||||
|
setState(() {});
|
||||||
|
} else if (position <
|
||||||
|
min(_scrollController.position.maxScrollExtent, 200) &&
|
||||||
|
state.isColapsed) {
|
||||||
|
state.isScrolled = false;
|
||||||
|
_isAnimating = true;
|
||||||
|
setState(() {});
|
||||||
|
await _scrollController.animateTo(
|
||||||
|
0,
|
||||||
|
duration: DesignConfig.mediumAnimationDuration,
|
||||||
|
curve: Curves.easeIn,
|
||||||
|
);
|
||||||
|
_isAnimating = false;
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_scrollController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
import 'package:didvan/constants/assets.dart';
|
||||||
|
import 'package:didvan/models/category.dart';
|
||||||
|
import 'package:didvan/models/enums.dart';
|
||||||
|
import 'package:didvan/models/overview_data.dart';
|
||||||
|
import 'package:didvan/models/requests/radar.dart';
|
||||||
|
import 'package:didvan/providers/core.dart';
|
||||||
|
import 'package:didvan/services/network/request.dart';
|
||||||
|
import 'package:didvan/services/network/request_helper.dart';
|
||||||
|
|
||||||
|
class StatisticsState extends CoreProvier {
|
||||||
|
int page = 1;
|
||||||
|
int lastPage = 1;
|
||||||
|
bool isScrolled = false;
|
||||||
|
bool shouldColapse = false;
|
||||||
|
final List<CategoryData> selectedCats = [];
|
||||||
|
List<CategoryData> categories = [];
|
||||||
|
final List<OverviewData> statistics = [];
|
||||||
|
|
||||||
|
bool get isColapsed => (isCategorySelected && isScrolled) || isScrolled;
|
||||||
|
|
||||||
|
bool get isCategorySelected => selectedCats.length == 1;
|
||||||
|
|
||||||
|
void resetFilters(bool isInit) {
|
||||||
|
selectedCats.clear();
|
||||||
|
isScrolled = false;
|
||||||
|
if (!isInit) {
|
||||||
|
getStatistics(page: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> getStatistics({
|
||||||
|
required int page,
|
||||||
|
}) async {
|
||||||
|
this.page = page;
|
||||||
|
if (this.page == page) {
|
||||||
|
statistics.clear();
|
||||||
|
}
|
||||||
|
if (page == 1) {
|
||||||
|
appState = AppState.busy;
|
||||||
|
}
|
||||||
|
final RequestService service = RequestService(
|
||||||
|
RequestHelper.radarOverviews(
|
||||||
|
args: RadarRequestArgs(
|
||||||
|
page: page,
|
||||||
|
categories: selectedCats.map((e) => e.id).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await service.httpGet();
|
||||||
|
if (service.isSuccess) {
|
||||||
|
lastPage = service.result['lastPage'];
|
||||||
|
final radarsList = service.result['radars'];
|
||||||
|
for (var i = 0; i < radarsList.length; i++) {
|
||||||
|
statistics.add(OverviewData.fromJson(radarsList[i]));
|
||||||
|
}
|
||||||
|
if (isColapsed || isCategorySelected) {
|
||||||
|
shouldColapse = true;
|
||||||
|
}
|
||||||
|
appState = AppState.idle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
appState = AppState.failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> changeMark(int id, bool value, bool shouldUpdate) async {
|
||||||
|
statistics.firstWhere((element) => element.id == id).marked = value;
|
||||||
|
if (shouldUpdate) {
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
resetFilters(true);
|
||||||
|
Future.delayed(Duration.zero, () {
|
||||||
|
getStatistics(page: 1);
|
||||||
|
});
|
||||||
|
categories = [
|
||||||
|
CategoryData(
|
||||||
|
id: 1,
|
||||||
|
label: 'اقتصاد کلان',
|
||||||
|
asset: Assets.economicCategoryIcon,
|
||||||
|
),
|
||||||
|
CategoryData(
|
||||||
|
id: 2,
|
||||||
|
label: 'صنعت فولاد',
|
||||||
|
asset: Assets.politicalCategoryIcon,
|
||||||
|
),
|
||||||
|
CategoryData(
|
||||||
|
id: 3,
|
||||||
|
label: 'بازار سرمایه',
|
||||||
|
asset: Assets.techCategoryIcon,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,32 @@
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/views/home/radar/radar_state.dart';
|
import 'package:didvan/models/category.dart';
|
||||||
import 'package:didvan/views/home/radar/widgets/category_item.dart';
|
import 'package:didvan/views/home/widgets/category_item.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class CategoriesRow1 extends StatelessWidget {
|
class CategoriesRow1 extends StatelessWidget {
|
||||||
const CategoriesRow1({Key? key}) : super(key: key);
|
final List<CategoryData> categories;
|
||||||
|
final bool isColapsed;
|
||||||
|
final double topPadding;
|
||||||
|
final void Function(CategoryData data) onSelected;
|
||||||
|
const CategoriesRow1({
|
||||||
|
Key? key,
|
||||||
|
required this.categories,
|
||||||
|
required this.isColapsed,
|
||||||
|
required this.onSelected,
|
||||||
|
required this.topPadding,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final state = context.read<RadarState>();
|
|
||||||
final isColapsed = state.isColapsed || state.searching || state.filtering;
|
|
||||||
final MediaQueryData d = MediaQuery.of(context);
|
final MediaQueryData d = MediaQuery.of(context);
|
||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
curve: Curves.easeIn,
|
curve: Curves.easeIn,
|
||||||
duration: DesignConfig.mediumAnimationDuration,
|
duration: DesignConfig.mediumAnimationDuration,
|
||||||
top: isColapsed ? -60 : 300 + d.padding.top,
|
top: isColapsed ? -60 : topPadding + d.padding.top,
|
||||||
left: isColapsed ? -80 : 0,
|
left: isColapsed ? -80 : 0,
|
||||||
right: isColapsed ? 124 : 0,
|
right: isColapsed ? 124 : 0,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: context
|
children: categories
|
||||||
.read<RadarState>()
|
|
||||||
.categories
|
|
||||||
.sublist(0, 3)
|
.sublist(0, 3)
|
||||||
.map(
|
.map(
|
||||||
(category) => Expanded(
|
(category) => Expanded(
|
||||||
|
|
@ -30,6 +35,7 @@ class CategoriesRow1 extends StatelessWidget {
|
||||||
child: CategoryItem(
|
child: CategoryItem(
|
||||||
category: category,
|
category: category,
|
||||||
isColapsed: isColapsed,
|
isColapsed: isColapsed,
|
||||||
|
onSelected: () => onSelected(category),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -41,14 +47,19 @@ class CategoriesRow1 extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class CategoriesRow2 extends StatelessWidget {
|
class CategoriesRow2 extends StatelessWidget {
|
||||||
|
final List<CategoryData> categories;
|
||||||
|
final bool isColapsed;
|
||||||
|
final void Function(CategoryData data) onSelected;
|
||||||
|
|
||||||
const CategoriesRow2({
|
const CategoriesRow2({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
required this.categories,
|
||||||
|
required this.isColapsed,
|
||||||
|
required this.onSelected,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final state = context.read<RadarState>();
|
|
||||||
final isColapsed = state.isColapsed || state.searching || state.filtering;
|
|
||||||
final MediaQueryData d = MediaQuery.of(context);
|
final MediaQueryData d = MediaQuery.of(context);
|
||||||
return AnimatedPositioned(
|
return AnimatedPositioned(
|
||||||
curve: Curves.easeIn,
|
curve: Curves.easeIn,
|
||||||
|
|
@ -57,14 +68,13 @@ class CategoriesRow2 extends StatelessWidget {
|
||||||
left: isColapsed ? -d.size.width : 0,
|
left: isColapsed ? -d.size.width : 0,
|
||||||
right: isColapsed ? d.size.width : 0,
|
right: isColapsed ? d.size.width : 0,
|
||||||
child: Row(
|
child: Row(
|
||||||
children: context
|
children: categories
|
||||||
.read<RadarState>()
|
|
||||||
.categories
|
|
||||||
.sublist(3, 6)
|
.sublist(3, 6)
|
||||||
.map(
|
.map(
|
||||||
(category) => Expanded(
|
(category) => Expanded(
|
||||||
child: CategoryItem(
|
child: CategoryItem(
|
||||||
category: category,
|
category: category,
|
||||||
|
onSelected: () => onSelected(category),
|
||||||
isColapsed: isColapsed,
|
isColapsed: isColapsed,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -1,14 +1,24 @@
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/models/view/radar_category.dart';
|
import 'package:didvan/models/category.dart';
|
||||||
import 'package:didvan/views/home/radar/radar_state.dart';
|
|
||||||
import 'package:didvan/views/widgets/animated_visibility.dart';
|
import 'package:didvan/views/widgets/animated_visibility.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class CategoriesList extends StatefulWidget {
|
class CategoriesList extends StatefulWidget {
|
||||||
const CategoriesList({Key? key}) : super(key: key);
|
final bool isColapsed;
|
||||||
|
final List<CategoryData> selectedCats;
|
||||||
|
final List<CategoryData> categories;
|
||||||
|
final VoidCallback onSelected;
|
||||||
|
final bool isRadar;
|
||||||
|
const CategoriesList({
|
||||||
|
Key? key,
|
||||||
|
required this.isColapsed,
|
||||||
|
required this.selectedCats,
|
||||||
|
required this.categories,
|
||||||
|
required this.onSelected,
|
||||||
|
required this.isRadar,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<CategoriesList> createState() => _CategoriesListState();
|
State<CategoriesList> createState() => _CategoriesListState();
|
||||||
|
|
@ -21,12 +31,11 @@ class _CategoriesListState extends State<CategoriesList> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(covariant CategoriesList oldWidget) {
|
void didUpdateWidget(covariant CategoriesList oldWidget) {
|
||||||
final RadarState state = context.read<RadarState>();
|
if (widget.selectedCats.isNotEmpty &&
|
||||||
if (state.selectedCats.isNotEmpty &&
|
_lastSelectedCategoryId != widget.selectedCats.first.id) {
|
||||||
_lastSelectedCategoryId != state.selectedCats.first.id) {
|
_lastSelectedCategoryId = widget.selectedCats.first.id;
|
||||||
_lastSelectedCategoryId = state.selectedCats.first.id;
|
|
||||||
_scrollController.animateTo(
|
_scrollController.animateTo(
|
||||||
state.selectedCats.first.id * 100,
|
widget.selectedCats.first.id * 100,
|
||||||
duration: DesignConfig.lowAnimationDuration,
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
curve: Curves.easeIn,
|
curve: Curves.easeIn,
|
||||||
);
|
);
|
||||||
|
|
@ -37,15 +46,14 @@ class _CategoriesListState extends State<CategoriesList> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final MediaQueryData d = MediaQuery.of(context);
|
final MediaQueryData d = MediaQuery.of(context);
|
||||||
final state = context.read<RadarState>();
|
|
||||||
final isColapsed = state.isColapsed || state.searching || state.filtering;
|
|
||||||
return Positioned(
|
return Positioned(
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
child: AnimatedCrossFade(
|
child: AnimatedCrossFade(
|
||||||
crossFadeState:
|
crossFadeState: widget.isColapsed
|
||||||
isColapsed ? CrossFadeState.showSecond : CrossFadeState.showFirst,
|
? CrossFadeState.showSecond
|
||||||
|
: CrossFadeState.showFirst,
|
||||||
duration: DesignConfig.mediumAnimationDuration,
|
duration: DesignConfig.mediumAnimationDuration,
|
||||||
reverseDuration: DesignConfig.lowAnimationDuration,
|
reverseDuration: DesignConfig.lowAnimationDuration,
|
||||||
sizeCurve: Curves.easeIn,
|
sizeCurve: Curves.easeIn,
|
||||||
|
|
@ -57,7 +65,7 @@ class _CategoriesListState extends State<CategoriesList> {
|
||||||
boxShadow: DesignConfig.defaultShadow,
|
boxShadow: DesignConfig.defaultShadow,
|
||||||
),
|
),
|
||||||
child: AnimatedVisibility(
|
child: AnimatedVisibility(
|
||||||
isVisible: isColapsed,
|
isVisible: widget.isColapsed,
|
||||||
duration: DesignConfig.mediumAnimationDuration,
|
duration: DesignConfig.mediumAnimationDuration,
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
|
|
@ -71,11 +79,14 @@ class _CategoriesListState extends State<CategoriesList> {
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
_itemBuilder(
|
_itemBuilder(
|
||||||
RadarCategory(title: 'همه', asset: '', id: 0),
|
CategoryData(
|
||||||
|
label: widget.isRadar ? 'همه' : 'منتخب',
|
||||||
|
id: 0,
|
||||||
|
),
|
||||||
context,
|
context,
|
||||||
),
|
),
|
||||||
for (var i = 0; i < state.categories.length; i++)
|
for (var i = 0; i < widget.categories.length; i++)
|
||||||
_itemBuilder(state.categories[i], context),
|
_itemBuilder(widget.categories[i], context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -85,20 +96,19 @@ class _CategoriesListState extends State<CategoriesList> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _itemBuilder(RadarCategory category, BuildContext context) {
|
Widget _itemBuilder(CategoryData category, BuildContext context) {
|
||||||
final state = context.read<RadarState>();
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (state.selectedCats.isNotEmpty &&
|
if (widget.selectedCats.isNotEmpty &&
|
||||||
state.selectedCats.first.id == category.id) return;
|
widget.selectedCats.first.id == category.id) return;
|
||||||
state.selectedCats.clear();
|
widget.selectedCats.clear();
|
||||||
if (category.id != 0) state.selectedCats.add(category);
|
if (category.id != 0) widget.selectedCats.add(category);
|
||||||
await _scrollController.animateTo(
|
await _scrollController.animateTo(
|
||||||
category.id * 100,
|
category.id * 100,
|
||||||
duration: DesignConfig.lowAnimationDuration,
|
duration: DesignConfig.lowAnimationDuration,
|
||||||
curve: Curves.easeIn,
|
curve: Curves.easeIn,
|
||||||
);
|
);
|
||||||
state.getRadars(page: 1);
|
widget.onSelected();
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.only(left: 12),
|
margin: const EdgeInsets.only(left: 12),
|
||||||
|
|
@ -108,15 +118,15 @@ class _CategoriesListState extends State<CategoriesList> {
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
child: DidvanText(
|
child: DidvanText(
|
||||||
category.title,
|
category.label,
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Theme.of(context).colorScheme.focusedBorder,
|
color: Theme.of(context).colorScheme.focusedBorder,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: state.selectedCats.length == 1 &&
|
color: widget.selectedCats.length == 1 &&
|
||||||
state.selectedCats.contains(category) ||
|
widget.selectedCats.contains(category) ||
|
||||||
category.id == 0 && state.selectedCats.isEmpty
|
category.id == 0 && widget.selectedCats.isEmpty
|
||||||
? Theme.of(context).colorScheme.focused
|
? Theme.of(context).colorScheme.focused
|
||||||
: null,
|
: null,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
import 'package:didvan/config/design_config.dart';
|
import 'package:didvan/config/design_config.dart';
|
||||||
import 'package:didvan/config/theme_data.dart';
|
import 'package:didvan/config/theme_data.dart';
|
||||||
import 'package:didvan/models/view/radar_category.dart';
|
import 'package:didvan/models/category.dart';
|
||||||
import 'package:didvan/views/home/radar/radar_state.dart';
|
|
||||||
import 'package:didvan/views/widgets/animated_visibility.dart';
|
import 'package:didvan/views/widgets/animated_visibility.dart';
|
||||||
import 'package:didvan/views/widgets/didvan/text.dart';
|
import 'package:didvan/views/widgets/didvan/text.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
|
|
||||||
class CategoryItem extends StatelessWidget {
|
class CategoryItem extends StatelessWidget {
|
||||||
final RadarCategory category;
|
final CategoryData category;
|
||||||
final bool isColapsed;
|
final bool isColapsed;
|
||||||
|
final VoidCallback onSelected;
|
||||||
|
|
||||||
const CategoryItem({
|
const CategoryItem({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.isColapsed,
|
required this.isColapsed,
|
||||||
required this.category,
|
required this.category,
|
||||||
|
required this.onSelected,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
double _width(context) {
|
double _width(context) {
|
||||||
|
|
@ -40,14 +40,7 @@ class CategoryItem extends StatelessWidget {
|
||||||
final Size ds = MediaQuery.of(context).size;
|
final Size ds = MediaQuery.of(context).size;
|
||||||
return Center(
|
return Center(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: onSelected,
|
||||||
final state = context.read<RadarState>();
|
|
||||||
state.selectedCats.clear();
|
|
||||||
if (category.id != 0) {
|
|
||||||
state.selectedCats.add(category);
|
|
||||||
}
|
|
||||||
state.getRadars(page: 1);
|
|
||||||
},
|
|
||||||
child: AnimatedContainer(
|
child: AnimatedContainer(
|
||||||
duration: DesignConfig.mediumAnimationDuration,
|
duration: DesignConfig.mediumAnimationDuration,
|
||||||
padding: isColapsed ? const EdgeInsets.all(4) : EdgeInsets.zero,
|
padding: isColapsed ? const EdgeInsets.all(4) : EdgeInsets.zero,
|
||||||
|
|
@ -77,14 +70,14 @@ class CategoryItem extends StatelessWidget {
|
||||||
borderRadius: DesignConfig.mediumBorderRadius,
|
borderRadius: DesignConfig.mediumBorderRadius,
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
child: SvgPicture.asset(category.asset),
|
child: SvgPicture.asset(category.asset!),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 8,
|
height: 8,
|
||||||
),
|
),
|
||||||
DidvanText(
|
DidvanText(
|
||||||
category.title,
|
category.label,
|
||||||
style: Theme.of(context).textTheme.subtitle2,
|
style: Theme.of(context).textTheme.subtitle2,
|
||||||
color: Theme.of(context).colorScheme.title,
|
color: Theme.of(context).colorScheme.title,
|
||||||
),
|
),
|
||||||
Loading…
Reference in New Issue