D1APP-47 empty states configuration
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
|
@ -5,6 +5,7 @@ class Assets {
|
|||
static const String _basePath = 'lib/assets';
|
||||
static const String _baseImagesPath = _basePath + '/images';
|
||||
static const String _baseThemesPath = _basePath + '/images/themes';
|
||||
static const String _baseEmptyStatesPath = _basePath + '/images/empty_states';
|
||||
static const String _baseAnimationsPath = _basePath + '/animations';
|
||||
static const String _baseRecordsPath = _basePath + '/images/records';
|
||||
|
||||
|
|
@ -29,6 +30,19 @@ class Assets {
|
|||
static String get techCategoryIcon =>
|
||||
_baseImagesPath + '/categories/tech-$_themeSuffix.svg';
|
||||
|
||||
static String get emptyBookmark =>
|
||||
_baseEmptyStatesPath + '/bookmark-$_themeSuffix.svg';
|
||||
static String get emptyChart =>
|
||||
_baseEmptyStatesPath + '/chart-$_themeSuffix.svg';
|
||||
static String get emptyChat =>
|
||||
_baseEmptyStatesPath + '/chat-$_themeSuffix.svg';
|
||||
static String get emptyConnection =>
|
||||
_baseEmptyStatesPath + '/connection-$_themeSuffix.svg';
|
||||
static String get emptyResult =>
|
||||
_baseEmptyStatesPath + '/result-$_themeSuffix.svg';
|
||||
static String get emptyStudio =>
|
||||
_baseEmptyStatesPath + '/studio-$_themeSuffix.svg';
|
||||
|
||||
static const String lightTheme = _baseThemesPath + '/theme-light.svg';
|
||||
static const String darkTheme = _baseThemesPath + '/theme-dark.svg';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:didvan/constants/app_icons.dart';
|
||||
import 'package:didvan/models/enums.dart';
|
||||
import 'package:didvan/models/view/action_sheet_data.dart';
|
||||
import 'package:didvan/pages/home/news/news_state.dart';
|
||||
import 'package:didvan/pages/home/news/widgets/news_item.dart';
|
||||
|
|
@ -12,7 +13,8 @@ import 'package:didvan/pages/home/widgets/logo_app_bar.dart';
|
|||
import 'package:didvan/widgets/didvan/card.dart';
|
||||
import 'package:didvan/widgets/didvan/divider.dart';
|
||||
import 'package:didvan/widgets/shimmer_placeholder.dart';
|
||||
import 'package:didvan/widgets/sliver_state_handler.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_result.dart';
|
||||
import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
|
@ -25,25 +27,25 @@ class News extends StatefulWidget {
|
|||
|
||||
class _NewsState extends State<News> {
|
||||
Timer? _timer;
|
||||
final _focusNode = FocusNode();
|
||||
@override
|
||||
void initState() {
|
||||
Future.delayed(Duration.zero, () {
|
||||
context.read<NewsState>().getNews(page: 1);
|
||||
});
|
||||
context.read<NewsState>().init();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final state = context.watch<NewsState>();
|
||||
return Scaffold(
|
||||
body: CustomScrollView(
|
||||
return CustomScrollView(
|
||||
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,
|
||||
|
|
@ -52,16 +54,20 @@ class _NewsState extends State<News> {
|
|||
),
|
||||
),
|
||||
SliverStateHandler<NewsState>(
|
||||
onRetry: () => state.getNews(page: state.page),
|
||||
state: state,
|
||||
builder: (context, state, index) => NewsItem(
|
||||
news: state.news[index],
|
||||
),
|
||||
enableEmptyState: state.news.isEmpty,
|
||||
emptyState: EmptyResult(
|
||||
onNewSearch: () => _focusNode.requestFocus(),
|
||||
),
|
||||
childCount: state.news.length,
|
||||
itemPadding: const EdgeInsets.only(left: 16, right: 16, bottom: 16),
|
||||
placeholder: const _NewsItemPlaceholder(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ import 'package:didvan/widgets/didvan/divider.dart';
|
|||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:didvan/widgets/item_title.dart';
|
||||
import 'package:didvan/widgets/shimmer_placeholder.dart';
|
||||
import 'package:didvan/widgets/sliver_state_handler.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_result.dart';
|
||||
import 'package:didvan/widgets/state_handlers/sliver_state_handler.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ class Radar extends StatefulWidget {
|
|||
|
||||
class _RadarState extends State<Radar> {
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
// final ScrollController _categoriesScrollController = ScrollController();
|
||||
final _focusNode = FocusNode();
|
||||
|
||||
bool _isAnimating = false;
|
||||
|
||||
|
|
@ -58,8 +59,7 @@ class _RadarState extends State<Radar> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Consumer<RadarState>(
|
||||
return Consumer<RadarState>(
|
||||
builder: (context, state, child) => Stack(
|
||||
children: [
|
||||
CustomScrollView(
|
||||
|
|
@ -70,6 +70,7 @@ class _RadarState extends State<Radar> {
|
|||
controller: _scrollController,
|
||||
slivers: [
|
||||
const SliverToBoxAdapter(child: LogoAppBar()),
|
||||
if (state.appState != AppState.failed)
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16,
|
||||
|
|
@ -78,6 +79,7 @@ class _RadarState extends State<Radar> {
|
|||
),
|
||||
sliver: SliverToBoxAdapter(
|
||||
child: SearchField(
|
||||
focusNode: _focusNode,
|
||||
isFiltered: state.filtering,
|
||||
title: 'رادار',
|
||||
onChanged: _onChanged,
|
||||
|
|
@ -85,10 +87,13 @@ class _RadarState extends State<Radar> {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (!state.filtering && !state.searching)
|
||||
if (!state.filtering &&
|
||||
!state.searching &&
|
||||
state.appState != AppState.failed)
|
||||
const SliverToBoxAdapter(
|
||||
child: SizedBox(height: 276),
|
||||
),
|
||||
if (state.appState != AppState.failed)
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.only(right: 16, bottom: 20),
|
||||
sliver: SliverToBoxAdapter(
|
||||
|
|
@ -109,12 +114,16 @@ class _RadarState extends State<Radar> {
|
|||
),
|
||||
),
|
||||
SliverStateHandler<RadarState>(
|
||||
onRetry: () => state.getRadarOverviews(page: state.page),
|
||||
state: state,
|
||||
itemPadding: const EdgeInsets.only(
|
||||
bottom: 20,
|
||||
left: 16,
|
||||
right: 16,
|
||||
),
|
||||
enableEmptyState: state.radars.isEmpty,
|
||||
emptyState:
|
||||
EmptyResult(onNewSearch: () => _focusNode.requestFocus()),
|
||||
placeholder: const _RadarItemPlaceholder(),
|
||||
builder: (context, state, index) => RadarItem(
|
||||
radar: state.radars[index],
|
||||
|
|
@ -127,20 +136,22 @@ class _RadarState extends State<Radar> {
|
|||
),
|
||||
],
|
||||
),
|
||||
if (state.appState != AppState.failed)
|
||||
CategoriesRow1(
|
||||
isColapsed:
|
||||
state.isColapsed || state.searching || state.filtering,
|
||||
),
|
||||
if (state.appState != AppState.failed)
|
||||
CategoriesRow2(
|
||||
isColapsed:
|
||||
state.isColapsed || state.searching || state.filtering,
|
||||
),
|
||||
if (state.appState != AppState.failed)
|
||||
CategoriesList(
|
||||
isColapsed: state.isColapsed && !state.searching,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/models/enums.dart';
|
||||
import 'package:didvan/models/requests/radar.dart';
|
||||
import 'package:didvan/models/view/radar_category.dart';
|
||||
import 'package:didvan/models/radar_overview.dart';
|
||||
import 'package:didvan/providers/core_provider.dart';
|
||||
|
|
@ -12,6 +13,7 @@ class RadarState extends CoreProvier {
|
|||
String lastSearch = '';
|
||||
String? startDate;
|
||||
String? endDate;
|
||||
int page = 1;
|
||||
bool isScrolled = false;
|
||||
bool shouldColapse = false;
|
||||
final List<MapEntry> _markQueue = [];
|
||||
|
|
@ -44,17 +46,22 @@ class RadarState extends CoreProvier {
|
|||
Future<void> getRadarOverviews({
|
||||
required int page,
|
||||
}) async {
|
||||
if (this.page == page) {
|
||||
radars.clear();
|
||||
}
|
||||
this.page = page;
|
||||
lastSearch = search;
|
||||
appState = AppState.busy;
|
||||
final RequestService service = RequestService(
|
||||
RequestHelper.radarOverviews(
|
||||
args: RadarRequestArgs(
|
||||
page: page,
|
||||
startDate: startDate?.split(' ').first,
|
||||
endDate: endDate?.split(' ').first,
|
||||
search: search == '' ? null : search,
|
||||
categories: selectedCats.map((e) => e.id).toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
await service.httpGet();
|
||||
if (service.isSuccess) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import 'package:didvan/widgets/didvan/divider.dart';
|
|||
import 'package:didvan/widgets/didvan/scaffold.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:didvan/widgets/item_title.dart';
|
||||
import 'package:didvan/widgets/state_handler.dart';
|
||||
import 'package:didvan/widgets/state_handlers/state_handler.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
|
@ -27,6 +27,7 @@ class GeneralSettings extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return Consumer<GeneralSettingsState>(
|
||||
builder: (context, state, child) => StateHandler<GeneralSettingsState>(
|
||||
onRetry: () {},
|
||||
state: context.read<GeneralSettingsState>(),
|
||||
builder: (context, state) => DidvanScaffold(
|
||||
appBarData: AppBarData(hasBack: true, title: 'تنظیمات'),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/pages/home/widgets/logo_app_bar.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Statictics extends StatelessWidget {
|
||||
|
|
@ -5,6 +9,18 @@ class Statictics extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container();
|
||||
return Column(
|
||||
children: [
|
||||
const LogoAppBar(),
|
||||
Expanded(
|
||||
child: EmptyState(
|
||||
asset: Assets.emptyChart,
|
||||
title: 'قیمتها و شاخصهای اقتصادی',
|
||||
subtitle: 'به زودی...',
|
||||
titleColor: Theme.of(context).colorScheme.title,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/pages/home/widgets/logo_app_bar.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Studio extends StatelessWidget {
|
||||
|
|
@ -5,6 +9,18 @@ class Studio extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container();
|
||||
return Column(
|
||||
children: [
|
||||
const LogoAppBar(),
|
||||
Expanded(
|
||||
child: EmptyState(
|
||||
asset: Assets.emptyStudio,
|
||||
title: 'استودیو آینده',
|
||||
subtitle: 'به زودی...',
|
||||
titleColor: Theme.of(context).colorScheme.title,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class SearchField extends StatefulWidget {
|
||||
final String title;
|
||||
final FocusNode focusNode;
|
||||
final bool? isFiltered;
|
||||
final void Function(String value) onChanged;
|
||||
final VoidCallback? onFilterButtonPressed;
|
||||
|
|
@ -13,6 +14,7 @@ class SearchField extends StatefulWidget {
|
|||
Key? key,
|
||||
required this.title,
|
||||
required this.onChanged,
|
||||
required this.focusNode,
|
||||
this.onFilterButtonPressed,
|
||||
this.isFiltered,
|
||||
}) : super(key: key);
|
||||
|
|
@ -22,11 +24,9 @@ class SearchField extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _SearchFieldState extends State<SearchField> {
|
||||
final FocusNode _focusNode = FocusNode();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_focusNode.addListener(() {
|
||||
widget.focusNode.addListener(() {
|
||||
setState(() {});
|
||||
});
|
||||
super.initState();
|
||||
|
|
@ -44,8 +44,8 @@ class _SearchFieldState extends State<SearchField> {
|
|||
color: _fillColor(),
|
||||
),
|
||||
child: TextFormField(
|
||||
focusNode: _focusNode,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
focusNode: widget.focusNode,
|
||||
style: Theme.of(context).textTheme.bodyText2,
|
||||
textAlignVertical: TextAlignVertical.center,
|
||||
onChanged: widget.onChanged,
|
||||
keyboardType: TextInputType.text,
|
||||
|
|
@ -117,7 +117,7 @@ class _SearchFieldState extends State<SearchField> {
|
|||
}
|
||||
|
||||
Color _fillColor() {
|
||||
if (_focusNode.hasFocus) {
|
||||
if (widget.focusNode.hasFocus) {
|
||||
return Theme.of(context).colorScheme.surface;
|
||||
}
|
||||
return Theme.of(context).colorScheme.surface;
|
||||
|
|
@ -125,7 +125,7 @@ class _SearchFieldState extends State<SearchField> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
_focusNode.dispose();
|
||||
widget.focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class EmptyConnection extends StatelessWidget {
|
||||
final VoidCallback onRetry;
|
||||
const EmptyConnection({Key? key, required this.onRetry}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return EmptyState(
|
||||
asset: Assets.emptyConnection,
|
||||
title: 'ارتباط با اینترنت قطع شد...',
|
||||
action: onRetry,
|
||||
buttonTitle: 'تلاش دوباره',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:didvan/constants/assets.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_state.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class EmptyResult extends StatelessWidget {
|
||||
final VoidCallback onNewSearch;
|
||||
const EmptyResult({Key? key, required this.onNewSearch}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return EmptyState(
|
||||
asset: Assets.emptyResult,
|
||||
title: 'نتیجهای پیدا نشد',
|
||||
buttonTitle: 'تغییر جستجو',
|
||||
action: onNewSearch,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import 'package:didvan/config/theme_data.dart';
|
||||
import 'package:didvan/widgets/didvan/button.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
|
||||
class EmptyState extends StatelessWidget {
|
||||
final String asset;
|
||||
final String title;
|
||||
final String? subtitle;
|
||||
final String? buttonTitle;
|
||||
final VoidCallback? action;
|
||||
final Color? titleColor;
|
||||
|
||||
const EmptyState({
|
||||
Key? key,
|
||||
required this.asset,
|
||||
required this.title,
|
||||
this.action,
|
||||
this.buttonTitle,
|
||||
this.subtitle,
|
||||
this.titleColor,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: 210, child: SvgPicture.asset(asset)),
|
||||
const SizedBox(height: 16),
|
||||
DidvanText(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.headline3,
|
||||
color: titleColor ?? Theme.of(context).colorScheme.caption,
|
||||
),
|
||||
if (subtitle != null) const SizedBox(height: 8),
|
||||
if (subtitle != null)
|
||||
DidvanText(
|
||||
subtitle!,
|
||||
color: Theme.of(context).colorScheme.caption,
|
||||
),
|
||||
if (action != null) const SizedBox(height: 16),
|
||||
if (action != null)
|
||||
DidvanButton(
|
||||
height: 40,
|
||||
onPressed: action,
|
||||
title: buttonTitle,
|
||||
width: 112,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import 'package:didvan/models/enums.dart';
|
||||
import 'package:didvan/providers/core_provider.dart';
|
||||
import 'package:didvan/widgets/didvan/text.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_connection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SliverStateHandler<T extends CoreProvier> extends SliverList {
|
||||
final T state;
|
||||
final Widget Function(BuildContext context, T state, int index) builder;
|
||||
final int childCount;
|
||||
final VoidCallback? onRefresh;
|
||||
final VoidCallback onRetry;
|
||||
final bool enableEmptyState;
|
||||
final Widget? emptyState;
|
||||
final Widget? placeholder;
|
||||
|
|
@ -17,20 +17,28 @@ class SliverStateHandler<T extends CoreProvier> extends SliverList {
|
|||
required this.state,
|
||||
required this.builder,
|
||||
required this.childCount,
|
||||
required this.onRetry,
|
||||
this.itemPadding,
|
||||
this.placeholder,
|
||||
this.emptyState,
|
||||
this.enableEmptyState = false,
|
||||
this.onRefresh,
|
||||
}) : super(
|
||||
key: key,
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
if (state.appState == AppState.failed) {
|
||||
return const DidvanText('مشکل اتصال');
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height - 240,
|
||||
child: EmptyConnection(
|
||||
onRetry: onRetry,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (enableEmptyState) {
|
||||
return emptyState;
|
||||
if (enableEmptyState && state.appState == AppState.idle) {
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height - 240,
|
||||
child: emptyState,
|
||||
);
|
||||
}
|
||||
if (state.appState == AppState.busy) {
|
||||
return Padding(
|
||||
|
|
@ -44,7 +52,9 @@ class SliverStateHandler<T extends CoreProvier> extends SliverList {
|
|||
);
|
||||
},
|
||||
childCount: state.appState == AppState.idle
|
||||
? childCount
|
||||
? enableEmptyState
|
||||
? 1
|
||||
: childCount
|
||||
: state.appState == AppState.busy
|
||||
? 3
|
||||
: 1,
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
import 'package:didvan/models/enums.dart';
|
||||
import 'package:didvan/providers/core_provider.dart';
|
||||
import 'package:didvan/widgets/state_handlers/empty_connection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
|
||||
class StateHandler<T extends CoreProvier> extends StatelessWidget {
|
||||
final T state;
|
||||
final Widget Function(BuildContext context, T state) builder;
|
||||
final VoidCallback? onRefresh;
|
||||
final VoidCallback onRetry;
|
||||
final bool enableEmptyState;
|
||||
final Widget? placeholder;
|
||||
final Widget? emptyState;
|
||||
|
|
@ -14,11 +15,11 @@ class StateHandler<T extends CoreProvier> extends StatelessWidget {
|
|||
const StateHandler({
|
||||
Key? key,
|
||||
required this.builder,
|
||||
required this.onRetry,
|
||||
required this.state,
|
||||
this.emptyState,
|
||||
this.enableEmptyState = false,
|
||||
this.onRefresh,
|
||||
this.topPadding = 0,
|
||||
required this.state,
|
||||
this.placeholder,
|
||||
}) : super(key: key);
|
||||
|
||||
|
|
@ -42,7 +43,7 @@ class StateHandler<T extends CoreProvier> extends StatelessWidget {
|
|||
color: Theme.of(context).colorScheme.primary,
|
||||
);
|
||||
case AppState.failed:
|
||||
return Container();
|
||||
return EmptyConnection(onRetry: onRetry);
|
||||
default:
|
||||
return Container();
|
||||
}
|
||||
14
pubspec.lock
|
|
@ -160,6 +160,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.3.0"
|
||||
flutter_html:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_html
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0-alpha.2"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
|
@ -378,6 +385,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
numerus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: numerus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
octo_image:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
13
pubspec.yaml
|
|
@ -58,6 +58,7 @@ dependencies:
|
|||
image_cropper: ^1.4.1
|
||||
bot_toast: ^4.0.1
|
||||
flutter_secure_storage: ^5.0.2
|
||||
flutter_html: ^3.0.0-alpha.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
@ -103,6 +104,18 @@ flutter:
|
|||
- lib/assets/images/themes/theme-dark.svg
|
||||
- lib/assets/images/records/record-dark.svg
|
||||
- lib/assets/images/records/record-light.svg
|
||||
- lib/assets/images/empty_states/bookmark-light.svg
|
||||
- lib/assets/images/empty_states/chart-light.svg
|
||||
- lib/assets/images/empty_states/chat-light.svg
|
||||
- lib/assets/images/empty_states/connection-light.svg
|
||||
- lib/assets/images/empty_states/result-light.svg
|
||||
- lib/assets/images/empty_states/studio-light.svg
|
||||
- lib/assets/images/empty_states/bookmark-dark.svg
|
||||
- lib/assets/images/empty_states/chart-dark.svg
|
||||
- lib/assets/images/empty_states/chat-dark.svg
|
||||
- lib/assets/images/empty_states/connection-dark.svg
|
||||
- lib/assets/images/empty_states/result-dark.svg
|
||||
- lib/assets/images/empty_states/studio-dark.svg
|
||||
- lib/assets/animations/indicator-light.riv
|
||||
- lib/assets/animations/indicator-dark.riv
|
||||
|
||||
|
|
|
|||