diff --git a/easel/assets/images/svg/audio_file_icon.svg b/easel/assets/images/svg/audio_file_icon.svg new file mode 100644 index 0000000000..4b281ad10c --- /dev/null +++ b/easel/assets/images/svg/audio_file_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/easel/assets/images/svg/full_screen_img_gridview.svg b/easel/assets/images/svg/full_screen_img_gridview.svg new file mode 100644 index 0000000000..cf62e5fd75 --- /dev/null +++ b/easel/assets/images/svg/full_screen_img_gridview.svg @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/easel/i18n/de.json b/easel/i18n/de.json index 79c3e37f76..ff53e944c2 100644 --- a/easel/i18n/de.json +++ b/easel/i18n/de.json @@ -37,7 +37,7 @@ "compressing_thumbnail": "Miniaturbild Komprimieren", "uploading": "Hochladen ...", "nft_name": "{}", - "could_not_uploaded": "{} konnte nicht hochgeladen werden", + "could_not_uploaded": "{fileName} konnte nicht hochgeladen werden. Das {format} NFT muss:", "something_wrong": "Etwas ist schief gelaufen. Bitte versuchen Sie, die Anwendung neu zu starten.", "err_add_audio_thumbnail": "Bitte Audio-Thumbnail auswählen", "err_add_video_thumbnail": "Bitte Video-Thumbnail auswählen", diff --git a/easel/i18n/en-US.json b/easel/i18n/en-US.json index cd9d80b003..b720a88d2c 100644 --- a/easel/i18n/en-US.json +++ b/easel/i18n/en-US.json @@ -37,7 +37,7 @@ "compressing_thumbnail": "Compressing Thumbnail", "uploading": "Uploading ...", "nft_name": "{}", - "could_not_uploaded": "{} could not be uploaded", + "could_not_uploaded": "{fileName} could not be uploaded. The {format} NFT must be:", "something_wrong": "Something went wrong. Please try restarting the application.", "err_add_audio_thumbnail": "Please select audio thumbnail", "err_add_video_thumbnail": "Please select video thumbnail", diff --git a/easel/i18n/es.json b/easel/i18n/es.json index 3915a89ddd..f334fdfb05 100644 --- a/easel/i18n/es.json +++ b/easel/i18n/es.json @@ -37,7 +37,7 @@ "compressing_thumbnail": "Comprimir archivo de miniaturas", "uploading": "Subiendo...", "nft_name": "{}", - "could_not_uploaded": "{} no se pudo cargar", + "could_not_uploaded": "{fileName} no se pudo cargar. El {format} NFT debe ser:", "something_wrong": "Algo salió mal. Intenta reiniciar la aplicación.", "err_add_audio_thumbnail": "Seleccione el archivo de miniatura de audio", "err_add_video_thumbnail": "Seleccione el archivo de miniatura de video", diff --git a/easel/i18n/ru-RU.json b/easel/i18n/ru-RU.json index b92a479fed..6c1ef9b216 100644 --- a/easel/i18n/ru-RU.json +++ b/easel/i18n/ru-RU.json @@ -37,7 +37,7 @@ "pylons_app": "Приложение пилонов", "once_you_enter_all": "После того, как вы введете всю необходимую информацию, бесплатно запустите свой NFT в блокчейн pylons!", "compressing_thumbnail": "Compressing Thumbnail", - "could_not_uploaded": "{} не удалось загрузить", + "could_not_uploaded": "{fileName} не удалось загрузить. {format} NFT должен быть:", "something_wrong": "Что-то пошло не так. Попробуйте перезапустить приложение.", "err_add_audio_thumbnail": "Пожалуйста, выберите миниатюру аудио", "err_add_video_thumbnail": "Пожалуйста, выберите миниатюру видео", diff --git a/easel/lib/generated/locale_keys.g.dart b/easel/lib/generated/locale_keys.g.dart index e94bcf3abd..02e87f29a8 100644 --- a/easel/lib/generated/locale_keys.g.dart +++ b/easel/lib/generated/locale_keys.g.dart @@ -1,5 +1,4 @@ // DO NOT EDIT. This is code generated via package:easy_localization/generate.dart -// ignore_for_file: constant_identifier_names abstract class LocaleKeys { static const creator_hub = 'creator_hub'; @@ -8,7 +7,6 @@ abstract class LocaleKeys { static const publish_total = 'publish_total'; static const draft_total = 'draft_total'; static const draft = 'draft'; - static const publish = 'publish'; static const delete = 'delete'; static const view = 'view'; static const delete_error = 'delete_error'; diff --git a/easel/lib/models/nft_format.dart b/easel/lib/models/nft_format.dart index 87c5caac49..1a0b10a385 100644 --- a/easel/lib/models/nft_format.dart +++ b/easel/lib/models/nft_format.dart @@ -10,7 +10,12 @@ class NftFormat { final String badge; final Color color; - NftFormat({required this.format, required this.extensions, required this.badge, required this.color}); + NftFormat({ + required this.format, + required this.extensions, + required this.badge, + required this.color, + }); String getExtensionsList() { final buffer = StringBuffer(); @@ -45,7 +50,7 @@ class NftFormat { NftFormat( format: NFTTypes.audio, extensions: ['wav', 'aiff', 'alac', 'flac', 'mp3', 'aac', 'wma', 'ogg'], - badge: SVGUtils.kSvgNftFormatAudio, + badge: SVGUtils.kAudioFileIcon, color: EaselAppTheme.kLightRed, ), NftFormat( diff --git a/easel/lib/screens/choose_format_screen.dart b/easel/lib/screens/choose_format_screen.dart index 720ce09b1e..7f04ff22a3 100644 --- a/easel/lib/screens/choose_format_screen.dart +++ b/easel/lib/screens/choose_format_screen.dart @@ -6,17 +6,17 @@ import 'package:easel_flutter/models/picked_file_model.dart'; import 'package:easel_flutter/screens/preview_screen.dart'; import 'package:easel_flutter/utils/constants.dart'; import 'package:easel_flutter/utils/easel_app_theme.dart'; -import 'package:easel_flutter/utils/screen_responsive.dart'; import 'package:easel_flutter/utils/space_utils.dart'; import 'package:easel_flutter/viewmodels/home_viewmodel.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:flutter_svg_provider/flutter_svg_provider.dart' as svg_provider; import 'package:provider/provider.dart'; import '../generated/locale_keys.g.dart'; +import 'custom_widgets/step_labels.dart'; +import 'custom_widgets/steps_indicator.dart'; class ChooseFormatScreen extends StatefulWidget { const ChooseFormatScreen({Key? key}) : super(key: key); @@ -37,8 +37,14 @@ class _ChooseFormatScreenState extends State { } if (!provider.nftFormat.extensions.contains(result.extension)) { - errorText.value = LocaleKeys.un_supported_format.tr(); - showErrorDialog(); + final fileName = result.fileName.replaceAll(".${result.extension}", ""); + errorText.value = LocaleKeys.could_not_uploaded.tr( + namedArgs: { + kFileName: fileName, + kFormat: provider.nftFormat.format.getTitle(), + }, + ); + showErrorDialog(extensions: provider.nftFormat.extensions); return; } @@ -48,9 +54,9 @@ class _ChooseFormatScreenState extends State { return; } - if (easelProvider.repository.getFileSizeInGB(File(result.path).lengthSync()) > kFileSizeLimitForAudiVideoInGB) { + if (easelProvider.repository.getFileSizeInGB(File(result.path).lengthSync()) > kFileSizeLimitForAudioVideoInGB) { errorText.value = LocaleKeys.size_error.tr(); - showErrorDialog(type: nftFormat.format); + showErrorDialog(type: nftFormat.format, extensions: nftFormat.extensions); return; } @@ -64,11 +70,12 @@ class _ChooseFormatScreenState extends State { ))); } - void showErrorDialog({NFTTypes? type}) { + void showErrorDialog({NFTTypes? type, required List extensions}) { showDialog( context: context, builder: (context) => _ErrorMessageWidget( errorMessage: errorText.value, + extensions: extensions, nftTypes: type, onClose: () { Navigator.of(context).pop(); @@ -93,34 +100,44 @@ class _ChooseFormatScreenState extends State { body: Column( children: [ const VerticalSpace(20), - Stack(alignment: Alignment.center, children: [ - Align( + Stack( + alignment: Alignment.center, + children: [ + Align( alignment: Alignment.centerLeft, child: ValueListenableBuilder( valueListenable: homeViewModel.currentPage, builder: (_, int currentPage, __) => Padding( - padding: EdgeInsets.only(left: 10.sp), - child: IconButton( - onPressed: () { - ScaffoldMessenger.of(context).hideCurrentSnackBar(); - Navigator.of(context).pop(); - }, - icon: const Icon( - Icons.arrow_back_ios, - color: EaselAppTheme.kGrey, - ), - )), - )), - ValueListenableBuilder( - valueListenable: homeViewModel.currentPage, - builder: (_, int currentPage, __) { - return Text( - homeViewModel.pageTitles[homeViewModel.currentPage.value], - style: Theme.of(context).textTheme.bodyText1!.copyWith(fontSize: 18.sp, fontWeight: FontWeight.w400, color: EaselAppTheme.kDarkText), - ); - }, - ), - ]), + padding: EdgeInsets.only(left: 10.w), + child: IconButton( + onPressed: () { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + Navigator.of(context).pop(); + }, + icon: const Icon( + Icons.arrow_back_ios, + color: EaselAppTheme.kGrey, + ), + ), + ), + ), + ), + ValueListenableBuilder( + valueListenable: homeViewModel.currentPage, + builder: (_, int currentPage, __) { + return Column( + key: const Key(kProgressStepsKey), + children: [ + const VerticalSpace(20), + MyStepsIndicator(currentStep: homeViewModel.currentStep), + const VerticalSpace(5), + StepLabels(currentPage: homeViewModel.currentPage, currentStep: homeViewModel.currentStep), + ], + ); + }, + ), + ], + ), const VerticalSpace(20), Expanded( child: _CardWidget( @@ -231,7 +248,7 @@ class _CardWidget extends StatelessWidget { NftFormat.supportedFormats[typeIdx].badge, ), SizedBox( - width: 10.0.w, + width: 20.0.w, ), Expanded( child: Column( @@ -240,14 +257,22 @@ class _CardWidget extends StatelessWidget { children: [ Text( NftFormat.supportedFormats[typeIdx].format.getTitle().toUpperCase(), - style: Theme.of(context).textTheme.bodyText1!.copyWith(color: textIconColor, fontSize: 45.sp, fontWeight: FontWeight.bold), + style: Theme.of(context).textTheme.bodyText1!.copyWith( + color: textIconColor, + fontSize: 45.sp, + fontWeight: FontWeight.bold, + ), ), SizedBox(height: 3.h), RichText( overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, text: TextSpan( - style: Theme.of(context).textTheme.bodyText1!.copyWith(color: textIconColor, fontSize: 12.sp, fontWeight: FontWeight.w600), + style: Theme.of(context).textTheme.bodyText1!.copyWith( + color: textIconColor, + fontSize: 12.sp, + fontWeight: FontWeight.w600, + ), text: NftFormat.supportedFormats[typeIdx].getExtensionsList(), ), ), @@ -281,132 +306,80 @@ class _CardWidget extends StatelessWidget { } class _ErrorMessageWidget extends StatelessWidget { - const _ErrorMessageWidget({Key? key, required this.errorMessage, required this.onClose, this.nftTypes}) : super(key: key); + const _ErrorMessageWidget({ + Key? key, + required this.errorMessage, + required this.extensions, + required this.onClose, + this.nftTypes, + }) : super(key: key); final String errorMessage; final VoidCallback onClose; final NFTTypes? nftTypes; + final List extensions; @override Widget build(BuildContext context) { - return ScreenResponsive( - mobileScreen: (context) => buildMobile(context), - tabletScreen: (context) => buildTablet(context), - ); + return buildMobile(context); } - Padding buildTablet(BuildContext context) { - return Padding( - padding: EdgeInsets.symmetric(horizontal: 0.17.sw), - child: DecoratedBox( - decoration: const BoxDecoration(image: DecorationImage(image: svg_provider.Svg(SVGUtils.kSvgUploadErrorBG))), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - SvgPicture.asset( - SVGUtils.kSvgCloseIcon, - height: 30.h, - ), - SizedBox(height: 30.h), - Text( - errorMessage, - style: TextStyle(color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.w800), - ), - SizedBox(height: 30.h), - Column( + Widget buildMobile(BuildContext context) { + return Container( + width: double.maxFinite, + height: double.maxFinite, + margin: EdgeInsets.symmetric(horizontal: 0.1.sw, vertical: 0.08.sw), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + const Spacer(), + Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 15.w), + decoration: const BoxDecoration(color: EaselAppTheme.kRed), + child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text((nftTypes == NFTTypes.video || nftTypes == NFTTypes.audio) ? "• ${(kFileSizeLimitForAudiVideoInGB * 1000).toStringAsFixed(0)}MB Limit" : "• ${kFileSizeLimitInGB}GB Limit", - style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w800)), - Text(kUploadHint2, style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w800)), - Text(LocaleKeys.upload_hint_three.tr(), style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w800)), - ], - ), - SizedBox(height: 30.h), - GestureDetector( - child: SizedBox( - width: 0.35.sw, - height: 0.09.sw, - child: Stack( - children: [ - Positioned.fill(child: SvgPicture.asset(SVGUtils.kSvgCloseButton, fit: BoxFit.cover)), - Center( - child: Text( - LocaleKeys.close.tr(), - style: Theme.of(context).textTheme.bodyText1!.copyWith(fontSize: 16.sp, color: EaselAppTheme.kWhite, fontWeight: FontWeight.w300), + Text( + errorMessage, + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w800, + ), + ), + SizedBox(height: 10.h), + Text( + (nftTypes == NFTTypes.video || nftTypes == NFTTypes.audio) + ? "• ${(kFileSizeLimitForAudioVideoInGB * 1000).toStringAsFixed(0)}MB limit" + : "• ${kFileSizeLimitInGB}GB limit", + style: Theme.of(context).textTheme.bodyText2!.copyWith( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w800, ), - ), - ], ), - ), - onTap: () { - onClose(); - }, - ), - ], - ), - ), - ); - } - - Padding buildMobile(BuildContext context) { - return Padding( - padding: EdgeInsets.symmetric(horizontal: 0.10.sw), - child: DecoratedBox( - decoration: const BoxDecoration(image: DecorationImage(image: svg_provider.Svg(SVGUtils.kSvgUploadErrorBG))), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox(height: 10.h), - SvgPicture.asset( - SVGUtils.kSvgCloseIcon, - height: 30.h, - ), - SizedBox(height: 30.h), - Text( - errorMessage, - style: TextStyle(color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.w800), - ), - SizedBox(height: 30.h), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text((nftTypes == NFTTypes.video || nftTypes == NFTTypes.audio) ? "• ${(kFileSizeLimitForAudiVideoInGB * 1000).toStringAsFixed(0)}MB Limit" : "• ${kFileSizeLimitInGB}GB Limit", - style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w800)), - Text(kUploadHint2, style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w800)), - Text(LocaleKeys.upload_hint_three.tr(), style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w800)), - ], - ), - SizedBox(height: 30.h), - GestureDetector( - child: SizedBox( - width: 0.35.sw, - height: 0.09.sw, - child: Stack( - children: [ - Positioned.fill(child: SvgPicture.asset(SVGUtils.kSvgCloseButton, fit: BoxFit.cover)), - Center( - child: Text( - LocaleKeys.close.tr(), - style: Theme.of(context).textTheme.bodyText1!.copyWith( - fontSize: 16.sp, - color: EaselAppTheme.kWhite, - fontWeight: FontWeight.w300, - ), + Text( + "• ${extensions.join(", ").toUpperCase()}", + style: Theme.of(context).textTheme.bodyText2!.copyWith( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w800, ), - ), - ], ), - ), - onTap: () { - onClose(); - }, + Text( + LocaleKeys.upload_hint_three.tr(), + style: Theme.of(context).textTheme.bodyText2!.copyWith( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w800, + ), + ), + ], ), - SizedBox(height: 10.h), - ], - ), + ), + ], ), ); } diff --git a/easel/lib/screens/preview_screen.dart b/easel/lib/screens/preview_screen.dart index a70eb03148..e21ecc8590 100644 --- a/easel/lib/screens/preview_screen.dart +++ b/easel/lib/screens/preview_screen.dart @@ -13,10 +13,12 @@ import 'package:easel_flutter/widgets/video_widget.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:get_it/get_it.dart'; import 'package:provider/provider.dart'; import '../generated/locale_keys.g.dart'; +import '../main.dart'; import '../utils/easel_app_theme.dart'; class PreviewScreen extends StatefulWidget { @@ -30,6 +32,7 @@ class PreviewScreen extends StatefulWidget { class _PreviewScreenState extends State { Repository repository = GetIt.I.get(); + @override void initState() { super.initState(); @@ -53,16 +56,18 @@ class _PreviewScreenState extends State { children: [ if (provider.file != null) buildPreviewWidget(provider), Image.asset(PngUtils.kPreviewGradient, width: 1.sw, fit: BoxFit.fill), - Column(children: [ - SizedBox(height: MediaQuery.of(context).viewPadding.top + 20.h), - Align( - child: Text(LocaleKeys.nft_preview_header.tr(), - textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyText2!.copyWith(color: EaselAppTheme.kLightPurple, fontSize: 15.sp, fontWeight: FontWeight.w600)), + if (provider.nftFormat.format == NFTTypes.image) + SizedBox( + key: const Key(kImageFullScreenGridviewKey), + width: double.maxFinite, + child: SvgPicture.asset(SVGUtils.kFullScreenImgGridview, width: 1.sw, height: 1.sh, fit: BoxFit.fill), ), - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.only(left: 10.sp), + Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).viewPadding.top + 20.h), + child: Row( + children: [ + Padding( + padding: EdgeInsets.only(left: 10.w), child: IconButton( onPressed: () { provider.setAudioThumbnail(null); @@ -73,15 +78,33 @@ class _PreviewScreenState extends State { Icons.arrow_back_ios, color: EaselAppTheme.kWhite, ), - )), - ) - ]), + ), + ), + Expanded( + child: Text( + LocaleKeys.nft_preview_header.tr(), + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.bodyText2!.copyWith( + color: EaselAppTheme.kLightPurple, + fontSize: 13.sp, + fontWeight: FontWeight.w600, + ), + ), + ), + SizedBox( + width: 30.w, + ) + ], + ), + ), Padding( - padding: EdgeInsets.only(bottom: 30.h, right: 25.w), + padding: EdgeInsets.only( + bottom: 30.h, + ), child: Align( - alignment: Alignment.bottomRight, - child: PylonsButton( - onPressed: () async { + alignment: Alignment.bottomCenter, + child: GestureDetector( + onTap: () async { final navigator = Navigator.of(context); final result = await onUploadPressed(); if (result) { @@ -89,12 +112,31 @@ class _PreviewScreenState extends State { widget.onMoveToNextScreen(); } }, - btnText: LocaleKeys.upload.tr(), - showArrow: true, - color: EaselAppTheme.kRed, + child: ClipPath( + clipper: PylonsButtonClipper(), + child: Container( + width: 0.75.sw, + height: isTablet ? 0.09.sw : 0.12.sw, + decoration: const BoxDecoration(color: EaselAppTheme.kBlue), + child: Stack( + children: [ + Center( + child: Text( + LocaleKeys.continue_key.tr(), + style: Theme.of(context).textTheme.bodyText1!.copyWith( + fontSize: 15.sp, + color: EaselAppTheme.kWhite, + fontWeight: FontWeight.w600, + ), + ), + ) + ], + ), + ), + ), ), ), - ) + ), ], ), ), diff --git a/easel/lib/utils/constants.dart b/easel/lib/utils/constants.dart index e93309b1b7..60cf07a9af 100644 --- a/easel/lib/utils/constants.dart +++ b/easel/lib/utils/constants.dart @@ -3,9 +3,22 @@ import 'package:easy_localization/easy_localization.dart'; import '../generated/locale_keys.g.dart'; List kTutorialItems = [ - {'header': LocaleKeys.upload_your_ipfs.tr(), 'description': LocaleKeys.pick_the_file.tr(), 'image': 'assets/images/tutorial1.png'}, - {'header': LocaleKeys.edit_your_nft.tr(), 'description': LocaleKeys.enter_information_describing_your_nft.tr(), 'image': 'assets/images/tutorial2.png'}, - {'header': LocaleKeys.publish_your_nft.tr(), 'header1': LocaleKeys.pylons_app.tr(), 'description': LocaleKeys.once_you_enter_all.tr(), 'image': 'assets/images/tutorial3.png'}, + { + 'header': LocaleKeys.upload_your_ipfs.tr(), + 'description': LocaleKeys.pick_the_file.tr(), + 'image': 'assets/images/tutorial1.png' + }, + { + 'header': LocaleKeys.edit_your_nft.tr(), + 'description': LocaleKeys.enter_information_describing_your_nft.tr(), + 'image': 'assets/images/tutorial2.png' + }, + { + 'header': LocaleKeys.publish_your_nft.tr(), + 'header1': LocaleKeys.pylons_app.tr(), + 'description': LocaleKeys.once_you_enter_all.tr(), + 'image': 'assets/images/tutorial3.png' + }, ]; /// ```PNG assets @@ -62,6 +75,8 @@ class SVGUtils { static const kListIcon = 'assets/images/svg/list.svg'; static const kOwnerVerifiedIcon = 'assets/images/svg/verified.svg'; static const kFileTypeImageIcon = 'assets/images/svg/file_type_image.svg'; + static const kAudioFileIcon = 'assets/images/svg/audio_file_icon.svg'; + static const kFullScreenImgGridview = 'assets/images/svg/full_screen_img_gridview.svg'; } const String kLoadingGif = 'assets/images/gifs/loading.gif'; @@ -90,7 +105,7 @@ const kMaxEdition = 10000; const kMinRoyalty = 0; const kMaxRoyalty = 99.99; const kFileSizeLimitInGB = 32; -const kFileSizeLimitForAudiVideoInGB = 0.125; +const kFileSizeLimitForAudioVideoInGB = 0.125; const kMaxPriceLength = 14; const kSecInMillis = 1000; const double tabletMinWidth = 600; @@ -172,6 +187,8 @@ const kFileSize = "fileSize"; const kRealWorld = "real_world"; const kThumbnailFileName = "temp.jpg"; +const kFormat = "format"; +const kFileName = "fileName"; final List stepLabels = ["upload", "detail", "price"]; @@ -259,6 +276,8 @@ const kNFTTypeVideoIconKey = "NFT_type_video_icon_key"; const kNFTTypeAudioIconKey = "NFT_type_audio_icon_key"; const kNFTTypePdfIconKey = "NFT_type_pdf_icon_key"; const kNFTType3dModelIconKey = "NFT_type_3d_icon_key"; +const kProgressStepsKey = "progress_steps_key"; +const kImageFullScreenGridviewKey = "image_full_screen_gridview_key"; class AnalyticsScreenEvents { static String tutorialScreen = "TutorialScreen"; diff --git a/easel/lib/widgets/image_widget.dart b/easel/lib/widgets/image_widget.dart index 0a5aaa763c..cc3445af1e 100644 --- a/easel/lib/widgets/image_widget.dart +++ b/easel/lib/widgets/image_widget.dart @@ -13,28 +13,30 @@ class ImageWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return file != null - ? Image.memory( - file!.readAsBytesSync(), - width: 1.sw, - height: 1.sh, - fit: BoxFit.fitWidth, - ) - : SizedBox( - height: double.infinity, - child: CachedNetworkImage( - fit: BoxFit.fitWidth, - imageUrl: filePath!, - errorWidget: (a, b, c) => const Center(child: Icon(Icons.error_outline)), - placeholder: (context, url) => Center( - child: SizedBox( - height: 50.0.h, - child: Image.asset( - kLoadingGif, - ), - ), + if (file != null) { + return Image.memory( + file!.readAsBytesSync(), + width: 1.sw, + height: 1.sh, + fit: BoxFit.fill, + ); + } else { + return SizedBox( + height: double.infinity, + child: CachedNetworkImage( + fit: BoxFit.fill, + imageUrl: filePath!, + errorWidget: (a, b, c) => const Center(child: Icon(Icons.error_outline)), + placeholder: (context, url) => Center( + child: SizedBox( + height: 50.0.h, + child: Image.asset( + kLoadingGif, ), ), - ); + ), + ), + ); + } } } diff --git a/easel/lib/widgets/loading_with_progress.dart b/easel/lib/widgets/loading_with_progress.dart index 8064a03c47..ae3d5621e0 100644 --- a/easel/lib/widgets/loading_with_progress.dart +++ b/easel/lib/widgets/loading_with_progress.dart @@ -2,13 +2,12 @@ import 'dart:async'; import 'package:easel_flutter/easel_provider.dart'; import 'package:easel_flutter/main.dart'; -import 'package:easel_flutter/models/upload_progress.dart'; -import 'package:easel_flutter/utils/easel_app_theme.dart'; import 'package:easel_flutter/utils/image_util.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get_it/get_it.dart'; -import 'package:percent_indicator/percent_indicator.dart'; + +import '../utils/easel_app_theme.dart'; class LoadingProgress { LoadingProgress(); @@ -25,31 +24,20 @@ class LoadingProgress { .future; // return a fake future if state is screwy - this only ever happens during testing. todo: eliminate this hack } return showDialog( - context: navigatorKey.currentState!.overlay!.context, - barrierDismissible: true, - barrierColor: Colors.white.withOpacity(0), - builder: (ctx) => WillPopScope( - onWillPop: () async => false, - child: AlertDialog( - elevation: 0, - backgroundColor: EaselAppTheme.kTransparent, - content: StreamBuilder( - stream: easelProvider.uploadProgressStream, - builder: (context, uploadProgress) { - return CircularPercentIndicator( - radius: 60.h, - lineWidth: 5.w, - percent: uploadProgress.hasData - ? uploadProgress.data!.uploadedProgressData - : 0, - center: SizedBox( - height: 100.h, - width: 100.h, - child: Image.asset(ImageUtil.LOADING_GIF)), - progressColor: EaselAppTheme.kLightRed, - backgroundColor: EaselAppTheme.kLightPurple, - ); - })), - )); + context: navigatorKey.currentState!.overlay!.context, + barrierDismissible: true, + builder: (ctx) => WillPopScope( + onWillPop: () async => false, + child: AlertDialog( + elevation: 0, + backgroundColor: EaselAppTheme.kTransparent, + content: SizedBox( + width: 100.w, + height: 100.h, + child: Image.asset(ImageUtil.LOADING_GIF), + ), + ), + ), + ); } } diff --git a/easel/lib/widgets/publish_button.dart b/easel/lib/widgets/publish_button.dart index c9e9721094..b1e7825ff8 100644 --- a/easel/lib/widgets/publish_button.dart +++ b/easel/lib/widgets/publish_button.dart @@ -16,7 +16,7 @@ class PublishButton extends StatelessWidget { Widget build(BuildContext context) { return ClippedButton( key: const Key(kPublishButtonKey), - title: LocaleKeys.publish.tr(), + title: LocaleKeys.published.tr(), bgColor: EaselAppTheme.kLightRed, textColor: EaselAppTheme.kWhite, onPressed: onPress, diff --git a/easel/test/screens/choose_format_screen_test.dart b/easel/test/screens/choose_format_screen_test.dart new file mode 100644 index 0000000000..541839c73e --- /dev/null +++ b/easel/test/screens/choose_format_screen_test.dart @@ -0,0 +1,45 @@ +import 'package:easel_flutter/easel_provider.dart'; +import 'package:easel_flutter/screens/choose_format_screen.dart'; +import 'package:easel_flutter/utils/constants.dart'; +import 'package:easel_flutter/viewmodels/home_viewmodel.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:provider/provider.dart'; + +import '../extensions/size_extension.dart'; +import '../mock/media_info.mocks.dart'; +import '../mock/mock_audio_imp.dart'; +import '../mock/mock_file_utils.dart'; +import '../mock/mock_repository.dart'; +import '../mock/mock_video_player.dart'; + +void main() { + final repository = MockRepositoryImp(); + final homeViewModel = HomeViewModel(repository); + final easelProvider = EaselProvider( + repository: repository, + fileUtilsHelper: MockFileUtilsHelperImp(), + audioPlayerHelperForFile: MockAudioPlayerHelperImp(), + audioPlayerHelperForUrl: MockAudioPlayerHelperImp(), + mediaInfo: MockMediaInfo(), + videoPlayerHelper: MockVideoPlayerHelperImp(), + ); + + testWidgets("when choosing file for nft creation process indicator should be visible", (widgetTester) async { + homeViewModel.currentPage = ValueNotifier(1); + homeViewModel.currentStep = ValueNotifier(1); + await widgetTester.testAppForWidgetTesting( + MultiProvider( + providers: [ + ChangeNotifierProvider.value(value: easelProvider), + ChangeNotifierProvider.value(value: homeViewModel) + ], + builder: (context, widget) { + return const ChooseFormatScreen(); + }, + ), + ); + final progressSteps = find.byKey(const Key(kProgressStepsKey)); + expect(progressSteps, findsOneWidget); + }); +} diff --git a/easel/test/screens/preview_screen_test.dart b/easel/test/screens/preview_screen_test.dart new file mode 100644 index 0000000000..ff70f9945a --- /dev/null +++ b/easel/test/screens/preview_screen_test.dart @@ -0,0 +1,45 @@ +import 'package:easel_flutter/easel_provider.dart'; +import 'package:easel_flutter/repository/repository.dart'; +import 'package:easel_flutter/screens/preview_screen.dart'; +import 'package:easel_flutter/utils/constants.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:get_it/get_it.dart'; +import 'package:provider/provider.dart'; + +import '../extensions/size_extension.dart'; +import '../mock/media_info.mocks.dart'; +import '../mock/mock_audio_imp.dart'; +import '../mock/mock_file_utils.dart'; +import '../mock/mock_repository.dart'; +import '../mock/mock_video_player.dart'; + +void main() { + final repository = MockRepositoryImp(); + GetIt.I.registerLazySingleton(() => repository); + final easelProvider = EaselProvider( + repository: repository, + fileUtilsHelper: MockFileUtilsHelperImp(), + audioPlayerHelperForFile: MockAudioPlayerHelperImp(), + audioPlayerHelperForUrl: MockAudioPlayerHelperImp(), + mediaInfo: MockMediaInfo(), + videoPlayerHelper: MockVideoPlayerHelperImp(), + ); + + testWidgets("when showing image nft in full screen gridview should show", (widgetTester) async { + await widgetTester.testAppForWidgetTesting( + MultiProvider( + providers: [ + ChangeNotifierProvider.value( + value: easelProvider, + ) + ], + builder: (context, widget) { + return PreviewScreen(onMoveToNextScreen: () {}); + }, + ), + ); + final imageFullScreenGridView = find.byKey(const Key(kImageFullScreenGridviewKey)); + expect(imageFullScreenGridView, findsOneWidget); + }); +}