From 7f717e60f391be414dc4859dfb4e25b2de398e5a Mon Sep 17 00:00:00 2001 From: Nguyen Phuoc Sang <47568867+ppupha@users.noreply.github.com> Date: Tue, 2 Jan 2024 18:17:06 +0700 Subject: [PATCH] Sang/rebrand to ff/onboarding (#1450) * Update Onboarding Page * Update * Update Asset * Update UI --- assets | 2 +- lib/screen/home/collection_home_page.dart | 10 +- lib/screen/onboarding_page.dart | 358 +++++++++++++----- .../view_playlist/view_playlist.dart | 278 +++++++------- 4 files changed, 413 insertions(+), 235 deletions(-) diff --git a/assets b/assets index 3a49e6a6f..7c4bbd15d 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 3a49e6a6f8374cadc481c724ac35bba283412722 +Subproject commit 7c4bbd15d373ca1fb2248f340334e8db8037525a diff --git a/lib/screen/home/collection_home_page.dart b/lib/screen/home/collection_home_page.dart index a34d80f23..b68d23196 100644 --- a/lib/screen/home/collection_home_page.dart +++ b/lib/screen/home/collection_home_page.dart @@ -264,8 +264,11 @@ class CollectionHomePageState extends State Widget _loadingView(BuildContext context) => Center( child: Column( children: [ + SizedBox( + height: MediaQuery.of(context).padding.top, + ), _header(context), - loadingIndicator(), + loadingIndicator(valueColor: AppColor.white), ], )); @@ -274,13 +277,16 @@ class CollectionHomePageState extends State return ListView( padding: ResponsiveLayout.getPadding.copyWith(left: 0, right: 0), children: [ + SizedBox( + height: MediaQuery.of(context).padding.top, + ), _header(context), Padding( padding: const EdgeInsets.only(left: 15), child: Text( 'collection_empty_now'.tr(), //"Your collection is empty for now.", - style: theme.textTheme.ppMori400Black14, + style: theme.textTheme.ppMori400White14, ), ), ], diff --git a/lib/screen/onboarding_page.dart b/lib/screen/onboarding_page.dart index 1c722f472..4e576e7ee 100644 --- a/lib/screen/onboarding_page.dart +++ b/lib/screen/onboarding_page.dart @@ -22,12 +22,16 @@ import 'package:autonomy_flutter/util/constants.dart'; import 'package:autonomy_flutter/util/log.dart'; import 'package:autonomy_flutter/util/style.dart'; import 'package:autonomy_flutter/util/ui_helper.dart'; +import 'package:autonomy_flutter/view/back_appbar.dart'; import 'package:autonomy_flutter/view/primary_button.dart'; import 'package:autonomy_flutter/view/responsive.dart'; import 'package:autonomy_theme/autonomy_theme.dart'; +import 'package:card_swiper/card_swiper.dart'; +import 'package:collection/collection.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_svg/flutter_svg.dart'; class OnboardingPage extends StatefulWidget { const OnboardingPage({Key? key}) : super(key: key); @@ -44,9 +48,14 @@ class _OnboardingPageState extends State final metricClient = injector.get(); + late SwiperController _swiperController; + late int _currentIndex; + @override void initState() { super.initState(); + _swiperController = SwiperController(); + _currentIndex = 0; handleBranchLink(); handleDeepLink(); handleIrlLink(); @@ -183,101 +192,110 @@ class _OnboardingPageState extends State final paddingTop = (height - 640).clamp(0.0, 104).toDouble(); return Scaffold( + appBar: getDarkEmptyAppBar(), body: BlocConsumer( - listener: (context, state) async { - switch (state.onboardingStep) { - case OnboardingStep.dashboard: - Navigator.of(context) - .pushReplacementNamed(AppRouter.homePageNoTransition); - try { - await injector().restoreSettingsData(); - } catch (_) { - // just ignore this so that user can go through onboarding + listener: (context, state) async { + switch (state.onboardingStep) { + case OnboardingStep.dashboard: + Navigator.of(context) + .pushReplacementNamed(AppRouter.homePageNoTransition); + try { + await injector().restoreSettingsData(); + } catch (_) { + // just ignore this so that user can go through onboarding + } + // await askForNotification(); + await injector().checkForUpdate(); + // hide code show surveys issues/1459 + // await Future.delayed(SHORT_SHOW_DIALOG_DURATION, + // () => showSurveysNotification(context)); + break; + default: + break; } - // await askForNotification(); - await injector().checkForUpdate(); - // hide code show surveys issues/1459 - // await Future.delayed(SHORT_SHOW_DIALOG_DURATION, - // () => showSurveysNotification(context)); - break; - default: - break; - } - if (state.onboardingStep != OnboardingStep.dashboard) { - await injector().checkForUpdate(); - } - }, - builder: (context, state) { - if (state.isLoading) { - return loadingScreen(theme, "restoring_autonomy".tr()); - } + if (state.onboardingStep != OnboardingStep.dashboard) { + await injector().checkForUpdate(); + } + }, + builder: (context, state) { + if (state.isLoading) { + return loadingScreen(theme, "restoring_autonomy".tr()); + } + if (state.onboardingStep == OnboardingStep.startScreen) { + return Container( + padding: EdgeInsets.only(bottom: 40), + color: AppColor.primaryBlack, + child: _swipper(context)); + } - return Padding( - padding: ResponsiveLayout.pageEdgeInsets.copyWith(bottom: 40), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 40), - _logo(maxWidthLogo: 50), - SizedBox(height: paddingTop), - addBoldDivider(), - Text("collect".tr(), style: theme.textTheme.ppMori700Black36), - const SizedBox(height: 20), - addBoldDivider(), - Text("view".tr(), style: theme.textTheme.ppMori700Black36), - const SizedBox(height: 20), - addBoldDivider(), - Text("discover".tr(), style: theme.textTheme.ppMori700Black36), - const Spacer(), - if ((fromBranchLink || - fromDeeplink || - fromIrlLink || - (state.onboardingStep == OnboardingStep.undefined)) && - (state.onboardingStep != OnboardingStep.restore)) ...[ - PrimaryButton( - text: "h_loading...".tr(), - isProcessing: true, - ) - ] else if (state.onboardingStep == - OnboardingStep.startScreen) ...[ - Text("create_wallet_description".tr(), - style: theme.textTheme.ppMori400Grey14), - const SizedBox(height: 20), - PrimaryButton( - text: "create_a_new_wallet".tr(), - onTap: () { - Navigator.of(context).pushNamed(ChooseChainPage.tag); - }, - ), - const SizedBox(height: 20), - Center( - child: Text("or".tr().toUpperCase(), - style: theme.textTheme.ppMori400Grey14), - ), - const SizedBox(height: 20), - Text("view_existing_address_des".tr(), - style: theme.textTheme.ppMori400Grey14), - const SizedBox(height: 20), - PrimaryButton( - text: "view_existing_address".tr(), - onTap: () { - Navigator.of(context).pushNamed(ViewExistingAddress.tag, - arguments: ViewExistingAddressPayload(true)); - }, - ), - ] else if (state.onboardingStep == OnboardingStep.restore) ...[ - PrimaryButton( - text: "restoring".tr(), - isProcessing: true, - enabled: false, - ), - ] - ], - ), - ); - }, - )); + return Padding( + padding: ResponsiveLayout.pageEdgeInsets.copyWith(bottom: 40), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 40), + _logo(maxWidthLogo: 50), + SizedBox(height: paddingTop), + addBoldDivider(), + Text("collect".tr(), style: theme.textTheme.ppMori700Black36), + const SizedBox(height: 20), + addBoldDivider(), + Text("view".tr(), style: theme.textTheme.ppMori700Black36), + const SizedBox(height: 20), + addBoldDivider(), + Text("discover".tr(), + style: theme.textTheme.ppMori700Black36), + const Spacer(), + if ((fromBranchLink || + fromDeeplink || + fromIrlLink || + (state.onboardingStep == OnboardingStep.undefined)) && + (state.onboardingStep != OnboardingStep.restore)) ...[ + PrimaryButton( + text: "h_loading...".tr(), + isProcessing: true, + ) + ] else if (state.onboardingStep == + OnboardingStep.startScreen) ...[ + Text("create_wallet_description".tr(), + style: theme.textTheme.ppMori400Grey14), + const SizedBox(height: 20), + PrimaryButton( + text: "create_a_new_wallet".tr(), + onTap: () { + Navigator.of(context).pushNamed(ChooseChainPage.tag); + }, + ), + const SizedBox(height: 20), + Center( + child: Text("or".tr().toUpperCase(), + style: theme.textTheme.ppMori400Grey14), + ), + const SizedBox(height: 20), + Text("view_existing_address_des".tr(), + style: theme.textTheme.ppMori400Grey14), + const SizedBox(height: 20), + PrimaryButton( + text: "view_existing_address".tr(), + onTap: () { + Navigator.of(context).pushNamed(ViewExistingAddress.tag, + arguments: ViewExistingAddressPayload(true)); + }, + ), + ] else if (state.onboardingStep == + OnboardingStep.restore) ...[ + PrimaryButton( + text: "restoring".tr(), + isProcessing: true, + enabled: false, + ), + ] + ], + ), + ); + }, + )); } Widget _logo({double? maxWidthLogo}) { @@ -292,4 +310,162 @@ class _OnboardingPageState extends State ); }); } + + Widget _onboardingItem(BuildContext context, + {required String title, + required String desc, + required String image, + Widget? subDesc}) { + final theme = Theme.of(context); + return Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 100), + Text( + title, + style: theme.textTheme.ppMori700White24 + .copyWith(fontSize: 36, height: 1.0), + ), + const SizedBox(height: 40), + Image.asset(image), + const SizedBox(height: 40), + Text( + desc, + style: theme.textTheme.ppMori400White14 + .copyWith(fontSize: 24, height: 1.0), + ), + const SizedBox(height: 10), + subDesc ?? const SizedBox(), + ], + ), + ); + } + + Widget _swipper(BuildContext context) { + final theme = Theme.of(context); + final explore_artworks = [ + 'Licia He, Fictional Lullaby', + ]; + final stream_artworks = [ + 'Refik Anadol, Unsupervised', + 'Nancy Baker Cahill, Slipstream 001', + 'Refik Anadol, Unsupervised' + ]; + final pages = [ + Center( + child: SvgPicture.asset('assets/images/feral_file_onboarding.svg'), + ), + _onboardingItem( + context, + title: 'explore_exhibitions'.tr(), + desc: 'explore_exhibitions_desc'.tr(), + image: 'assets/images/feral_file_onboarding_exhibition.png', + subDesc: RichText( + text: TextSpan( + text: 'artwork_'.tr(), + style: theme.textTheme.ppMori400Grey12, + children: explore_artworks + .map((e) => TextSpan( + text: e, + )) + .toList()), + ), + ), + _onboardingItem(context, + title: 'manage_your_collection'.tr(), + desc: 'manage_your_collection_desc'.tr(), + image: 'assets/images/feral_file_onboarding_organize.png'), + _onboardingItem( + context, + title: 'view_everywhere'.tr(), + desc: 'view_everywhere_desc'.tr(), + image: 'assets/images/feral_file_onboarding_stream.png', + subDesc: RichText( + text: TextSpan( + text: 'artwork_'.tr(), + style: theme.textTheme.ppMori400Grey12, + children: stream_artworks + .mapIndexed((index, e) => [ + TextSpan( + text: e, + ), + if (index != stream_artworks.length - 1) + const TextSpan(text: '; ') + ]) + .flattened + .toList()), + ), + ), + ]; + final isLastPage = _currentIndex == pages.length - 1; + final padding = ResponsiveLayout.pageHorizontalEdgeInsets; + + return Stack( + children: [ + Swiper( + itemCount: pages.length, + itemBuilder: (context, index) { + final page = pages[index]; + return Padding( + padding: ResponsiveLayout.pageEdgeInsets, + child: page, + ); + }, + onIndexChanged: (index) { + setState(() { + _currentIndex = index; + }); + }, + pagination: SwiperPagination( + builder: DotSwiperPaginationBuilder( + color: Colors.grey, + activeColor: AppColor.feralFileHighlight, + ), + ), + control: const SwiperControl( + color: Colors.transparent, + disableColor: Colors.transparent, + size: 0), + loop: false, + controller: _swiperController, + ), + Visibility( + visible: isLastPage, + child: Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( + color: AppColor.primaryBlack, + padding: padding, + child: Column( + children: [ + PrimaryButton( + text: 'get_started'.tr(), + onTap: () async { + await Navigator.of(context) + .pushNamed(ChooseChainPage.tag); + }, + ), + const SizedBox(height: 16), + TextButton( + onPressed: () async { + await Navigator.of(context).pushNamed( + ViewExistingAddress.tag, + arguments: ViewExistingAddressPayload(true)); + }, + child: Text( + 'already_have_an_address'.tr(), + style: theme.textTheme.ppMori400Grey14, + ), + ), + ], + ), + ), + ), + ) + ], + ); + } } diff --git a/lib/screen/playlists/view_playlist/view_playlist.dart b/lib/screen/playlists/view_playlist/view_playlist.dart index b0b7598a4..bc636fb7c 100644 --- a/lib/screen/playlists/view_playlist/view_playlist.dart +++ b/lib/screen/playlists/view_playlist/view_playlist.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:autonomy_flutter/common/injector.dart'; import 'package:autonomy_flutter/model/play_control_model.dart'; import 'package:autonomy_flutter/model/play_list_model.dart'; @@ -46,7 +48,7 @@ class ViewPlaylistScreenPayload { class ViewPlaylistScreen extends StatefulWidget { final ViewPlaylistScreenPayload payload; - const ViewPlaylistScreen({Key? key, required this.payload}) : super(key: key); + const ViewPlaylistScreen({required this.payload, super.key}); @override State createState() => _ViewPlaylistScreenState(); @@ -98,7 +100,7 @@ class _ViewPlaylistScreenState extends State { )); _canvasDeviceBloc = context.read(); - _fetchDevice(); + unawaited(_fetchDevice()); bloc.add(GetPlayList(playListModel: widget.payload.playListModel)); } @@ -106,8 +108,8 @@ class _ViewPlaylistScreenState extends State { final listPlaylist = await _playlistService.getPlayList(); listPlaylist.removeWhere( (element) => element.id == widget.payload.playListModel?.id); - _playlistService.setPlayList(listPlaylist, override: true); - injector.get().backup(); + await _playlistService.setPlayList(listPlaylist, override: true); + unawaited(injector.get().backup()); injector().popUntilHomeOrSettings(); } @@ -121,9 +123,8 @@ class _ViewPlaylistScreenState extends State { ?.map((e) => tokens.where((element) => element.id == e).firstOrDefault()) .toList() ?? - []; - - temp.removeWhere((element) => element == null); + [] + ..removeWhere((element) => element == null); tokensPlaylist = List.from(temp) ..sort((a, b) { @@ -162,101 +163,97 @@ class _ViewPlaylistScreenState extends State { : Constants.maxWidthModalTablet), barrierColor: Colors.black.withOpacity(0.5), isScrollControlled: true, - builder: (context) { - return StatefulBuilder(builder: (context, setState) { - return Container( - color: theme.auSuperTeal, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(15, 17, 15, 20), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(top: 3, left: 37), - child: Text( - "sort_by".tr(), - style: theme.textTheme.ppMori400Black14, - overflow: TextOverflow.ellipsis, + builder: (context) => StatefulBuilder( + builder: (context, setState) => Container( + color: theme.auSuperTeal, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(15, 17, 15, 20), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: 3, left: 37), + child: Text( + 'sort_by'.tr(), + style: theme.textTheme.ppMori400Black14, + overflow: TextOverflow.ellipsis, + ), + ), ), - ), - ), - Align( - alignment: Alignment.centerRight, - child: IconButton( - onPressed: () => Navigator.pop(context), - padding: EdgeInsets.zero, - constraints: - const BoxConstraints(maxHeight: 18, maxWidth: 18), - icon: const Icon( - AuIcon.close, - size: 17, + Align( + alignment: Alignment.centerRight, + child: IconButton( + onPressed: () => Navigator.pop(context), + padding: EdgeInsets.zero, + constraints: const BoxConstraints( + maxHeight: 18, maxWidth: 18), + icon: const Icon( + AuIcon.close, + size: 17, + ), + ), ), - ), + ], ), - ], - ), - ), - addOnlyDivider(color: AppColor.white), - const SizedBox(height: 20), - ListView.separated( - itemBuilder: (context, index) { - final order = orders[index]; - return Padding( - padding: const EdgeInsets.symmetric(horizontal: 15.0), - child: GestureDetector( - onTap: () { - Navigator.pop(context); - _onSelectOrder(order); - }, - child: Container( - color: Colors.transparent, - child: Row( - children: [ - AuRadio( - onTap: (order) { - Navigator.pop(context); - _onSelectOrder(order); - }, - value: order, - groupValue: _sortOrder, - ), - const SizedBox(width: 15), - Expanded( - child: Text( - order.text, - style: theme.textTheme.ppMori400Black14, - overflow: TextOverflow.ellipsis, - ), + ), + addOnlyDivider(color: AppColor.white), + const SizedBox(height: 20), + ListView.separated( + itemBuilder: (context, index) { + final order = orders[index]; + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 15), + child: GestureDetector( + onTap: () { + Navigator.pop(context); + _onSelectOrder(order); + }, + child: Container( + color: Colors.transparent, + child: Row( + children: [ + AuRadio( + onTap: (order) { + Navigator.pop(context); + _onSelectOrder(order); + }, + value: order, + groupValue: _sortOrder, + ), + const SizedBox(width: 15), + Expanded( + child: Text( + order.text, + style: theme.textTheme.ppMori400Black14, + overflow: TextOverflow.ellipsis, + ), + ), + ], ), - ], + ), ), - ), - ), - ); - }, - itemCount: orders.length, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - separatorBuilder: (BuildContext context, int index) { - return const SizedBox(height: 15); - }, + ); + }, + itemCount: orders.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + separatorBuilder: (BuildContext context, int index) => + const SizedBox(height: 15), + ), + const SizedBox(height: 65), + ], ), - const SizedBox(height: 65), - ], - ), - ); - }); - }, + )), ); } - void _onMoreTap(BuildContext context, PlayListModel? playList) { + Future _onMoreTap(BuildContext context, PlayListModel? playList) async { final theme = Theme.of(context); - UIHelper.showDrawerAction( + await UIHelper.showDrawerAction( context, options: [ OptionItem( @@ -267,7 +264,9 @@ class _ViewPlaylistScreenState extends State { ), onTap: () { Navigator.pop(context); - if (isDemo) return; + if (isDemo) { + return; + } Navigator.pushNamed( context, AppRouter.editPlayListPage, @@ -288,10 +287,10 @@ class _ViewPlaylistScreenState extends State { tr('delete_playlist'), '', descriptionWidget: Text( - "delete_playlist_desc".tr(), + 'delete_playlist_desc'.tr(), style: theme.textTheme.ppMori400White14, ), - actionButton: "remove_collection".tr(), + actionButton: 'remove_collection'.tr(), onAction: deletePlayList, ); }, @@ -321,7 +320,9 @@ class _ViewPlaylistScreenState extends State { listener: (context, state) {}, builder: (context, state) { final playList = state.playListModel; - if (playList == null) return const SizedBox(); + if (playList == null) { + return const SizedBox(); + } return Scaffold( appBar: AppBar( systemOverlayStyle: systemUiOverlayLightStyle(AppColor.white), @@ -350,7 +351,7 @@ class _ViewPlaylistScreenState extends State { children: [ if (widget.payload.titleIcon != null) ...[ SizedBox( - width: 22, height: 22, child: widget.payload.titleIcon!), + width: 22, height: 22, child: widget.payload.titleIcon), const SizedBox(width: 10), Text( playList.getName(), @@ -370,11 +371,11 @@ class _ViewPlaylistScreenState extends State { actions: [ const SizedBox(width: 15), GestureDetector( - onTap: () { - _onOrderTap(context, _getAvailableOrders()); + onTap: () async { + await _onOrderTap(context, _getAvailableOrders()); }, child: SvgPicture.asset( - "assets/images/sort.svg", + 'assets/images/sort.svg', colorFilter: ColorFilter.mode(theme.primaryColor, BlendMode.srcIn), width: 22, @@ -384,7 +385,7 @@ class _ViewPlaylistScreenState extends State { if (editable) ...[ const SizedBox(width: 15), GestureDetector( - onTap: () => _onMoreTap(context, playList), + onTap: () async => _onMoreTap(context, playList), child: SvgPicture.asset( 'assets/images/more_circle.svg', colorFilter: @@ -402,32 +403,30 @@ class _ViewPlaylistScreenState extends State { ), body: BlocBuilder( bloc: nftBloc, - builder: (context, nftState) { - return NftCollectionGrid( - state: nftState.state, - tokens: setupPlayList( - tokens: nftState.tokens.items, - selectedTokens: playList.tokenIDs, - ), - customGalleryViewBuilder: (context, tokens) => _assetsWidget( - context, - tokens, - accountIdentities: accountIdentities, - playControlModel: - playList.playControlModel ?? PlayControlModel(), - onShuffleTap: () => _onShufferTap(playList), - onTimerTap: () => _onTimerTap(playList), - ), - ); - }, + builder: (context, nftState) => NftCollectionGrid( + state: nftState.state, + tokens: setupPlayList( + tokens: nftState.tokens.items, + selectedTokens: playList.tokenIDs, + ), + customGalleryViewBuilder: (context, tokens) => _assetsWidget( + context, + tokens, + accountIdentities: accountIdentities, + playControlModel: + playList.playControlModel ?? PlayControlModel(), + onShuffleTap: () => _onShufferTap(playList), + onTimerTap: () => _onTimerTap(playList), + ), + ), ), ); }, ); } - void moveToAddNftToCollection(BuildContext context) { - Navigator.pushNamed( + Future moveToAddNftToCollection(BuildContext context) async { + await Navigator.pushNamed( context, AppRouter.addToCollectionPage, arguments: widget.payload.playListModel, @@ -446,9 +445,9 @@ class _ViewPlaylistScreenState extends State { BuildContext context, List tokens, { required List accountIdentities, + required PlayControlModel playControlModel, Function()? onShuffleTap, Function()? onTimerTap, - required PlayControlModel playControlModel, }) { int cellPerRow = ResponsiveLayout.isMobile ? cellPerRowPhone : cellPerRowTablet; @@ -484,8 +483,10 @@ class _ViewPlaylistScreenState extends State { usingThumbnailID: index > 50, useHero: false, ), - onTap: () { - if (asset.pending == true && !asset.hasMetadata) return; + onTap: () async { + if (asset.pending == true && !asset.hasMetadata) { + return; + } final index = tokens .where((e) => e.pending != true || e.hasMetadata) @@ -506,16 +507,13 @@ class _ViewPlaylistScreenState extends State { ? AppRouter.claimedPostcardDetailsPage : AppRouter.artworkDetailsPage; - Navigator.of(context) + await Navigator.of(context) .pushNamed(pageName, arguments: payload); }, ); }, itemCount: tokens.length), ), - const SizedBox( - height: 50, - ), ], ), Positioned( @@ -530,12 +528,12 @@ class _ViewPlaylistScreenState extends State { child: Center( child: AddButton( icon: SvgPicture.asset( - "assets/images/Add.svg", + 'assets/images/Add.svg', width: 21, height: 21, ), - onTap: () { - moveToAddNftToCollection(context); + onTap: () async { + await moveToAddNftToCollection(context); }, ), ), @@ -550,7 +548,7 @@ class _ViewPlaylistScreenState extends State { Future _fetchDevice() async { _canvasDeviceBloc.add(CanvasDeviceGetDevicesEvent( - widget.payload.playListModel?.id ?? "", + widget.payload.playListModel?.id ?? '', syncAll: false)); } } @@ -577,9 +575,9 @@ enum SortOrder { int compare(CompactedAssetToken a, CompactedAssetToken b) { switch (this) { case SortOrder.title: - return a.title?.compareTo(b.title ?? "") ?? 1; + return a.title?.compareTo(b.title ?? '') ?? 1; case SortOrder.artist: - return a.artistID?.compareTo(b.artistID ?? "") ?? 1; + return a.artistID?.compareTo(b.artistID ?? '') ?? 1; case SortOrder.newest: return b.lastActivityTime.compareTo(a.lastActivityTime); case SortOrder.manual: @@ -593,16 +591,14 @@ class AddButton extends StatelessWidget { final void Function() onTap; const AddButton({ - super.key, required this.icon, required this.onTap, + super.key, }); @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: icon, - ); - } + Widget build(BuildContext context) => GestureDetector( + onTap: onTap, + child: icon, + ); }