From 5c6bafb51e41816e39129ef66a7a90552bddeb02 Mon Sep 17 00:00:00 2001 From: behnam-deriv <133759298+behnam-deriv@users.noreply.github.com> Date: Fri, 12 Jul 2024 19:03:32 +0800 Subject: [PATCH] add info banner for indicators count limit --- .../lib/src/core_widgets/info_banner.dart | 61 +++++++++++++++++++ .../mobile_tools_ui/indicator_list_item.dart | 1 + .../mobile_tools_bottom_sheet_content.dart | 36 ++++++++--- .../lib/src/models/indicator_tab_label.dart | 3 +- 4 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 packages/deriv_mobile_chart_wrapper/lib/src/core_widgets/info_banner.dart diff --git a/packages/deriv_mobile_chart_wrapper/lib/src/core_widgets/info_banner.dart b/packages/deriv_mobile_chart_wrapper/lib/src/core_widgets/info_banner.dart new file mode 100644 index 000000000..0303f1379 --- /dev/null +++ b/packages/deriv_mobile_chart_wrapper/lib/src/core_widgets/info_banner.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; +import 'package:deriv_theme/deriv_theme.dart'; + +/// Information banner used to display information to the user. +class InfoBanner extends StatelessWidget { + /// Initializes [InfoBanner]. + const InfoBanner({ + required this.message, + this.onClose, + Key? key, + }) : super(key: key); + + /// Message to be displayed. + final String message; + + /// This callback will be called when the user click on the close banner icon. + final VoidCallback? onClose; + + @override + Widget build(BuildContext context) => Container( + padding: const EdgeInsets.symmetric( + horizontal: ThemeProvider.margin16, + vertical: ThemeProvider.margin08, + ), + decoration: BoxDecoration( + color: context.theme.colors.information.withOpacity(0.24), + borderRadius: BorderRadius.circular(ThemeProvider.borderRadius04), + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon( + Icons.info_outline, + color: context.theme.colors.information, + size: ThemeProvider.iconSize24, + ), + const SizedBox(width: ThemeProvider.margin08), + Expanded( + child: Text( + message, + style: TextStyles.overline, + ), + ), + if (onClose != null) + Padding( + padding: const EdgeInsetsDirectional.only( + start: ThemeProvider.margin08, + ), + child: GestureDetector( + onTap: onClose, + child: Icon( + Icons.close, + color: context.theme.colors.prominent, + size: ThemeProvider.iconSize16, + ), + ), + ), + ], + ), + ); +} diff --git a/packages/deriv_mobile_chart_wrapper/lib/src/mobile_tools_ui/indicator_list_item.dart b/packages/deriv_mobile_chart_wrapper/lib/src/mobile_tools_ui/indicator_list_item.dart index a8accf2e7..b88d9b8ed 100644 --- a/packages/deriv_mobile_chart_wrapper/lib/src/mobile_tools_ui/indicator_list_item.dart +++ b/packages/deriv_mobile_chart_wrapper/lib/src/mobile_tools_ui/indicator_list_item.dart @@ -37,6 +37,7 @@ class IndicatorListItem extends StatelessWidget { Widget build(BuildContext context) { return GestureDetector( onTap: onTap, + behavior: HitTestBehavior.translucent, child: Padding( padding: const EdgeInsets.all(ThemeProvider.margin16), child: Row( diff --git a/packages/deriv_mobile_chart_wrapper/lib/src/mobile_tools_ui/mobile_tools_bottom_sheet_content.dart b/packages/deriv_mobile_chart_wrapper/lib/src/mobile_tools_ui/mobile_tools_bottom_sheet_content.dart index c4df6c015..24784aa0f 100644 --- a/packages/deriv_mobile_chart_wrapper/lib/src/mobile_tools_ui/mobile_tools_bottom_sheet_content.dart +++ b/packages/deriv_mobile_chart_wrapper/lib/src/mobile_tools_ui/mobile_tools_bottom_sheet_content.dart @@ -14,6 +14,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; +import '../core_widgets/info_banner.dart'; import '../core_widgets/no_glow_scroll_behavior.dart'; /// Bottom sheet content to show the list of support tools (indicators/ drawing @@ -86,6 +87,9 @@ class _MobileToolsBottomSheetContentState return MobileToolsBottomSheetContent.indicators; } + /// Returns `true` if the limit of active indicators is reached. + bool get isLimitReached => indicatorsRepo.items.length >= 3; + late AddOnsRepository indicatorsRepo; @override @@ -106,6 +110,9 @@ class _MobileToolsBottomSheetContentState const SizedBox(height: ThemeProvider.margin16), _buildChipsList(), const SizedBox(height: ThemeProvider.margin16), + if (isLimitReached && + _selectedChip != IndicatorTabLabel.active) + _buildLimitInfoBanner(), Expanded( child: _selectedChip == IndicatorTabLabel.active ? _buildIndicatorsActiveTab() @@ -162,14 +169,17 @@ class _MobileToolsBottomSheetContentState itemBuilder: (_, index) { final IndicatorItemModel indicator = filteredIndicators[index]; - return IndicatorListItem( - iconAssetPath: indicator.icon, - title: indicator.title, - count: _getIndicatorCount(indicator), - onInfoIconTapped: () {}, - onTap: () { - indicatorsRepo.add(indicator.config); - }, + return Interaction( + isEnabled: !isLimitReached, + child: IndicatorListItem( + iconAssetPath: indicator.icon, + title: indicator.title, + count: _getIndicatorCount(indicator), + onInfoIconTapped: () {}, + onTap: () { + indicatorsRepo.add(indicator.config); + }, + ), ); }, ); @@ -241,7 +251,7 @@ class _MobileToolsBottomSheetContentState 'You have no active indicators yet.', style: context.themeProvider.textStyle( textStyle: TextStyles.body1, - color: context.themeProvider.colors.lessProminent, + color: const Color(0xFF999999), ), ), ], @@ -270,6 +280,12 @@ class _MobileToolsBottomSheetContentState ); } + Widget _buildLimitInfoBanner() { + return const InfoBanner( + message: 'You\'ve added the maximum number of active indicators.', + ); + } + /// Returns the number of active indicators for specified [indicator]. int _getIndicatorCount(IndicatorItemModel indicator) { return indicatorsRepo.items @@ -292,6 +308,8 @@ class _MobileToolsBottomSheetContentState horizontalPadding: Dimens.margin16, items: [ CustomChip( + labelBuilder: (_, __) => + IndicatorTabLabel.activeCount(indicatorsRepo.items.length), value: IndicatorTabLabel.active, onTap: _onChipTapped, isSelected: _selectedChip == IndicatorTabLabel.active, diff --git a/packages/deriv_mobile_chart_wrapper/lib/src/models/indicator_tab_label.dart b/packages/deriv_mobile_chart_wrapper/lib/src/models/indicator_tab_label.dart index 2995379fb..b61d21093 100644 --- a/packages/deriv_mobile_chart_wrapper/lib/src/models/indicator_tab_label.dart +++ b/packages/deriv_mobile_chart_wrapper/lib/src/models/indicator_tab_label.dart @@ -1,6 +1,7 @@ /// A class to define label of indicators chip. class IndicatorTabLabel { - static const String active = 'Active (0)'; + static String activeCount(int count) => 'Active ($count)'; + static const String active = 'Active'; static const String all = 'All'; static const String momentum = 'Momentum'; static const String volatility = 'Volatility';