diff --git a/lib/features/dapps/presentation/responsive_layout/dapp_card.dart b/lib/features/dapps/presentation/responsive_layout/dapp_card.dart deleted file mode 100644 index f79e3930..00000000 --- a/lib/features/dapps/presentation/responsive_layout/dapp_card.dart +++ /dev/null @@ -1,319 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:datadashwallet/features/dapps/presentation/responsive_layout/card_item.dart'; -import 'package:datadashwallet/common/components/context_menu_extended.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:flutter_i18n/flutter_i18n.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:mxc_logic/mxc_logic.dart'; -import 'package:mxc_ui/mxc_ui.dart'; -import 'package:reorderable_grid_view/reorderable_grid_view.dart'; -import '../dapps_presenter.dart'; -import 'shatter_widget.dart'; - -class DAppCard extends HookConsumerWidget { - final Dapp dapp; - final int index; - final double width; - final bool isEditMode; - final VoidCallback? onTap; - final int mainAxisCount; - const DAppCard({ - super.key, - required this.index, - required this.width, - required this.dapp, - required this.isEditMode, - required this.onTap, - required this.mainAxisCount, - }); - - Widget cardBox( - BuildContext context, { - double? ratioFactor, - DAppsPagePresenter? actions, - void Function()? shatter, - bool animated = false, - }) { - final isMobile = mainAxisCount == CardMainAxisCount.mobile; - final imageRatioFactor = (isMobile ? 0.2 : 0.1); - String? image; - if (dapp is Bookmark) { - if ((dapp as Bookmark).image != null) { - image = (dapp as Bookmark).image!; - } else { - actions!.updateBookmarkFavIcon(dapp as Bookmark); - } - } else { - image = dapp.reviewApi!.icon!; - } - final name = dapp is Bookmark ? (dapp as Bookmark).title : dapp.app!.name!; - final imageSize = width * (ratioFactor ?? imageRatioFactor); - return GestureDetector( - onTap: () { - if (animated) { - Navigator.pop(context); - Future.delayed( - const Duration(milliseconds: 500), - () => onTap!(), - ); - } else if (onTap != null) { - onTap!(); - } - }, - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Stack( - clipBehavior: Clip.none, - children: [ - Container( - padding: const EdgeInsets.all(Sizes.spaceXLarge), - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(15)), - gradient: LinearGradient( - colors: [ - ColorsTheme.of(context).textBlack100, - ColorsTheme.of(context).iconBlack200, - ], - begin: AlignmentDirectional.bottomEnd, - end: AlignmentDirectional.topStart, - ), - ), - child: SizedBox( - width: imageSize, - height: imageSize, - child: image == null - ? Icon( - Icons.image_not_supported_rounded, - color: ColorsTheme.of(context).textPrimary, - ) - : image.contains('https') && dapp is Bookmark - ? CachedNetworkImage( - imageUrl: image, - fit: BoxFit.cover, - errorWidget: (context, url, error) { - return Column( - children: [ - Icon( - Icons.image_not_supported_outlined, - color: ColorsTheme.of(context).textError, - ), - const SizedBox( - height: Sizes.spaceXSmall, - ), - ], - ); - }, - ) - : image.contains('https') - ? SvgPicture.network( - image, - ) - : SvgPicture.asset( - image, - ), - ), - ), - if (isEditMode && dapp is Bookmark) - Positioned( - top: -6, - left: -6, - child: GestureDetector( - onTap: () => actions! - .removeBookmarkDialog(dapp as Bookmark, shatter!), - child: const Icon( - Icons.remove_circle_rounded, - ), - ), - ), - ], - ), - const SizedBox( - height: Sizes.spaceXSmall, - ), - Text( - name, - style: FontTheme.of(context) - .caption1 - .primary() - .copyWith(fontWeight: FontWeight.w700), - softWrap: false, - overflow: TextOverflow.ellipsis, - ), - ], - ), - ); - } - - @override - Widget build( - BuildContext context, - WidgetRef ref, - ) { - final actions = ref.read(appsPagePageContainer.actions); - final dappAbout = - dapp is Bookmark ? (dapp as Bookmark).title : dapp.app!.description!; - final dappUrl = dapp is Bookmark ? (dapp as Bookmark).url : dapp.app!.url!; - final isBookMark = dapp is Bookmark; - - final animationController = useAnimationController( - duration: const Duration(milliseconds: 75), - lowerBound: -pi / 50, - upperBound: pi / 50, - ); - - if (isEditMode) { - animationController.forward(); - } else { - animationController.stop(); - } - - animationController.addStatusListener((status) { - if (status == AnimationStatus.completed) { - animationController.reverse(); - } else if (status == AnimationStatus.dismissed) { - animationController.forward(); - } - }); - - List getDAppMarkContextMenuAction() => [ - CupertinoContextMenuAction( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - FlutterI18n.translate(context, 'about'), - style: FontTheme.of(context) - .caption1 - .primary() - .copyWith(fontWeight: FontWeight.w700), - ), - Text( - dapp.app!.description!, - style: FontTheme.of(context).caption1.primary(), - ), - ], - )), - CupertinoContextMenuAction( - trailingIcon: Icons.phone_iphone_rounded, - child: Text(FlutterI18n.translate(context, 'edit_home_screen'), - style: FontTheme.of(context).subtitle1()), - onPressed: () => popWrapper(actions.changeEditMode, context)), - CupertinoContextMenuAction( - trailingIcon: Icons.add_circle_outline_rounded, - child: Text(FlutterI18n.translate(context, 'add_new_dapp'), - style: FontTheme.of(context).subtitle1()), - onPressed: () => popWrapper(actions.addBookmark, context)), - ]; - - getBookMarkContextMenuAction(void Function() shatter) => [ - CupertinoContextMenuAction( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - FlutterI18n.translate(context, 'about'), - style: FontTheme.of(context) - .caption1 - .primary() - .copyWith(fontWeight: FontWeight.w700), - ), - Text( - dappAbout, - style: FontTheme.of(context).caption1.primary(), - ), - ], - )), - CupertinoContextMenuAction( - trailingIcon: Icons.phone_iphone_rounded, - child: Text(FlutterI18n.translate(context, 'edit_home_screen'), - style: FontTheme.of(context).body1()), - onPressed: () => popWrapper(actions.changeEditMode, context)), - CupertinoContextMenuAction( - trailingIcon: Icons.add_circle_outline_rounded, - child: Text(FlutterI18n.translate(context, 'add_new_dapp'), - style: FontTheme.of(context).body1()), - onPressed: () => popWrapper(actions.addBookmark, context)), - CupertinoContextMenuAction( - isDestructiveAction: true, - trailingIcon: Icons.remove_circle_outline_rounded, - onPressed: () => popWrapper(() async { - actions.removeBookmarkDialog(dapp as Bookmark, shatter); - }, context), - child: Text(FlutterI18n.translate(context, 'remove_dapp'), - style: FontTheme.of(context).body1Cl())) - ]; - final isMobile = mainAxisCount == CardMainAxisCount.mobile; - - final imageRatioFactor = (isMobile ? 0.2 : 0.1); - final animatedSize = (isMobile ? 0.3 : 0.15); - final sizeLimit = (imageRatioFactor / animatedSize); - - Widget getCardItem({void Function()? shatter}) { - final contextMenuActions = dapp is Bookmark? - ? getBookMarkContextMenuAction(shatter!) - : getDAppMarkContextMenuAction(); - if (isEditMode) { - return ReorderableItemView( - key: Key(dappUrl), - index: index, - child: AnimatedBuilder( - animation: animationController, - builder: (context, child) { - return Transform.rotate( - angle: animationController.value * - (pi / 8), // Adjust the range of rotation - child: child, - ); - }, - child: SizedBox.expand( - child: cardBox(context, shatter: shatter, actions: actions)), - ), - ); - } - return CupertinoContextMenuExtended.builder( - builder: (context, animation) { - return SizedBox( - width: MediaQuery.of(context).size.width / (mainAxisCount), - height: MediaQuery.of(context).size.width / (mainAxisCount), - child: Center( - child: cardBox( - context, - ratioFactor: animation.value < sizeLimit - ? null - : (animatedSize * animation.value), - shatter: shatter, - actions: actions, - animated: animation.value != 0.0, - ), - ), - ); - }, - actions: contextMenuActions, - ); - } - - return isBookMark - ? ShatteringWidget( - builder: (shatter) { - return getCardItem(shatter: shatter); - }, - onShatterCompleted: () => actions.removeBookmark(dapp as Bookmark)) - : getCardItem(); - } -} - -void popWrapper(void Function()? func, BuildContext context) { - Navigator.pop(context); - Future.delayed( - const Duration(milliseconds: 500), - () => {if (func != null) func()}, - ); -} diff --git a/lib/features/dapps/presentation/responsive_layout/dapp_card_layout.dart b/lib/features/dapps/presentation/responsive_layout/dapp_card_layout.dart index ec6e8e3f..123cc7dc 100644 --- a/lib/features/dapps/presentation/responsive_layout/dapp_card_layout.dart +++ b/lib/features/dapps/presentation/responsive_layout/dapp_card_layout.dart @@ -7,10 +7,10 @@ import 'package:reorderable_grid_view/reorderable_grid_view.dart'; import '../dapps_state.dart'; import '../widgets/dapp_indicator.dart'; -import 'card_item.dart'; +import 'dapps_layout/card_item.dart'; import 'dapp_loading.dart'; import 'dapp_utils.dart'; -import 'dapp_card.dart'; +import 'dapps_layout/dapp_card.dart'; class DappCardLayout extends HookConsumerWidget { const DappCardLayout({ diff --git a/lib/features/dapps/presentation/responsive_layout/dapp_loading.dart b/lib/features/dapps/presentation/responsive_layout/dapp_loading.dart index 99db8634..e3844fd2 100644 --- a/lib/features/dapps/presentation/responsive_layout/dapp_loading.dart +++ b/lib/features/dapps/presentation/responsive_layout/dapp_loading.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:mxc_ui/mxc_ui.dart'; import 'package:shimmer/shimmer.dart'; -import 'card_item.dart'; +import 'dapps_layout/card_item.dart'; class DAppLoading extends StatelessWidget { const DAppLoading({ diff --git a/lib/features/dapps/presentation/responsive_layout/dapp_utils.dart b/lib/features/dapps/presentation/responsive_layout/dapp_utils.dart index 7d31cb4c..2d1016bf 100644 --- a/lib/features/dapps/presentation/responsive_layout/dapp_utils.dart +++ b/lib/features/dapps/presentation/responsive_layout/dapp_utils.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:mxc_logic/mxc_logic.dart'; -import 'card_item.dart'; +import 'dapps_layout/card_item.dart'; class DappUtils { static bool loadingOnce = true; diff --git a/lib/features/dapps/presentation/responsive_layout/dapps_layout/build_card.dart b/lib/features/dapps/presentation/responsive_layout/dapps_layout/build_card.dart new file mode 100644 index 00000000..8eca9575 --- /dev/null +++ b/lib/features/dapps/presentation/responsive_layout/dapps_layout/build_card.dart @@ -0,0 +1,132 @@ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mxc_logic/mxc_logic.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +import '../../dapps_presenter.dart'; +import 'card_item.dart'; + +Widget buildCard( + BuildContext context, + Dapp dapp, + int mainAxisCount, + VoidCallback? onTap, + bool isEditMode, + double width, { + double? ratioFactor, + DAppsPagePresenter? actions, + void Function()? shatter, + bool animated = false, +}) { + final isMobile = mainAxisCount == CardMainAxisCount.mobile; + final imageRatioFactor = (isMobile ? 0.2 : 0.1); + String? image; + if (dapp is Bookmark) { + if ((dapp as Bookmark).image != null) { + image = (dapp as Bookmark).image!; + } else { + actions!.updateBookmarkFavIcon(dapp as Bookmark); + } + } else { + image = dapp.reviewApi!.icon!; + } + final name = dapp is Bookmark ? (dapp as Bookmark).title : dapp.app!.name!; + final imageSize = width * (ratioFactor ?? imageRatioFactor); + return GestureDetector( + onTap: () { + if (animated) { + Navigator.pop(context); + Future.delayed( + const Duration(milliseconds: 500), + () => onTap!(), + ); + } else if (onTap != null) { + onTap(); + } + }, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack( + clipBehavior: Clip.none, + children: [ + Container( + padding: const EdgeInsets.all(Sizes.spaceXLarge), + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(15)), + gradient: LinearGradient( + colors: [ + ColorsTheme.of(context).textBlack100, + ColorsTheme.of(context).iconBlack200, + ], + begin: AlignmentDirectional.bottomEnd, + end: AlignmentDirectional.topStart, + ), + ), + child: SizedBox( + width: imageSize, + height: imageSize, + child: image == null + ? Icon( + Icons.image_not_supported_rounded, + color: ColorsTheme.of(context).textPrimary, + ) + : image.contains('https') && dapp is Bookmark + ? CachedNetworkImage( + imageUrl: image, + fit: BoxFit.cover, + errorWidget: (context, url, error) { + return Column( + children: [ + Icon( + Icons.image_not_supported_outlined, + color: ColorsTheme.of(context).textError, + ), + const SizedBox( + height: Sizes.spaceXSmall, + ), + ], + ); + }, + ) + : image.contains('https') + ? SvgPicture.network( + image, + ) + : SvgPicture.asset( + image, + ), + ), + ), + if (isEditMode && dapp is Bookmark) + Positioned( + top: -6, + left: -6, + child: GestureDetector( + onTap: () => + actions!.removeBookmarkDialog(dapp as Bookmark, shatter!), + child: const Icon( + Icons.remove_circle_rounded, + ), + ), + ), + ], + ), + const SizedBox( + height: Sizes.spaceXSmall, + ), + Text( + name, + style: FontTheme.of(context) + .caption1 + .primary() + .copyWith(fontWeight: FontWeight.w700), + softWrap: false, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ); +} diff --git a/lib/features/dapps/presentation/responsive_layout/card_item.dart b/lib/features/dapps/presentation/responsive_layout/dapps_layout/card_item.dart similarity index 100% rename from lib/features/dapps/presentation/responsive_layout/card_item.dart rename to lib/features/dapps/presentation/responsive_layout/dapps_layout/card_item.dart diff --git a/lib/features/dapps/presentation/responsive_layout/dapps_layout/context_menu_actions.dart b/lib/features/dapps/presentation/responsive_layout/dapps_layout/context_menu_actions.dart new file mode 100644 index 00000000..a088f053 --- /dev/null +++ b/lib/features/dapps/presentation/responsive_layout/dapps_layout/context_menu_actions.dart @@ -0,0 +1,120 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:mxc_logic/mxc_logic.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +import '../../dapps_presenter.dart'; + +getContextMenuActions( + DAppsPagePresenter actions, + BuildContext context, + Dapp dapp, + void Function()? shatter, +) => + dapp is Bookmark? + ? getBookMarkContextMenuAction( + actions, + context, + dapp, + shatter!, + ) + : getDAppMarkContextMenuAction( + actions, + context, + dapp, + ); + +List getDAppMarkContextMenuAction( + DAppsPagePresenter actions, + BuildContext context, + Dapp dapp, +) => + [ + CupertinoContextMenuAction( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + FlutterI18n.translate(context, 'about'), + style: FontTheme.of(context) + .caption1 + .primary() + .copyWith(fontWeight: FontWeight.w700), + ), + Text( + dapp.app!.description!, + style: FontTheme.of(context).caption1.primary(), + ), + ], + )), + CupertinoContextMenuAction( + trailingIcon: Icons.phone_iphone_rounded, + child: Text(FlutterI18n.translate(context, 'edit_home_screen'), + style: FontTheme.of(context).subtitle1()), + onPressed: () => popWrapper(actions.changeEditMode, context)), + CupertinoContextMenuAction( + trailingIcon: Icons.add_circle_outline_rounded, + child: Text(FlutterI18n.translate(context, 'add_new_dapp'), + style: FontTheme.of(context).subtitle1()), + onPressed: () => popWrapper(actions.addBookmark, context)), + ]; + +getBookMarkContextMenuAction( + DAppsPagePresenter actions, + BuildContext context, + Dapp dapp, + void Function() shatter, +) => + [ + CupertinoContextMenuAction( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + FlutterI18n.translate(context, 'about'), + style: FontTheme.of(context) + .caption1 + .primary() + .copyWith(fontWeight: FontWeight.w700), + ), + Text( + getDappAbout(dapp), + style: FontTheme.of(context).caption1.primary(), + ), + ], + )), + CupertinoContextMenuAction( + trailingIcon: Icons.phone_iphone_rounded, + child: Text(FlutterI18n.translate(context, 'edit_home_screen'), + style: FontTheme.of(context).body1()), + onPressed: () => popWrapper(actions.changeEditMode, context)), + CupertinoContextMenuAction( + trailingIcon: Icons.add_circle_outline_rounded, + child: Text(FlutterI18n.translate(context, 'add_new_dapp'), + style: FontTheme.of(context).body1()), + onPressed: () => popWrapper(actions.addBookmark, context)), + CupertinoContextMenuAction( + isDestructiveAction: true, + trailingIcon: Icons.remove_circle_outline_rounded, + onPressed: () => popWrapper(() async { + actions.removeBookmarkDialog(dapp as Bookmark, shatter); + }, context), + child: Text(FlutterI18n.translate(context, 'remove_dapp'), + style: FontTheme.of(context).body1Cl())) + ]; + +void popWrapper(void Function()? func, BuildContext context) { + Navigator.pop(context); + Future.delayed( + const Duration(milliseconds: 500), + () => {if (func != null) func()}, + ); +} + +String getDappAbout( + Dapp dapp, +) { + final dappAbout = dapp is Bookmark ? (dapp).title : dapp.app!.description!; + return dappAbout; +} diff --git a/lib/features/dapps/presentation/responsive_layout/dapps_layout/dapp_card.dart b/lib/features/dapps/presentation/responsive_layout/dapps_layout/dapp_card.dart new file mode 100644 index 00000000..b08ad270 --- /dev/null +++ b/lib/features/dapps/presentation/responsive_layout/dapps_layout/dapp_card.dart @@ -0,0 +1,128 @@ +import 'dart:math'; + +import 'package:datadashwallet/common/components/context_menu_extended.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mxc_logic/mxc_logic.dart'; +import 'package:reorderable_grid_view/reorderable_grid_view.dart'; +import '../../dapps_presenter.dart'; +import 'build_card.dart'; +import 'context_menu_actions.dart'; +import 'shatter_widget.dart'; +import 'card_item.dart'; + +class DAppCard extends HookConsumerWidget { + final Dapp dapp; + final int index; + final double width; + final bool isEditMode; + final VoidCallback? onTap; + final int mainAxisCount; + const DAppCard({ + super.key, + required this.index, + required this.width, + required this.dapp, + required this.isEditMode, + required this.onTap, + required this.mainAxisCount, + }); + + @override + Widget build( + BuildContext context, + WidgetRef ref, + ) { + final actions = ref.read(appsPagePageContainer.actions); + final dappUrl = dapp is Bookmark ? (dapp as Bookmark).url : dapp.app!.url!; + final isBookMark = dapp is Bookmark; + + final isMobile = mainAxisCount == CardMainAxisCount.mobile; + final imageRatioFactor = (isMobile ? 0.2 : 0.1); + final animatedSize = (isMobile ? 0.3 : 0.15); + final sizeLimit = (imageRatioFactor / animatedSize); + + final animationController = useAnimationController( + duration: const Duration(milliseconds: 75), + lowerBound: -pi / 50, + upperBound: pi / 50, + ); + + if (isEditMode) { + animationController.forward(); + } else { + animationController.stop(); + } + + animationController.addStatusListener((status) { + if (status == AnimationStatus.completed) { + animationController.reverse(); + } else if (status == AnimationStatus.dismissed) { + animationController.forward(); + } + }); + + Widget getCardItem({void Function()? shatter}) { + if (isEditMode) { + return ReorderableItemView( + key: Key(dappUrl), + index: index, + child: AnimatedBuilder( + animation: animationController, + builder: (context, child) { + return Transform.rotate( + angle: animationController.value * + (pi / 8), // Adjust the range of rotation + child: child, + ); + }, + child: SizedBox.expand( + child: buildCard( + context, dapp, mainAxisCount, onTap, isEditMode, width, + shatter: shatter, actions: actions)), + ), + ); + } + return CupertinoContextMenuExtended.builder( + builder: (context, animation) { + return SizedBox( + width: MediaQuery.of(context).size.width / (mainAxisCount), + height: MediaQuery.of(context).size.width / (mainAxisCount), + child: Center( + child: buildCard( + context, + dapp, + mainAxisCount, + onTap, + isEditMode, + width, + ratioFactor: animation.value < sizeLimit + ? null + : (animatedSize * animation.value), + shatter: shatter, + actions: actions, + animated: animation.value != 0.0, + ), + ), + ); + }, + actions: getContextMenuActions( + actions, + context, + dapp, + shatter, + ), + ); + } + + return isBookMark + ? ShatteringWidget( + builder: (shatter) { + return getCardItem(shatter: shatter); + }, + onShatterCompleted: () => actions.removeBookmark(dapp as Bookmark)) + : getCardItem(); + } +} diff --git a/lib/features/dapps/presentation/responsive_layout/shatter_widget.dart b/lib/features/dapps/presentation/responsive_layout/dapps_layout/shatter_widget.dart similarity index 100% rename from lib/features/dapps/presentation/responsive_layout/shatter_widget.dart rename to lib/features/dapps/presentation/responsive_layout/dapps_layout/shatter_widget.dart diff --git a/lib/features/dapps/presentation/responsive_layout/responsive_layout.dart b/lib/features/dapps/presentation/responsive_layout/responsive_layout.dart index c6071607..05a806f6 100644 --- a/lib/features/dapps/presentation/responsive_layout/responsive_layout.dart +++ b/lib/features/dapps/presentation/responsive_layout/responsive_layout.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:responsive_builder/responsive_builder.dart'; -import 'card_item.dart'; +import 'dapps_layout/card_item.dart'; import 'dapp_card_layout.dart'; class ResponsiveLayout extends StatelessWidget {